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 os
import sys import sys
import click
from . import __version__, log from . import __version__, log
from .doubleclick import click
from .storage import storage_names from .storage import storage_names
from .sync import StorageEmpty, SyncConflict, sync from .sync import StorageEmpty, SyncConflict, sync
from .utils import expand_path, get_class_init_args, parse_options, split_dict 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 logging
import sys import sys
import click from .doubleclick import click
class ColorFormatter(logging.Formatter): class ColorFormatter(logging.Formatter):

View file

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