Andy Mikhailenko avatar Andy Mikhailenko committed 4f8b689

Fix issue #31: check action handler capabilities for inferred argument properties

Comments (0)

Files changed (2)

argh/assembling.py

     """
     guessed = {}
 
+    TYPE_AWARE_ACTIONS = 'store', 'append'
+    "Parser actions that accept argument 'type'."
+
     # guess type/action from default value
     value = kwargs.get('default')
     if value is not None:
                 guessed['action'] = 'store_false' if value else 'store_true'
         elif kwargs.get('type') is None:
             # infer type from default value
-            guessed['type'] = type(value)
+            # (make sure that action handler supports this keyword)
+            if kwargs.get('action', 'store') in TYPE_AWARE_ACTIONS:
+                guessed['type'] = type(value)
 
     # guess type from choices (first item)
     if kwargs.get('choices') and 'type' not in list(guessed) + list(kwargs):

test/test_regressions.py

 """
 from .base import DebugArghParser, run
 
+import argh
+
 
 def test_regression_issue12():
     """Issue #12: @command was broken if there were more than one argument
 def test_regression_issue27():
     """Issue #27: store_true is not set for inferred bool argument.
 
-    Reason: when @command was refactored, it stopped using @arg, but it is
+    :Reason: when @command was refactored, it stopped using @arg, but it is
     it was there that guesses (choices→type, default→type and
     default→action) were made.
     """
     # default → action (store_true)
     assert run(p, 'parrot') == 'beautiful plumage\n'
     assert run(p, 'parrot --dead') == 'this parrot is no more\n'
+
+
+def test_regression_issue31():
+    """ Issue #31: Argh fails with parameter action type 'count' if a default
+    value is provided.
+
+    :Reason: assembling._guess() would infer type from default value without
+        regard to the action.  _CountAction does not accept argument "type".
+
+    :Solution: restricted type inferring to actions "store" and "append".
+    """
+
+    @argh.arg('-v', '--verbose', dest='verbose', action='count', default=0)
+    def cmd(**kwargs):
+        yield kwargs.get('verbose', -1)
+
+    p = DebugArghParser()
+    p.set_default_command(cmd)
+    assert '0\n' == run(p, '')
+    assert '1\n' == run(p, '-v')
+    assert '2\n' == run(p, '-vv')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.