Skip to content

Commit

Permalink
Only apply UTF-8 monkey patch when necessary (#3573)
Browse files Browse the repository at this point in the history
* Apply the UTF-8 locale patch only when necessary

* Cleanup args

* Only apply input/output patches when the handler is callable

* zzz

* Flake8 fix

* removed trailing spaces
  • Loading branch information
stefaang authored and medariox committed Jan 9, 2018
1 parent 8bb6e22 commit be79a12
Showing 1 changed file with 31 additions and 5 deletions.
36 changes: 31 additions & 5 deletions medusa/init/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,32 @@ def _varkwargs(**kwargs):
return {k: _handle_input(arg) for k, arg in kwargs.items()}


def make_closure(f, handle_arg, handle_output):
"""Create a closure that encodes parameters to utf-8 and call original function."""
return lambda *args, **kwargs: handle_output(f(*[handle_arg(arg) for arg in args], **{k: handle_arg(arg) for k, arg in kwargs.items()}))
def make_closure(f, handle_arg=None, handle_output=None):
"""Apply an input handler and output handler to a function.
Used to ensure UTF-8 encoding at input and output.
"""
return patch_output(patch_input(f, handle_arg), handle_output)


def patch_input(f, handle_arg=None):
"""Patch all args and kwargs of function f.
If handle_arg is None, just return the original function.
"""
def patched_input(*args, **kwargs):
return f(*[handle_arg(arg) for arg in args], **{k: handle_arg(arg) for k, arg in kwargs.items()})
return patched_input if callable(handle_arg) else f


def patch_output(f, handle_output=None):
"""Patch the output of function f with the handle_output function.
If handle_output is None, just return the original function.
"""
def patched_output(*args, **kwargs):
return handle_output(f(*args, **kwargs))
return patched_output if callable(handle_output) else f


def initialize():
Expand Down Expand Up @@ -113,9 +136,12 @@ def initialize():
if os.name != 'nt':
affected_functions[os].extend(['chmod', 'chown', 'link', 'statvfs', 'symlink'])

handle_arg = _handle_input if not fs_encoding or fs_encoding.lower() != 'utf-8' else lambda x: x
if not fs_encoding or fs_encoding.lower() != 'utf-8':
handle_input = _handle_input
else:
handle_input = None

for k, v in affected_functions.items():
handle_output = handle_output_map.get(k, _handle_output_u)
for f in v:
setattr(k, f, make_closure(getattr(k, f), handle_arg, handle_output))
setattr(k, f, make_closure(getattr(k, f), handle_input, handle_output))

0 comments on commit be79a12

Please sign in to comment.