Commits

Andy Mikhailenko committed 69251f9

Added an (unfinished?) attempt to address the Unicode arguments problem (re #11).

  • Participants
  • Parent commits 8bce6f1

Comments (0)

Files changed (2)

argh/decorators.py

 import inspect
 
 
-__all__ = ['alias', 'arg', 'command', 'plain_signature']
+__all__ = ['alias', 'arg', 'command', 'plain_signature', 'unicode_args']
 
 
 def alias(name):
             func = arg(a)(func)
 
     return func
+
+def unicode_args(*names):
+    """Tells the dispatcher that values of given arguments should be in
+    Unicode. The dispatcher will try its best to encode the values properly.
+
+    .. note::
+
+        Ideally this should be done this way::
+
+            @arg('--foo', type=unicode)
+            def bar(args):
+                assert isinstance(args.foo, unicode)
+
+        Unfortunately it simply breaks ArgumentParser when the values are *not*
+        Unicode.
+
+    """
+    def wrapper(func):
+        func.argh_unicode_args = names
+        return func
+    return wrapper
 from types import GeneratorType
 
 from argh.exceptions import CommandError
+from argh.completion import autocomplete
 
 
-__all__ = ['ArghParser', 'add_commands', 'dispatch', 'confirm']
+__all__ = ['ArghParser', 'add_commands', 'autocomplete', 'dispatch', 'confirm']
 
 
 def _get_subparsers(parser):
         # if there were no commands defined for the parser (a possible case)
         raise NotImplementedError('Cannot dispatch without commands')
 
+    # force Unicode values
+    # FIXME this should be done via @arg(type=unicode) but it seems to break
+    # argparse; can we work around it?
+    for name in getattr(args.function, 'argh_unicode_args', []):
+        value = getattr(args, name)
+        try:
+            value = unicode(value)
+        except UnicodeDecodeError:
+            value = str(value).decode('utf-8')
+        setattr(args, name, value)
+
     # try different ways of calling the command; if meanwhile it raises
     # CommandError, return the string representation of that error
     try:
         "Wrapper for :func:`add_commands`."
         return add_commands(self, *args, **kwargs)
 
+    def autocomplete(self):
+        return autocomplete(self)
+
     def dispatch(self, *args, **kwargs):
         "Wrapper for :func:`dispatch`."
         return dispatch(self, *args, **kwargs)