Don't produce overlapping output or prompts.

See #96 and #101
This commit is contained in:
Markus Unterwaditzer 2014-08-19 15:54:25 +02:00
parent 73b8381ab8
commit d0a2331d86
4 changed files with 58 additions and 5 deletions

View file

@ -12,9 +12,8 @@ import json
import os
import sys
import click
from . import __version__, log
from .doubleclick import click
from .storage import storage_names
from .sync import StorageEmpty, SyncConflict, sync
from .utils import expand_path, get_class_init_args, parse_options, split_dict

55
vdirsyncer/doubleclick.py Normal file
View file

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
'''
vdirsyncer.utils.doubleclick
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Utilities for writing multiprocessing applications with click.
Currently the only relevant object here is the ``click`` object, which
provides everything importable from click. It also wraps some UI functions
such that they don't produce overlapping output or prompt the user at the
same time.
:copyright: (c) 2014 Markus Unterwaditzer & contributors
:license: MIT, see LICENSE for more details.
'''
import functools
import multiprocessing
UI_FUNCTIONS = frozenset(['echo', 'echo_via_pager', 'prompt', 'clear', 'edit',
'launch', 'getchar', 'pause'])
_ui_lock = multiprocessing.Lock()
def _ui_function(f):
@functools.wraps(f)
def inner(*a, **kw):
_ui_lock.acquire()
try:
return f(*a, **kw)
finally:
_ui_lock.release()
return inner
class _ClickProxy(object):
def __init__(self, needs_wrapper, click=None):
if click is None:
import click
self._click = click
self._cache = {}
self._needs_wrapper = frozenset(needs_wrapper)
def __getattr__(self, name):
if name not in self._cache:
f = getattr(self._click, name)
if name in self._needs_wrapper:
f = _ui_function(f)
self._cache[name] = f
return self._cache[name]
click = _ClickProxy(UI_FUNCTIONS)

View file

@ -9,7 +9,7 @@
import logging
import sys
import click
from .doubleclick import click
class ColorFormatter(logging.Formatter):

View file

@ -9,12 +9,11 @@
import os
import click
import requests
from requests.packages.urllib3.poolmanager import PoolManager
from .. import exceptions, log
from ..doubleclick import click
from .compat import iteritems, urlparse