Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions fire/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@

class CoreTest(testutils.BaseTestCase):

def testBuiltinPositionalOnlyDefault(self):
with self.assertOutputMatches(stdout=' hi', stderr=None):
self.assertEqual(core.Fire('hi'.rjust, command=['5']), ' hi')

def testBuiltinPositionalOnlyDefaultOverride(self):
with self.assertOutputMatches(stdout='___hi', stderr=None):
self.assertEqual(core.Fire('hi'.rjust, command=['5', '_']), '___hi')

def testBuiltinPositionalOnlyRequiredArgument(self):
with self.assertRaisesFireExit(2, 'required argument: width'):
core.Fire('hi'.rjust, command=[])

def testOneLineResult(self):
self.assertEqual(core._OneLineResult(1), '1') # pylint: disable=protected-access
self.assertEqual(core._OneLineResult('hello'), 'hello') # pylint: disable=protected-access
Expand Down
7 changes: 4 additions & 3 deletions fire/inspectutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ def Py3GetFullArgSpec(fn):
name = param.name

# pylint: disable=protected-access
if kind is inspect._POSITIONAL_ONLY: # type: ignore
args.append(name)
elif kind is inspect._POSITIONAL_OR_KEYWORD: # type: ignore
if kind in (
inspect._POSITIONAL_ONLY,
inspect._POSITIONAL_OR_KEYWORD,
): # type: ignore
args.append(name)
if param.default is not param.empty:
defaults += (param.default,)
Expand Down
30 changes: 30 additions & 0 deletions fire/inspectutils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""Tests for the inspectutils module."""

import inspect
import os

from fire import inspectutils
Expand Down Expand Up @@ -52,6 +53,35 @@ def testGetFullArgSpecFromBuiltin(self):
self.assertEqual(spec.kwonlydefaults, {})
self.assertEqual(spec.annotations, {})

def testGetFullArgSpecPositionalOnlyDefault(self):
spec = inspectutils.GetFullArgSpec(dict.get)
self.assertEqual(spec.args, ['self', 'key', 'default'])
self.assertEqual(spec.defaults, (None,))

def testGetFullArgSpecBoundPositionalOnlyDefault(self):
spec = inspectutils.GetFullArgSpec({}.get)
self.assertEqual(spec.args, ['key', 'default'])
self.assertEqual(spec.defaults, (None,))

def testGetFullArgSpecMixedPositionalDefaults(self):
def function(*args, **kwargs):
del args, kwargs

# Use a signature object so this test also parses on Python 3.7.
function.__signature__ = inspect.Signature([
inspect.Parameter('required', inspect.Parameter.POSITIONAL_ONLY),
inspect.Parameter('first', inspect.Parameter.POSITIONAL_ONLY,
default=1),
inspect.Parameter('second', inspect.Parameter.POSITIONAL_OR_KEYWORD,
default=2),
inspect.Parameter('third', inspect.Parameter.KEYWORD_ONLY, default=3),
])
spec = inspectutils.GetFullArgSpec(function)
self.assertEqual(spec.args, ['required', 'first', 'second'])
self.assertEqual(spec.defaults, (1, 2))
self.assertEqual(spec.kwonlyargs, ['third'])
self.assertEqual(spec.kwonlydefaults, {'third': 3})

def testGetFullArgSpecFromSlotWrapper(self):
spec = inspectutils.GetFullArgSpec(tc.NoDefaults)
self.assertEqual(spec.args, [])
Expand Down