main: add `module_name` to `CollectionArgument`
This is available when the argument is a `--pyargs` argument (resolved from a python module path). Will be used in an upcoming commit.
This commit is contained in:
parent
5e0d11746c
commit
1612d4e393
|
@ -957,17 +957,18 @@ class Session(nodes.Collector):
|
||||||
node.ihook.pytest_collectreport(report=rep)
|
node.ihook.pytest_collectreport(report=rep)
|
||||||
|
|
||||||
|
|
||||||
def search_pypath(module_name: str) -> str:
|
def search_pypath(module_name: str) -> Optional[str]:
|
||||||
"""Search sys.path for the given a dotted module name, and return its file system path."""
|
"""Search sys.path for the given a dotted module name, and return its file
|
||||||
|
system path if found."""
|
||||||
try:
|
try:
|
||||||
spec = importlib.util.find_spec(module_name)
|
spec = importlib.util.find_spec(module_name)
|
||||||
# AttributeError: looks like package module, but actually filename
|
# AttributeError: looks like package module, but actually filename
|
||||||
# ImportError: module does not exist
|
# ImportError: module does not exist
|
||||||
# ValueError: not a module name
|
# ValueError: not a module name
|
||||||
except (AttributeError, ImportError, ValueError):
|
except (AttributeError, ImportError, ValueError):
|
||||||
return module_name
|
return None
|
||||||
if spec is None or spec.origin is None or spec.origin == "namespace":
|
if spec is None or spec.origin is None or spec.origin == "namespace":
|
||||||
return module_name
|
return None
|
||||||
elif spec.submodule_search_locations:
|
elif spec.submodule_search_locations:
|
||||||
return os.path.dirname(spec.origin)
|
return os.path.dirname(spec.origin)
|
||||||
else:
|
else:
|
||||||
|
@ -980,6 +981,7 @@ class CollectionArgument:
|
||||||
|
|
||||||
path: Path
|
path: Path
|
||||||
parts: Sequence[str]
|
parts: Sequence[str]
|
||||||
|
module_name: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
def resolve_collection_argument(
|
def resolve_collection_argument(
|
||||||
|
@ -997,6 +999,7 @@ def resolve_collection_argument(
|
||||||
CollectionArgument(
|
CollectionArgument(
|
||||||
path=Path("/full/path/to/pkg/tests/test_foo.py"),
|
path=Path("/full/path/to/pkg/tests/test_foo.py"),
|
||||||
parts=["TestClass", "test_foo"],
|
parts=["TestClass", "test_foo"],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
When as_pypath is True, expects that the command-line argument actually contains
|
When as_pypath is True, expects that the command-line argument actually contains
|
||||||
|
@ -1010,6 +1013,7 @@ def resolve_collection_argument(
|
||||||
CollectionArgument(
|
CollectionArgument(
|
||||||
path=Path("/home/u/myvenv/lib/site-packages/pkg/tests/test_foo.py"),
|
path=Path("/home/u/myvenv/lib/site-packages/pkg/tests/test_foo.py"),
|
||||||
parts=["TestClass", "test_foo"],
|
parts=["TestClass", "test_foo"],
|
||||||
|
module_name="pkg.tests.test_foo",
|
||||||
)
|
)
|
||||||
|
|
||||||
If the path doesn't exist, raise UsageError.
|
If the path doesn't exist, raise UsageError.
|
||||||
|
@ -1019,8 +1023,12 @@ def resolve_collection_argument(
|
||||||
strpath, *parts = base.split("::")
|
strpath, *parts = base.split("::")
|
||||||
if parts:
|
if parts:
|
||||||
parts[-1] = f"{parts[-1]}{squacket}{rest}"
|
parts[-1] = f"{parts[-1]}{squacket}{rest}"
|
||||||
|
module_name = None
|
||||||
if as_pypath:
|
if as_pypath:
|
||||||
strpath = search_pypath(strpath)
|
pyarg_strpath = search_pypath(strpath)
|
||||||
|
if pyarg_strpath is not None:
|
||||||
|
module_name = strpath
|
||||||
|
strpath = pyarg_strpath
|
||||||
fspath = invocation_path / strpath
|
fspath = invocation_path / strpath
|
||||||
fspath = absolutepath(fspath)
|
fspath = absolutepath(fspath)
|
||||||
if not safe_exists(fspath):
|
if not safe_exists(fspath):
|
||||||
|
@ -1040,4 +1048,5 @@ def resolve_collection_argument(
|
||||||
return CollectionArgument(
|
return CollectionArgument(
|
||||||
path=fspath,
|
path=fspath,
|
||||||
parts=parts,
|
parts=parts,
|
||||||
|
module_name=module_name,
|
||||||
)
|
)
|
||||||
|
|
|
@ -139,24 +139,28 @@ class TestResolveCollectionArgument:
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=[],
|
parts=[],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
assert resolve_collection_argument(
|
assert resolve_collection_argument(
|
||||||
invocation_path, "src/pkg/test.py::"
|
invocation_path, "src/pkg/test.py::"
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=[""],
|
parts=[""],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
assert resolve_collection_argument(
|
assert resolve_collection_argument(
|
||||||
invocation_path, "src/pkg/test.py::foo::bar"
|
invocation_path, "src/pkg/test.py::foo::bar"
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=["foo", "bar"],
|
parts=["foo", "bar"],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
assert resolve_collection_argument(
|
assert resolve_collection_argument(
|
||||||
invocation_path, "src/pkg/test.py::foo::bar::"
|
invocation_path, "src/pkg/test.py::foo::bar::"
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=["foo", "bar", ""],
|
parts=["foo", "bar", ""],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_dir(self, invocation_path: Path) -> None:
|
def test_dir(self, invocation_path: Path) -> None:
|
||||||
|
@ -166,6 +170,7 @@ class TestResolveCollectionArgument:
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg",
|
path=invocation_path / "src/pkg",
|
||||||
parts=[],
|
parts=[],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
|
@ -185,18 +190,21 @@ class TestResolveCollectionArgument:
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=[],
|
parts=[],
|
||||||
|
module_name="pkg.test",
|
||||||
)
|
)
|
||||||
assert resolve_collection_argument(
|
assert resolve_collection_argument(
|
||||||
invocation_path, "pkg.test::foo::bar", as_pypath=True
|
invocation_path, "pkg.test::foo::bar", as_pypath=True
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=["foo", "bar"],
|
parts=["foo", "bar"],
|
||||||
|
module_name="pkg.test",
|
||||||
)
|
)
|
||||||
assert resolve_collection_argument(
|
assert resolve_collection_argument(
|
||||||
invocation_path, "pkg", as_pypath=True
|
invocation_path, "pkg", as_pypath=True
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg",
|
path=invocation_path / "src/pkg",
|
||||||
parts=[],
|
parts=[],
|
||||||
|
module_name="pkg",
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
|
@ -212,6 +220,7 @@ class TestResolveCollectionArgument:
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=invocation_path / "src/pkg/test.py",
|
path=invocation_path / "src/pkg/test.py",
|
||||||
parts=["test[a::b]"],
|
parts=["test[a::b]"],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_does_not_exist(self, invocation_path: Path) -> None:
|
def test_does_not_exist(self, invocation_path: Path) -> None:
|
||||||
|
@ -237,6 +246,7 @@ class TestResolveCollectionArgument:
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=Path(os.path.abspath("src")),
|
path=Path(os.path.abspath("src")),
|
||||||
parts=[],
|
parts=[],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# ensure full paths given in the command-line without the drive letter resolve
|
# ensure full paths given in the command-line without the drive letter resolve
|
||||||
|
@ -247,6 +257,7 @@ class TestResolveCollectionArgument:
|
||||||
) == CollectionArgument(
|
) == CollectionArgument(
|
||||||
path=Path(os.path.abspath("src")),
|
path=Path(os.path.abspath("src")),
|
||||||
parts=[],
|
parts=[],
|
||||||
|
module_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue