From 921d934a0d61fd2863eb939aa872baca4156a85b Mon Sep 17 00:00:00 2001 From: ubershmekel Date: Mon, 2 Nov 2009 22:27:47 +0000 Subject: argparse.run now works with bound methods (instance methods and class methods). --- argparse.py | 9 +++++++++ test/test_argparse.py | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/argparse.py b/argparse.py index 9ebf845..c1459fb 100644 --- a/argparse.py +++ b/argparse.py @@ -95,6 +95,7 @@ import re as _re import sys as _sys import textwrap as _textwrap import inspect as _inspect +import types as _types from gettext import gettext as _ @@ -2414,6 +2415,14 @@ def _getfunctionspec(function): else: arg_names, varargs, varkw, defaults = _inspect.getargspec(function) kwonlyargs, kwonlydefaults, annotations = [], {}, {} + + # A fix for class-methods and instance-methods is to remove the first + # argument name (which is self or cls). + # In case of (*args, **kwargs) we don't intervene. + if isinstance(function, _types.MethodType): + if len(arg_names) > 0: + arg_names.pop(0) + return (arg_names, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations) diff --git a/test/test_argparse.py b/test/test_argparse.py index 462b065..8dc3c25 100644 --- a/test/test_argparse.py +++ b/test/test_argparse.py @@ -4077,10 +4077,22 @@ class TestAddFunction(TestCase): result = argparse.run(func, proc, args="proc monster".split()) self.failUnlessEqual(('monster', '...'), result) + def test_runner_on_bound_functions(self): + + class Bacon: + def proc(self, flying, spaghetti='...'): + return flying, spaghetti + + meat = Bacon() + result = argparse.run(meat.proc, args="monster".split()) + self.failUnlessEqual(('monster', '...'), result) + # only compile and test annotations if this is Python >= 3 if sys.version_info[0] >= 3: def test_annotations(self): + # the function with annotations is a string to avoid syntax errors + # in python 2.x func_source = textwrap.dedent(''' def func(foo:bool, bar:int, spam:int=101): return foo, bar -- cgit v1.2.1