Some `isinstance(obj, os.PathLike)` widen the type of `obj`
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
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
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、mypy 1.8.0 と示されている Union[None, str, pathlib.Path] の値を使用して、mkosi/init.py の built_uki の例で報告された動作を再現します。isinstance による型の絞り込みを追跡し、チェック後も型が Union[Path, str] として利用可能であることを示すリグレッションケースを追加します。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- 説明が足りない
- 初心者へのやさしさ
- 35/100