diff options
| author | Eli Schwartz <eschwartz93@gmail.com> | 2025-09-21 01:41:06 -0400 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2025-09-25 12:58:43 -0400 |
| commit | ee0a1c6b5bb7c42096cf6ea088865dd841dec438 (patch) | |
| tree | 8272b36087f4f2c9b0eab90966bee0f5978826a2 | |
| parent | 6cb9d898ebb5d0f1d619d4937b1c316400802609 (diff) | |
| download | meson-ee0a1c6b5bb7c42096cf6ea088865dd841dec438.tar.gz | |
mypy: enable allow-redefinition-new and fix fallout
Reduces 3 errors that show up in newer mypy versions than pinned in CI.
It is new since 1.16 and a likely future default for mypy 2.0. It allows
things like:
```
for i in ['one', 'two', 'three']:
frob_a(i)
for i in [1, 2, 3]:
frob_b(i)
```
since "i" is obviously used as a loop holder and its type can be freely
reinvented. Note: allow-redefinition-new isn't actually about this at
all, it has greater scope than loop holders and allows redefining
"unannotated variables" of all kinds. No granularity in what to accept
redefinition of. :P
To enable this, we must also opt in to local-partial-types, which has
some overlap with None-safety. Specifically:
> the most common cases for partial types are variables initialized
> using None, but without explicit X | None annotations. By default, mypy
> won’t check partial types spanning module top level or class top level.
> This flag changes the behavior to only allow partial types at local
> level, therefore it disallows inferring variable type for None from two
> assignments in different scopes.
So with this, we also fix a couple of actual type errors this revealed.
Where possible, stop None-initializing at all -- it's not strictly
needed for global variables, anyway, and it's a coding error if it is
possible to hit these variables without defining them first.
Bug: https://github.com/python/mypy/issues/19280
| -rw-r--r-- | .mypy.ini | 4 | ||||
| -rw-r--r-- | mesonbuild/ast/interpreter.py | 3 | ||||
| -rw-r--r-- | mesonbuild/dependencies/base.py | 3 | ||||
| -rw-r--r-- | mesonbuild/modules/cmake.py | 2 | ||||
| -rw-r--r-- | mesonbuild/modules/external_project.py | 4 | ||||
| -rw-r--r-- | mesonbuild/scripts/symbolextractor.py | 2 | ||||
| -rwxr-xr-x | run_project_tests.py | 10 |
7 files changed, 17 insertions, 11 deletions
@@ -22,3 +22,7 @@ check_untyped_defs = True # disallow_any_explicit = True # disallow_any_generics = True # disallow_subclassing_any = True + +# future default behaviors +allow_redefinition_new = True +local_partial_types = True diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py index 524f33193..2f82a4a84 100644 --- a/mesonbuild/ast/interpreter.py +++ b/mesonbuild/ast/interpreter.py @@ -731,7 +731,8 @@ class AstInterpreter(InterpreterBase): else: args = [args_raw] - flattened_args: T.List[TYPE_var] = [] + # BaseNode resolves to Any. :/ + flattened_args: T.List[T.Union[TYPE_var, T.Any]] = [] # Resolve the contents of args for i in args: diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 732bae544..72dbfdf2d 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -631,7 +631,8 @@ def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: T.Dict[st # Set the detection method. If the method is set to auto, use any available method. # If method is set to a specific string, allow only that detection method. if method == DependencyMethods.AUTO: - methods = list(possible) + # annotated for https://github.com/python/mypy/issues/19894 + methods: T.List[DependencyMethods] = list(possible) elif method in possible: methods = [method] else: diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py index f12cc51a6..fc300fab2 100644 --- a/mesonbuild/modules/cmake.py +++ b/mesonbuild/modules/cmake.py @@ -243,7 +243,7 @@ class CMakeSubprojectOptions(ModuleObject): class CmakeModule(ExtensionModule): cmake_detected = False - cmake_root = None + cmake_root: str INFO = ModuleInfo('cmake', '0.50.0') diff --git a/mesonbuild/modules/external_project.py b/mesonbuild/modules/external_project.py index ba7b30075..0881df94e 100644 --- a/mesonbuild/modules/external_project.py +++ b/mesonbuild/modules/external_project.py @@ -169,7 +169,7 @@ class ExternalProject(NewExtensionModule): def _quote_and_join(self, array: T.List[str]) -> str: return ' '.join([shlex.quote(i) for i in array]) - def _validate_configure_options(self, variables: T.List[T.Tuple[str, str, str]], state: 'ModuleState') -> None: + def _validate_configure_options(self, variables: T.Sequence[T.Tuple[str, T.Optional[str], str]], state: 'ModuleState') -> None: # Ensure the user at least try to pass basic info to the build system, # like the prefix, libdir, etc. for key, default, val in variables: @@ -183,7 +183,7 @@ class ExternalProject(NewExtensionModule): FeatureNew('Default configure_option', '0.57.0').use(self.subproject, state.current_node) self.configure_options.append(default) - def _format_options(self, options: T.List[str], variables: T.List[T.Tuple[str, str, str]]) -> T.List[str]: + def _format_options(self, options: T.List[str], variables: T.Sequence[T.Tuple[str, T.Optional[str], str]]) -> T.List[str]: out: T.List[str] = [] missing = set() regex = get_variable_regex('meson') diff --git a/mesonbuild/scripts/symbolextractor.py b/mesonbuild/scripts/symbolextractor.py index b0a07d906..c0aa6502b 100644 --- a/mesonbuild/scripts/symbolextractor.py +++ b/mesonbuild/scripts/symbolextractor.py @@ -23,7 +23,7 @@ parser.add_argument('--cross-host', default=None, dest='cross_host', help='cross compilation host platform') parser.add_argument('args', nargs='+') -TOOL_WARNING_FILE = None +TOOL_WARNING_FILE: str RELINKING_WARNING = 'Relinking will always happen on source changes.' def dummy_syms(outfilename: str) -> None: diff --git a/run_project_tests.py b/run_project_tests.py index b2442703e..7067bfa0b 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -1577,11 +1577,11 @@ def detect_tools(report: bool = True) -> None: print('{0:<{2}}: {1}'.format(tool.tool, get_version(tool), max_width)) print() -symlink_test_dir1 = None -symlink_test_dir2 = None -symlink_file1 = None -symlink_file2 = None -symlink_file3 = None +symlink_test_dir1: T.Optional[Path] = None +symlink_test_dir2: T.Optional[Path] = None +symlink_file1: T.Optional[Path] = None +symlink_file2: T.Optional[Path] = None +symlink_file3: T.Optional[Path] = None def scan_test_data_symlinks() -> None: global symlink_test_dir1, symlink_test_dir2, symlink_file1, symlink_file2, symlink_file3 |
