diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f853528d5..57896c395 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: blacken-docs additional_dependencies: [black==20.8b1] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.1.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -48,7 +48,7 @@ repos: hooks: - id: python-use-type-annotations - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.920 + rev: v0.930 hooks: - id: mypy files: ^(src/|testing/) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 1bdd8effb..dee3d4974 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1429,6 +1429,7 @@ class Config: ) except KeyError: return None + assert mod.__file__ is not None modpath = Path(mod.__file__).parent values: List[Path] = [] for relroot in relroots: @@ -1574,7 +1575,7 @@ def _strtobool(val: str) -> bool: @lru_cache(maxsize=50) def parse_warning_filter( arg: str, *, escape: bool -) -> Tuple[str, str, Type[Warning], str, int]: +) -> Tuple["warnings._ActionKind", str, Type[Warning], str, int]: """Parse a warnings filter string. This is copied from warnings._setoption with the following changes: @@ -1616,7 +1617,7 @@ def parse_warning_filter( parts.append("") action_, message, category_, module, lineno_ = (s.strip() for s in parts) try: - action: str = warnings._getaction(action_) # type: ignore[attr-defined] + action: "warnings._ActionKind" = warnings._getaction(action_) # type: ignore[attr-defined] except warnings._OptionError as e: raise UsageError(error_template.format(error=str(e))) try: diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index 31f95a95a..91d590fb3 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -55,7 +55,7 @@ def resolve(name: str) -> object: parts = name.split(".") used = parts.pop(0) - found = __import__(used) + found: object = __import__(used) for part in parts: used += "." + part try: diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index b23e51d44..def5fa94b 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -539,6 +539,9 @@ def import_path( ignore = os.environ.get("PY_IGNORE_IMPORTMISMATCH", "") if ignore != "1": module_file = mod.__file__ + if module_file is None: + raise ImportPathMismatchError(module_name, module_file, path) + if module_file.endswith((".pyc", ".pyo")): module_file = module_file[:-1] if module_file.endswith(os.path.sep + "__init__.py"): diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 0462665cd..90f035e8f 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -330,6 +330,7 @@ class PyobjMixin(nodes.Node): if isinstance(compat_co_firstlineno, int): # nose compatibility file_path = sys.modules[obj.__module__].__file__ + assert file_path is not None if file_path.endswith(".pyc"): file_path = file_path[:-1] path: Union["os.PathLike[str]", str] = file_path diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 64c1014a5..92a5ffb72 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -114,6 +114,7 @@ class TestConftestValueAccessGlobal: "a", startdir, importmode="prepend", rootpath=Path(basedir) ) assert value == 1.5 + assert mod.__file__ is not None path = Path(mod.__file__) assert path.parent == basedir / "adir" / "b" assert path.stem == "conftest" @@ -197,12 +198,14 @@ def test_conftestcutdir(pytester: Pytester) -> None: values = conftest._getconftestmodules( conf.parent, importmode="prepend", rootpath=pytester.path ) + assert values[0].__file__ is not None assert values[0].__file__.startswith(str(conf)) # and all sub paths get updated properly values = conftest._getconftestmodules( p, importmode="prepend", rootpath=pytester.path ) assert len(values) == 1 + assert values[0].__file__ is not None assert values[0].__file__.startswith(str(conf)) @@ -214,6 +217,7 @@ def test_conftestcutdir_inplace_considered(pytester: Pytester) -> None: conf.parent, importmode="prepend", rootpath=pytester.path ) assert len(values) == 1 + assert values[0].__file__ is not None assert values[0].__file__.startswith(str(conf)) diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index 24cd71b25..fe5e08f21 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -143,6 +143,10 @@ class TestImportPath: assert obj.x == 42 # type: ignore[attr-defined] assert obj.__name__ == "execfile" + def test_import_path_missing_file(self, path1: Path) -> None: + with pytest.raises(ImportPathMismatchError): + import_path(path1 / "sampledir", root=path1) + def test_renamed_dir_creates_mismatch( self, tmp_path: Path, monkeypatch: MonkeyPatch ) -> None: