Some `isinstance(obj, os.PathLike)` widen the type of `obj`
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug Report
Given an object of type Union[None, str, pathlib.Path] the revealed type before and after a check
if isinstance(obj, os.PathLike):
# code
widens from the given type before to builtin.object afterwards.
To Reproduce
Unfortunately, I have not been able to make a minimal reproducer, since all my attempts have type checked fine.
We've encounted this in this commit of the PR https://github.com/systemd/mkosi/pull/2373. The codebase is stdlib only and targets Python 3.9 (because it is shipped in RHEL).
One of the two examples can be found in the function built_uki here. The incoming Context object is a dataclass that holds many things, but relevant for this issue is context.config.secure_boot_key, which has type Union[None, str, pathlib.Path]. This type is defined on the dataclass and mypy reveals it at the beginning of the function.
Adding a lot of reveal_type statements I could find that this line building a command line for a program
reveal_type(context.config.secure_boot_key)
if isinstance(context.config.secure_boot_key, os.PathLike):
options += ["--ro-bind", context.config.secure_boot_key, context.config.secure_boot_key]
reveal_type(context.config.secure_boot_key)
switches the revealed type:
mkosi/__init__.py:1906:25: note: Revealed type is "Union[pathlib.Path, builtins.str]"
mkosi/__init__.py:1909:25: note: Revealed type is "builtins.object"
mkosi/__init__.py:1931:38: error: List item 1 has incompatible type "object"; expected "Union[Path, str]" [list-item]
"--pcr-private-key", context.config.secure_boot_key,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 1 error in 1 file (checked 42 source files)
Looking further the changes in the commit, not all isinstance(context.config.secure_boot_key, os.PathLike) checks added there suffer from this problem.
The problem has been encountered with
$ mypy --version
mypy 1.8.0 (compiled: no)
but pyright reveals the proper type.
Expected Behavior
The type of the object does not change.
Actual Behavior
The type is widened to builtin.object
mkosi/__init__.py:1906:25: note: Revealed type is "Union[pathlib.Path, builtins.str]"
mkosi/__init__.py:1909:25: note: Revealed type is "builtins.object"
mkosi/__init__.py:1931:38: error: List item 1 has incompatible type "object"; expected "Union[Path, str]" [list-item]
"--pcr-private-key", context.config.secure_boot_key,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 1 error in 1 file (checked 42 source files)
The problem can be worked around by changing the check
-if isinstance(context.config.secure_boot_key, os.PathLike):
+if context.config.secure_boot_key and not isinstance(context.config.secure_boot_key, str):
Your Environment
- Mypy version used: 1.8.0
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini(and other config files): The following section inpyproject.tomlis used to configure mypy:
[tool.mypy]
python_version = 3.9
# belonging to --strict
warn_unused_configs = true
disallow_any_generics = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_untyped_decorators = true
disallow_incomplete_defs = true
check_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = false
warn_return_any = true
no_implicit_reexport = true
# extra options not in --strict
pretty = true
show_error_codes = true
show_column_numbers = true
warn_unreachable = true
allow_redefinition = true
strict_equality = true
- Python version used: 3.11.7 on Arch Linux
I'm happy to provide more details
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, das gemeldete Verhalten anhand des built_uki-Beispiels aus mkosi/init.py mit mypy 1.8.0 und dem gezeigten Wert Union[None, str, pathlib.Path] zu reproduzieren. Verfolge die Eingrenzung durch isinstance und füge einen Regressionstest hinzu, der zeigt, dass der Typ nach der Prüfung weiterhin als Union[Path, str] verwendbar ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 35/100