Skip to content
Merged
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
8 changes: 4 additions & 4 deletions .github/scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ python -m pytest # Run the tests without IPython.
pip install ipython
python -m pytest # Now run the tests with IPython.
pylint fire --ignore=test_components_py3.py,parser_fuzz_test.py,console
if [[ ${PYTHON_VERSION} == 3.7 ]]; then
# Run type-checking.
pip install pytype;
pytype -x fire/test_components_py3.py;
if [[ ${PYTHON_VERSION} == 3.12 ]]; then
# Run type-checking
pip install ty
python -m ty check --python $(which python) --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py
fi
4 changes: 2 additions & 2 deletions fire/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ def import_from_file_path(path):

spec = util.spec_from_file_location(module_name, path)

if spec is None:
if spec is None or spec.loader is None:
raise OSError('Unable to load module from specified path.')

module = util.module_from_spec(spec) # pylint: disable=no-member
spec.loader.exec_module(module) # pytype: disable=attribute-error
spec.loader.exec_module(module)

return module, module_name

Expand Down
5 changes: 1 addition & 4 deletions fire/console/console_attr_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
# limitations under the License.

"""OS specific console_attr helper functions."""
# This file contains platform specific code which is not currently handled
# by pytype.
# pytype: skip-file

from __future__ import absolute_import
from __future__ import division
Expand Down Expand Up @@ -73,7 +70,7 @@ def _GetXY(fd):
try:
# This magic incantation converts a struct from ioctl(2) containing two
# binary shorts to a (rows, columns) int tuple.
rc = struct.unpack(b'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, 'junk'))
rc = struct.unpack(b'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, b'junk'))
return (rc[1], rc[0]) if rc else None
except: # pylint: disable=bare-except
return None
Expand Down
12 changes: 6 additions & 6 deletions fire/console/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ def Decode(data, encoding=None):

try:
# Just return the string if its pure ASCII.
return string.decode('ascii') # pytype: disable=attribute-error
return string.decode('ascii')
except UnicodeError:
# The string is not ASCII encoded.
pass

# Try the suggested encoding if specified.
if encoding:
try:
return string.decode(encoding) # pytype: disable=attribute-error
return string.decode(encoding)
except UnicodeError:
# Bad suggestion.
pass
Expand All @@ -84,21 +84,21 @@ def Decode(data, encoding=None):
# be exceptional if a valid extended ascii encoding with extended chars
# were also a valid UITF-8 encoding.
try:
return string.decode('utf8') # pytype: disable=attribute-error
return string.decode('utf8')
except UnicodeError:
# Not a UTF-8 encoding.
pass

# Try the filesystem encoding.
try:
return string.decode(sys.getfilesystemencoding()) # pytype: disable=attribute-error
return string.decode(sys.getfilesystemencoding())
except UnicodeError:
# string is not encoded for filesystem paths.
pass

# Try the system default encoding.
try:
return string.decode(sys.getdefaultencoding()) # pytype: disable=attribute-error
return string.decode(sys.getdefaultencoding())
except UnicodeError:
# string is not encoded using the default encoding.
pass
Expand All @@ -118,7 +118,7 @@ def Decode(data, encoding=None):
# string = '\xdc'
# string = string.decode('iso-8859-1')
# string = string.encode('ascii', 'backslashreplace')
return string.decode('iso-8859-1') # pytype: disable=attribute-error
return string.decode('iso-8859-1')


def GetEncodedValue(env, name, default=None):
Expand Down
4 changes: 2 additions & 2 deletions fire/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ def _Fire(component, args, parsed_flag_args, context, name=None):

# Treat namedtuples as dicts when handling them as a map.
if inspectutils.IsNamedTuple(component):
component_dict = component._asdict() # pytype: disable=attribute-error
component_dict = component._asdict()
else:
component_dict = component

Expand All @@ -519,7 +519,7 @@ def _Fire(component, args, parsed_flag_args, context, name=None):
# a key as another type.
# TODO(dbieber): Consider alternatives for accessing non-string keys.
for key, value in (
component_dict.items()): # pytype: disable=attribute-error
component_dict.items()):
if target == str(key):
component = value
handled = True
Expand Down
4 changes: 2 additions & 2 deletions fire/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,12 @@ def serialize(x):

def testLruCacheDecoratorBoundArg(self):
self.assertEqual(
core.Fire(tc.py3.LruCacheDecoratedMethod, # pytype: disable=module-attr
core.Fire(tc.py3.LruCacheDecoratedMethod,
command=['lru_cache_in_class', 'foo']), 'foo')

def testLruCacheDecorator(self):
self.assertEqual(
core.Fire(tc.py3.lru_cache_decorated, # pytype: disable=module-attr
core.Fire(tc.py3.lru_cache_decorated,
command=['foo']), 'foo')


Expand Down
8 changes: 4 additions & 4 deletions fire/custom_descriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ def GetStringTypeDescription(obj, available_space, line_length):
def GetSummary(obj, available_space, line_length):
obj_type_name = type(obj).__name__
if obj_type_name in CUSTOM_DESC_SUM_FN_DICT:
return CUSTOM_DESC_SUM_FN_DICT.get(obj_type_name)[0](obj, available_space,
line_length)
return CUSTOM_DESC_SUM_FN_DICT[obj_type_name][0](obj, available_space,
line_length)
return None


def GetDescription(obj, available_space, line_length):
obj_type_name = type(obj).__name__
if obj_type_name in CUSTOM_DESC_SUM_FN_DICT:
return CUSTOM_DESC_SUM_FN_DICT.get(obj_type_name)[1](obj, available_space,
line_length)
return CUSTOM_DESC_SUM_FN_DICT[obj_type_name][1](obj, available_space,
line_length)
return None
2 changes: 1 addition & 1 deletion fire/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def SetParseFns(*positional, **named):
def _Decorator(fn):
parse_fns = GetParseFns(fn)
parse_fns['positional'] = positional
parse_fns['named'].update(named) # pytype: disable=attribute-error
parse_fns['named'].update(named)
_SetMetadata(fn, FIRE_PARSE_FNS, parse_fns)
return fn

Expand Down
2 changes: 1 addition & 1 deletion fire/docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ def _consume_line(line_info, state):
if state.section.new and state.section.format == Formats.RST:
# The current line starts with an RST directive, e.g. ":param arg:".
directive = _get_directive(line_info)
directive_tokens = directive.split() # pytype: disable=attribute-error
directive_tokens = directive.split()
if state.section.title == Sections.ARGS:
name = directive_tokens[-1]
arg = _get_or_create_arg_by_name(
Expand Down
6 changes: 3 additions & 3 deletions fire/formatting_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import sys

try:
import colorama # pylint: disable=g-import-not-at-top, # pytype: disable=import-error
import colorama # pylint: disable=g-import-not-at-top
HAS_COLORAMA = True
except ImportError:
HAS_COLORAMA = False
Expand All @@ -38,9 +38,9 @@ def initialize_or_disable():
# Windows 10, 2016, and 2019 only.

wrap = False
kernel32 = ctypes.windll.kernel32 # pytype: disable=module-attr
kernel32 = ctypes.windll.kernel32
enable_virtual_terminal_processing = 0x04
out_handle = kernel32.GetStdHandle(subprocess.STD_OUTPUT_HANDLE) # pylint: disable=line-too-long, # pytype: disable=module-attr
out_handle = kernel32.GetStdHandle(subprocess.STD_OUTPUT_HANDLE) # pylint: disable=line-too-long,
# GetConsoleMode fails if the terminal isn't native.
mode = ctypes.wintypes.DWORD()
if kernel32.GetConsoleMode(out_handle, ctypes.byref(mode)) == 0:
Expand Down
15 changes: 9 additions & 6 deletions fire/helptext.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
information.
"""

from __future__ import annotations

import collections
import itertools

Expand Down Expand Up @@ -85,13 +87,14 @@ def HelpText(component, trace=None, verbose=False):
+ usage_details_sections
+ notes_sections
)
valid_sections = [section for section in sections if section is not None]
return '\n\n'.join(
_CreateOutputSection(*section)
for section in sections if section is not None
_CreateOutputSection(name, content)
for name, content in valid_sections
)


def _NameSection(component, info, trace=None, verbose=False):
def _NameSection(component, info, trace=None, verbose=False) -> tuple[str, str]:
"""The "Name" section of the help string."""

# Only include separators in the name in verbose mode.
Expand All @@ -113,7 +116,7 @@ def _NameSection(component, info, trace=None, verbose=False):


def _SynopsisSection(component, actions_grouped_by_kind, spec, metadata,
trace=None):
trace=None) -> tuple[str, str]:
"""The "Synopsis" section of the help string."""
current_command = _GetCurrentCommand(trace=trace, include_separators=True)

Expand All @@ -136,7 +139,7 @@ def _SynopsisSection(component, actions_grouped_by_kind, spec, metadata,
return ('SYNOPSIS', text)


def _DescriptionSection(component, info):
def _DescriptionSection(component, info) -> tuple[str, str] | None:
"""The "Description" sections of the help string.

Args:
Expand Down Expand Up @@ -408,7 +411,7 @@ def _GetCurrentCommand(trace=None, include_separators=True):
return current_command


def _CreateOutputSection(name, content):
def _CreateOutputSection(name: str, content: str) -> str:
return f"""{formatting.Bold(name)}
{formatting.Indent(content, SECTION_INDENTATION)}"""

Expand Down
12 changes: 6 additions & 6 deletions fire/helptext_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def testHelpTextFunctionWithKwargsAndDefaults(self):

def testHelpTextFunctionWithDefaultsAndTypes(self):
component = (
tc.py3.WithDefaultsAndTypes().double) # pytype: disable=module-attr
tc.py3.WithDefaultsAndTypes().double)
help_screen = helptext.HelpText(
component=component,
trace=trace.FireTrace(component, name='double'))
Expand All @@ -139,7 +139,7 @@ def testHelpTextFunctionWithDefaultsAndTypes(self):

def testHelpTextFunctionWithTypesAndDefaultNone(self):
component = (
tc.py3.WithDefaultsAndTypes().get_int) # pytype: disable=module-attr
tc.py3.WithDefaultsAndTypes().get_int)
help_screen = helptext.HelpText(
component=component,
trace=trace.FireTrace(component, name='get_int'))
Expand All @@ -153,7 +153,7 @@ def testHelpTextFunctionWithTypesAndDefaultNone(self):
self.assertNotIn('NOTES', help_screen)

def testHelpTextFunctionWithTypes(self):
component = tc.py3.WithTypes().double # pytype: disable=module-attr
component = tc.py3.WithTypes().double
help_screen = helptext.HelpText(
component=component,
trace=trace.FireTrace(component, name='double'))
Expand All @@ -168,7 +168,7 @@ def testHelpTextFunctionWithTypes(self):
help_screen)

def testHelpTextFunctionWithLongTypes(self):
component = tc.py3.WithTypes().long_type # pytype: disable=module-attr
component = tc.py3.WithTypes().long_type
help_screen = helptext.HelpText(
component=component,
trace=trace.FireTrace(component, name='long_type'))
Expand Down Expand Up @@ -263,14 +263,14 @@ def testHelpTextNoInit(self):
self.assertIn('SYNOPSIS\n OldStyleEmpty', help_screen)

def testHelpTextKeywordOnlyArgumentsWithDefault(self):
component = tc.py3.KeywordOnly.with_default # pytype: disable=module-attr
component = tc.py3.KeywordOnly.with_default
output = helptext.HelpText(
component=component, trace=trace.FireTrace(component, 'with_default'))
self.assertIn('NAME\n with_default', output)
self.assertIn('FLAGS\n -x, --x=X', output)

def testHelpTextKeywordOnlyArgumentsWithoutDefault(self):
component = tc.py3.KeywordOnly.double # pytype: disable=module-attr
component = tc.py3.KeywordOnly.double
output = helptext.HelpText(
component=component, trace=trace.FireTrace(component, 'double'))
self.assertIn('NAME\n double', output)
Expand Down
17 changes: 8 additions & 9 deletions fire/inspectutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ def Py3GetFullArgSpec(fn):
An inspect.FullArgSpec namedtuple with the full arg spec of the function.
"""
# pylint: disable=no-member
# pytype: disable=module-attr

try:
sig = inspect._signature_from_callable( # pylint: disable=protected-access
sig = inspect._signature_from_callable( # pylint: disable=protected-access # type: ignore
fn,
skip_bound_arg=True,
follow_wrapper_chains=True,
Expand All @@ -129,19 +129,19 @@ def Py3GetFullArgSpec(fn):
name = param.name

# pylint: disable=protected-access
if kind is inspect._POSITIONAL_ONLY:
if kind is inspect._POSITIONAL_ONLY: # type: ignore
args.append(name)
elif kind is inspect._POSITIONAL_OR_KEYWORD:
elif kind is inspect._POSITIONAL_OR_KEYWORD: # type: ignore
args.append(name)
if param.default is not param.empty:
defaults += (param.default,)
elif kind is inspect._VAR_POSITIONAL:
elif kind is inspect._VAR_POSITIONAL: # type: ignore
varargs = name
elif kind is inspect._KEYWORD_ONLY:
elif kind is inspect._KEYWORD_ONLY: # type: ignore
kwonlyargs.append(name)
if param.default is not param.empty:
kwdefaults[name] = param.default
elif kind is inspect._VAR_KEYWORD:
elif kind is inspect._VAR_KEYWORD: # type: ignore
varkw = name
if param.annotation is not param.empty:
annotations[name] = param.annotation
Expand All @@ -157,7 +157,6 @@ def Py3GetFullArgSpec(fn):
return inspect.FullArgSpec(args, varargs, varkw, defaults,
kwonlyargs, kwdefaults, annotations)
# pylint: enable=no-member
# pytype: enable=module-attr


def GetFullArgSpec(fn):
Expand Down Expand Up @@ -259,7 +258,7 @@ def Info(component):
try:
inspector = oinspect.Inspector(theme_name="neutral")
except TypeError: # Only recent versions of IPython support theme_name.
inspector = oinspect.Inspector()
inspector = oinspect.Inspector() # type: ignore
info = inspector.info(component)

# IPython's oinspect.Inspector.info may return '<no docstring>'
Expand Down
2 changes: 1 addition & 1 deletion fire/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def testFileNameModuleDuplication(self):
def testFileNameModuleFileFailure(self):
# Confirm that an invalid file that masks a non-existent module fails.
with self.assertRaisesRegex(ValueError,
r'Fire can only be called on \.py files\.'): # pylint: disable=line-too-long, # pytype: disable=attribute-error
r'Fire can only be called on \.py files\.'): # pylint: disable=line-too-long,
dirname = os.path.dirname(self.file.name)
with testutils.ChangeDirectory(dirname):
with open('foobar', 'w'):
Expand Down
2 changes: 1 addition & 1 deletion fire/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def _LiteralEval(value):
SyntaxError: If the value string has a syntax error.
"""
root = ast.parse(value, mode='eval')
if isinstance(root.body, ast.BinOp): # pytype: disable=attribute-error
if isinstance(root.body, ast.BinOp):
raise ValueError(value)

for node in ast.walk(root):
Expand Down
2 changes: 0 additions & 2 deletions fire/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ def __init__(self, initial_component, name=None, separator='-', verbose=False,

def GetResult(self):
"""Returns the component from the last element of the trace."""
# pytype: disable=attribute-error
return self.GetLastHealthyElement().component
# pytype: enable=attribute-error

def GetLastHealthyElement(self):
"""Returns the last element of the trace that is not an error.
Expand Down
4 changes: 0 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,3 @@ addopts = [
"--ignore=fire/test_components_py3.py",
"--ignore=fire/parser_fuzz_test.py"
]

[tool.pytype]
inputs = "."
output = ".pytype"
Loading