diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 7f5cf491..d9207dfe 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -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 diff --git a/fire/__main__.py b/fire/__main__.py index 140b4a76..eb98b1a4 100644 --- a/fire/__main__.py +++ b/fire/__main__.py @@ -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 diff --git a/fire/console/console_attr_os.py b/fire/console/console_attr_os.py index 869c5949..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 @@ -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 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/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/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/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/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.py b/fire/helptext.py index 318d6276..347278da 100644 --- a/fire/helptext.py +++ b/fire/helptext.py @@ -29,6 +29,8 @@ information. """ +from __future__ import annotations + import collections import itertools @@ -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. @@ -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) @@ -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: @@ -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)}""" 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 d9c62ca7..6dd8fd67 100644 --- a/fire/inspectutils.py +++ b/fire/inspectutils.py @@ -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, @@ -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 @@ -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): @@ -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 '' 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..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.""" - # 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. diff --git a/pyproject.toml b/pyproject.toml index 6a6ba63e..dfb1eeba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,3 @@ addopts = [ "--ignore=fire/test_components_py3.py", "--ignore=fire/parser_fuzz_test.py" ] - -[tool.pytype] -inputs = "." -output = ".pytype" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy