From 9aa3f6933133602b7c896b72ff43d8ebfaa1d15a Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 22:49:34 -0400 Subject: [PATCH 01/11] Use ty in place of pytype --- .github/scripts/build.sh | 6 +++--- fire/__main__.py | 2 +- fire/custom_descriptions.py | 8 ++++---- fire/helptext.py | 12 +++++++----- pyproject.toml | 5 ++--- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 7f5cf491..647122b8 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -25,7 +25,7 @@ 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; + # Run type-checking with ty. + pip install uv; + uvx ty check; fi diff --git a/fire/__main__.py b/fire/__main__.py index 140b4a76..3cda84fb 100644 --- a/fire/__main__.py +++ b/fire/__main__.py @@ -60,7 +60,7 @@ 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 diff --git a/fire/custom_descriptions.py b/fire/custom_descriptions.py index 768f0e23..ef1130a3 100644 --- a/fire/custom_descriptions.py +++ b/fire/custom_descriptions.py @@ -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 diff --git a/fire/helptext.py b/fire/helptext.py index 318d6276..94c55075 100644 --- a/fire/helptext.py +++ b/fire/helptext.py @@ -29,6 +29,8 @@ information. """ +from __future__ import annotations + import collections import itertools @@ -91,7 +93,7 @@ def HelpText(component, trace=None, verbose=False): ) -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. @@ -113,7 +115,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) @@ -136,7 +138,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: @@ -185,7 +187,7 @@ def _GetShortFlags(flags): return [v for v in short_flags if short_flag_counts[v] == 1] -def _ArgsAndFlagsSections(info, spec, metadata): +def _ArgsAndFlagsSections(info, spec, metadata) -> tuple[list[tuple[str, str]], list[tuple[str, str]]]: """The "Args and Flags" sections of the help string.""" args_with_no_defaults = spec.args[:len(spec.args) - len(spec.defaults)] args_with_defaults = spec.args[len(spec.args) - len(spec.defaults):] @@ -408,7 +410,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)}""" diff --git a/pyproject.toml b/pyproject.toml index 6a6ba63e..ee46e955 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,5 @@ addopts = [ "--ignore=fire/parser_fuzz_test.py" ] -[tool.pytype] -inputs = "." -output = ".pytype" +[tool.ty] +# ty configuration - using defaults for now From b663620dd0453c446ed17da8b4ef33648de3c8c3 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 22:50:56 -0400 Subject: [PATCH 02/11] Remove long annotation --- fire/helptext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fire/helptext.py b/fire/helptext.py index 94c55075..6e673e17 100644 --- a/fire/helptext.py +++ b/fire/helptext.py @@ -187,7 +187,7 @@ def _GetShortFlags(flags): return [v for v in short_flags if short_flag_counts[v] == 1] -def _ArgsAndFlagsSections(info, spec, metadata) -> tuple[list[tuple[str, str]], list[tuple[str, str]]]: +def _ArgsAndFlagsSections(info, spec, metadata): """The "Args and Flags" sections of the help string.""" args_with_no_defaults = spec.args[:len(spec.args) - len(spec.defaults)] args_with_defaults = spec.args[len(spec.args) - len(spec.defaults):] From 3d78d024223ba8a08caf09fb8b24b8acffdb3e37 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 22:52:07 -0400 Subject: [PATCH 03/11] Exclude test components --- .github/scripts/build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 647122b8..c23e98bc 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -25,7 +25,7 @@ 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 with ty. - pip install uv; - uvx ty check; + # Run type-checking + pip install uv + uvx ty check --exclude fire/test_components_py3.py fi From b2e79265903a0a7a7993197c6b3499a5a190c7cd Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 22:58:04 -0400 Subject: [PATCH 04/11] Add type comments --- .github/scripts/build.sh | 2 +- fire/inspectutils.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index c23e98bc..83c523c0 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -24,7 +24,7 @@ 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 +if [[ ${PYTHON_VERSION} == 3.12 ]]; then # Run type-checking pip install uv uvx ty check --exclude fire/test_components_py3.py diff --git a/fire/inspectutils.py b/fire/inspectutils.py index d9c62ca7..e84b80ee 100644 --- a/fire/inspectutils.py +++ b/fire/inspectutils.py @@ -102,7 +102,7 @@ def Py3GetFullArgSpec(fn): # 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, @@ -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 @@ -259,7 +259,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 '' From 89682cfe8ebee98eadb07c33e8e324d67cb798f3 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:03:24 -0400 Subject: [PATCH 05/11] Fix all ty errors --- .github/scripts/build.sh | 2 +- fire/console/console_attr_os.py | 2 +- fire/helptext.py | 7 ++++--- pyproject.toml | 3 --- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 83c523c0..1490e5eb 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -27,5 +27,5 @@ pylint fire --ignore=test_components_py3.py,parser_fuzz_test.py,console if [[ ${PYTHON_VERSION} == 3.12 ]]; then # Run type-checking pip install uv - uvx ty check --exclude fire/test_components_py3.py + uvx ty check --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py fi diff --git a/fire/console/console_attr_os.py b/fire/console/console_attr_os.py index 869c5949..84c0bb69 100644 --- a/fire/console/console_attr_os.py +++ b/fire/console/console_attr_os.py @@ -73,7 +73,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 diff --git a/fire/helptext.py b/fire/helptext.py index 6e673e17..d36580f8 100644 --- a/fire/helptext.py +++ b/fire/helptext.py @@ -87,9 +87,10 @@ 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 ) @@ -283,7 +284,7 @@ def _ArgsAndFlagsSections(info, spec, metadata): return args_and_flags_sections, notes_sections -def _UsageDetailsSections(component, actions_grouped_by_kind): +def _UsageDetailsSections(component, actions_grouped_by_kind) -> list[tuple[str, str]]: """The usage details sections of the help string.""" groups, commands, values, indexes = actions_grouped_by_kind diff --git a/pyproject.toml b/pyproject.toml index ee46e955..dfb1eeba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,3 @@ addopts = [ "--ignore=fire/test_components_py3.py", "--ignore=fire/parser_fuzz_test.py" ] - -[tool.ty] -# ty configuration - using defaults for now From ee757c5eba5946708aef6dd1fc9b6a795d7f3d76 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:05:32 -0400 Subject: [PATCH 06/11] Remove pytype comments --- fire/__main__.py | 2 +- fire/console/encoding.py | 12 ++++++------ fire/core.py | 4 ++-- fire/decorators.py | 2 +- fire/docstrings.py | 2 +- fire/helptext.py | 2 +- fire/main_test.py | 2 +- fire/parser.py | 2 +- fire/trace.py | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/fire/__main__.py b/fire/__main__.py index 3cda84fb..eb98b1a4 100644 --- a/fire/__main__.py +++ b/fire/__main__.py @@ -64,7 +64,7 @@ def import_from_file_path(path): 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 diff --git a/fire/console/encoding.py b/fire/console/encoding.py index 3ce30cb5..662342c6 100644 --- a/fire/console/encoding.py +++ b/fire/console/encoding.py @@ -67,7 +67,7 @@ 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 @@ -75,7 +75,7 @@ def Decode(data, encoding=None): # 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 @@ -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 @@ -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): diff --git a/fire/core.py b/fire/core.py index 26a25753..32e0e9cc 100644 --- a/fire/core.py +++ b/fire/core.py @@ -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 @@ -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 diff --git a/fire/decorators.py b/fire/decorators.py index 914b1de6..547153c6 100644 --- a/fire/decorators.py +++ b/fire/decorators.py @@ -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 diff --git a/fire/docstrings.py b/fire/docstrings.py index 2d7c7e63..2adfe5ec 100644 --- a/fire/docstrings.py +++ b/fire/docstrings.py @@ -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( diff --git a/fire/helptext.py b/fire/helptext.py index d36580f8..347278da 100644 --- a/fire/helptext.py +++ b/fire/helptext.py @@ -284,7 +284,7 @@ def _ArgsAndFlagsSections(info, spec, metadata): return args_and_flags_sections, notes_sections -def _UsageDetailsSections(component, actions_grouped_by_kind) -> list[tuple[str, str]]: +def _UsageDetailsSections(component, actions_grouped_by_kind): """The usage details sections of the help string.""" groups, commands, values, indexes = actions_grouped_by_kind diff --git a/fire/main_test.py b/fire/main_test.py index a2723347..9e1c382b 100644 --- a/fire/main_test.py +++ b/fire/main_test.py @@ -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'): diff --git a/fire/parser.py b/fire/parser.py index d945b8ce..b8e7f19c 100644 --- a/fire/parser.py +++ b/fire/parser.py @@ -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): diff --git a/fire/trace.py b/fire/trace.py index 4a6d4776..69050540 100644 --- a/fire/trace.py +++ b/fire/trace.py @@ -62,7 +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 From 8f4de66dcbe914b3c51c555546cae68adc21c33c Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:07:07 -0400 Subject: [PATCH 07/11] Remove pytype comments further --- fire/core_test.py | 4 ++-- fire/formatting_windows.py | 6 +++--- fire/helptext_test.py | 12 ++++++------ fire/inspectutils.py | 3 +-- fire/trace.py | 2 -- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/fire/core_test.py b/fire/core_test.py index 90b7f466..f48d6e2d 100644 --- a/fire/core_test.py +++ b/fire/core_test.py @@ -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') diff --git a/fire/formatting_windows.py b/fire/formatting_windows.py index cee6f393..749ab6d0 100644 --- a/fire/formatting_windows.py +++ b/fire/formatting_windows.py @@ -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 @@ -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: diff --git a/fire/helptext_test.py b/fire/helptext_test.py index aeff5240..c7098fc4 100644 --- a/fire/helptext_test.py +++ b/fire/helptext_test.py @@ -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')) @@ -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')) @@ -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')) @@ -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')) @@ -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) diff --git a/fire/inspectutils.py b/fire/inspectutils.py index e84b80ee..6dd8fd67 100644 --- a/fire/inspectutils.py +++ b/fire/inspectutils.py @@ -100,7 +100,7 @@ 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 # type: ignore fn, @@ -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): diff --git a/fire/trace.py b/fire/trace.py index 69050540..601026fd 100644 --- a/fire/trace.py +++ b/fire/trace.py @@ -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.""" - return self.GetLastHealthyElement().component - # pytype: enable=attribute-error def GetLastHealthyElement(self): """Returns the last element of the trace that is not an error. From 24802a724f829f1fbf0f8f8e0d684f75502cff5d Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:10:16 -0400 Subject: [PATCH 08/11] Use same env for ty --- .github/scripts/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 1490e5eb..54b79336 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -26,6 +26,6 @@ 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.12 ]]; then # Run type-checking - pip install uv - uvx ty check --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py + pip install ty + ty check --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py fi From 8230edf2209afb86e84f096750368a0d60004bb7 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:13:39 -0400 Subject: [PATCH 09/11] python -m for ty --- .github/scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 54b79336..a512a4bf 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -27,5 +27,5 @@ pylint fire --ignore=test_components_py3.py,parser_fuzz_test.py,console if [[ ${PYTHON_VERSION} == 3.12 ]]; then # Run type-checking pip install ty - ty check --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py + python -m ty check --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py fi From 49d3b367a8747495d586734539ad50854cf2a422 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:16:20 -0400 Subject: [PATCH 10/11] Select python --- .github/scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index a512a4bf..d9207dfe 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -27,5 +27,5 @@ pylint fire --ignore=test_components_py3.py,parser_fuzz_test.py,console if [[ ${PYTHON_VERSION} == 3.12 ]]; then # Run type-checking pip install ty - python -m ty check --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py + python -m ty check --python $(which python) --exclude fire/test_components_py3.py --exclude fire/console/ --exclude fire/formatting_windows.py fi From 2773a47ef718b9a7fb4d6771b2fc44029f0ab4d1 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Fri, 18 Jul 2025 23:18:33 -0400 Subject: [PATCH 11/11] Remove pytype comment --- fire/console/console_attr_os.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/fire/console/console_attr_os.py b/fire/console/console_attr_os.py index 84c0bb69..a7f38d4f 100644 --- a/fire/console/console_attr_os.py +++ b/fire/console/console_attr_os.py @@ -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