Commit a18b7e71 authored by John Kirkwood's avatar John Kirkwood

Handle introspection of builtins with no signature.

parent 62dc12e2
Pipeline #2798 failed with stages
in 16 seconds
......@@ -186,16 +186,38 @@ class Callable(Importable):
return getattr(cb, 'cli2', cls(cb.__name__, cb))
def __call__(self, *args, **kwargs):
if len(args) < len(self.required_args):
req_args = self.required_args
if len(args) < len(req_args):
raise Cli2ArgsException(self, args)
return*args, **kwargs)
return*args, **kwargs)
except TypeError as exc:
# catch builtins that don't provide info for required_args
if exc.args[0].startswith('Required argument'):
raise Cli2ArgsException(self, args)
def required_args(self):
if self.is_module:
return []
argspec = inspect.getfullargspec(
if argspec.defaults:
return argspec.args[:-len(argspec.defaults)]
return argspec.args
argspec = inspect.getfullargspec(
This edge case is for builtin which
returns args=['type', 'tz'] for some reason, rather than ['tz'].
The freezegun mocking module changes 'type' to 'cls' for tests...
if ('datetime')
and argspec.args[0] in ['cls', 'type']):
del argspec.args[0]
if argspec.defaults:
return argspec.args[:-len(argspec.defaults)]
return argspec.args
except TypeError:
# catch builtins that don't provide a signature
# TODO: parse first line of inspect.getdoc() for builtin signature?
return []
import pytest
from freezegun import freeze_time
import cli2
import pytest
@pytest.mark.parametrize('name,command', [
......@@ -14,17 +17,20 @@ import pytest
('run_module_missing_attr', 'cli2.missing'),
('run_module_missing', ''),
('run_module_nodoc', 'test_cli2.test_cli2'),
('run_module_builtin', ''),
('help_module', 'help cli2'),
('help_module_attr_notfound', 'help cli2.skipppp'),
('help_module_no_callables', 'help datetime'),
('help_module_no_signature', 'help datetime.datetime'),
('help_module_no_signature', 'help'),
('docmod', 'docmod cli2'),
('docmod_noargs', 'docmod'),
('docfile', 'docfile cli2/'),
('docfile_missing', 'docfile'),
('debug', 'debug to see=how -it --parses=me'),
@freeze_time("2010-02-01") # so output is unchanging
def test_cli2(name, command):
'cli2 ' + command,
command: cli2 help datetime.datetime
command: cli2 help
retcode: 1
Signature: datetime.datetime
datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
The year, month and day arguments are required. tzinfo may be None, or an
instance of a tzinfo subclass. The remaining arguments may be ints.
timestamp -> local date from a POSIX timestamp (like time.time()).
command: cli2
retcode: 1
FakeDatetime(2010, 2, 1, 0, 0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment