Skip to content

Commit 1612d4e

Browse files
committed
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.
1 parent 5e0d117 commit 1612d4e

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/_pytest/main.py

+14-5
Original file line numberDiff line numberDiff line change
@@ -957,17 +957,18 @@ def genitems(
957957
node.ihook.pytest_collectreport(report=rep)
958958

959959

960-
def search_pypath(module_name: str) -> str:
961-
"""Search sys.path for the given a dotted module name, and return its file system path."""
960+
def search_pypath(module_name: str) -> Optional[str]:
961+
"""Search sys.path for the given a dotted module name, and return its file
962+
system path if found."""
962963
try:
963964
spec = importlib.util.find_spec(module_name)
964965
# AttributeError: looks like package module, but actually filename
965966
# ImportError: module does not exist
966967
# ValueError: not a module name
967968
except (AttributeError, ImportError, ValueError):
968-
return module_name
969+
return None
969970
if spec is None or spec.origin is None or spec.origin == "namespace":
970-
return module_name
971+
return None
971972
elif spec.submodule_search_locations:
972973
return os.path.dirname(spec.origin)
973974
else:
@@ -980,6 +981,7 @@ class CollectionArgument:
980981

981982
path: Path
982983
parts: Sequence[str]
984+
module_name: Optional[str]
983985

984986

985987
def resolve_collection_argument(
@@ -997,6 +999,7 @@ def resolve_collection_argument(
997999
CollectionArgument(
9981000
path=Path("/full/path/to/pkg/tests/test_foo.py"),
9991001
parts=["TestClass", "test_foo"],
1002+
module_name=None,
10001003
)
10011004
10021005
When as_pypath is True, expects that the command-line argument actually contains
@@ -1010,6 +1013,7 @@ def resolve_collection_argument(
10101013
CollectionArgument(
10111014
path=Path("/home/u/myvenv/lib/site-packages/pkg/tests/test_foo.py"),
10121015
parts=["TestClass", "test_foo"],
1016+
module_name="pkg.tests.test_foo",
10131017
)
10141018
10151019
If the path doesn't exist, raise UsageError.
@@ -1019,8 +1023,12 @@ def resolve_collection_argument(
10191023
strpath, *parts = base.split("::")
10201024
if parts:
10211025
parts[-1] = f"{parts[-1]}{squacket}{rest}"
1026+
module_name = None
10221027
if as_pypath:
1023-
strpath = search_pypath(strpath)
1028+
pyarg_strpath = search_pypath(strpath)
1029+
if pyarg_strpath is not None:
1030+
module_name = strpath
1031+
strpath = pyarg_strpath
10241032
fspath = invocation_path / strpath
10251033
fspath = absolutepath(fspath)
10261034
if not safe_exists(fspath):
@@ -1040,4 +1048,5 @@ def resolve_collection_argument(
10401048
return CollectionArgument(
10411049
path=fspath,
10421050
parts=parts,
1051+
module_name=module_name,
10431052
)

testing/test_main.py

+11
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,28 @@ def test_file(self, invocation_path: Path) -> None:
139139
) == CollectionArgument(
140140
path=invocation_path / "src/pkg/test.py",
141141
parts=[],
142+
module_name=None,
142143
)
143144
assert resolve_collection_argument(
144145
invocation_path, "src/pkg/test.py::"
145146
) == CollectionArgument(
146147
path=invocation_path / "src/pkg/test.py",
147148
parts=[""],
149+
module_name=None,
148150
)
149151
assert resolve_collection_argument(
150152
invocation_path, "src/pkg/test.py::foo::bar"
151153
) == CollectionArgument(
152154
path=invocation_path / "src/pkg/test.py",
153155
parts=["foo", "bar"],
156+
module_name=None,
154157
)
155158
assert resolve_collection_argument(
156159
invocation_path, "src/pkg/test.py::foo::bar::"
157160
) == CollectionArgument(
158161
path=invocation_path / "src/pkg/test.py",
159162
parts=["foo", "bar", ""],
163+
module_name=None,
160164
)
161165

162166
def test_dir(self, invocation_path: Path) -> None:
@@ -166,6 +170,7 @@ def test_dir(self, invocation_path: Path) -> None:
166170
) == CollectionArgument(
167171
path=invocation_path / "src/pkg",
168172
parts=[],
173+
module_name=None,
169174
)
170175

171176
with pytest.raises(
@@ -185,18 +190,21 @@ def test_pypath(self, invocation_path: Path) -> None:
185190
) == CollectionArgument(
186191
path=invocation_path / "src/pkg/test.py",
187192
parts=[],
193+
module_name="pkg.test",
188194
)
189195
assert resolve_collection_argument(
190196
invocation_path, "pkg.test::foo::bar", as_pypath=True
191197
) == CollectionArgument(
192198
path=invocation_path / "src/pkg/test.py",
193199
parts=["foo", "bar"],
200+
module_name="pkg.test",
194201
)
195202
assert resolve_collection_argument(
196203
invocation_path, "pkg", as_pypath=True
197204
) == CollectionArgument(
198205
path=invocation_path / "src/pkg",
199206
parts=[],
207+
module_name="pkg",
200208
)
201209

202210
with pytest.raises(
@@ -212,6 +220,7 @@ def test_parametrized_name_with_colons(self, invocation_path: Path) -> None:
212220
) == CollectionArgument(
213221
path=invocation_path / "src/pkg/test.py",
214222
parts=["test[a::b]"],
223+
module_name=None,
215224
)
216225

217226
def test_does_not_exist(self, invocation_path: Path) -> None:
@@ -237,6 +246,7 @@ def test_absolute_paths_are_resolved_correctly(self, invocation_path: Path) -> N
237246
) == CollectionArgument(
238247
path=Path(os.path.abspath("src")),
239248
parts=[],
249+
module_name=None,
240250
)
241251

242252
# ensure full paths given in the command-line without the drive letter resolve
@@ -247,6 +257,7 @@ def test_absolute_paths_are_resolved_correctly(self, invocation_path: Path) -> N
247257
) == CollectionArgument(
248258
path=Path(os.path.abspath("src")),
249259
parts=[],
260+
module_name=None,
250261
)
251262

252263

0 commit comments

Comments
 (0)