Skip to content

Commit a76bc64

Browse files
authored
Merge pull request #6547 from bluetech/session-initialparts
Refactor Session._initialparts to have a more explicit type
2 parents 498884a + dd5c2b2 commit a76bc64

File tree

2 files changed

+26
-28
lines changed

2 files changed

+26
-28
lines changed

src/_pytest/main.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from typing import Dict
99
from typing import FrozenSet
1010
from typing import List
11+
from typing import Tuple
1112

1213
import attr
1314
import py
@@ -486,13 +487,13 @@ def _perform_collect(self, args, genitems):
486487
self.trace("perform_collect", self, args)
487488
self.trace.root.indent += 1
488489
self._notfound = []
489-
initialpaths = []
490-
self._initialparts = []
490+
initialpaths = [] # type: List[py.path.local]
491+
self._initial_parts = [] # type: List[Tuple[py.path.local, List[str]]]
491492
self.items = items = []
492493
for arg in args:
493-
parts = self._parsearg(arg)
494-
self._initialparts.append(parts)
495-
initialpaths.append(parts[0])
494+
fspath, parts = self._parsearg(arg)
495+
self._initial_parts.append((fspath, parts))
496+
initialpaths.append(fspath)
496497
self._initialpaths = frozenset(initialpaths)
497498
rep = collect_one_node(self)
498499
self.ihook.pytest_collectreport(report=rep)
@@ -512,13 +513,13 @@ def _perform_collect(self, args, genitems):
512513
return items
513514

514515
def collect(self):
515-
for initialpart in self._initialparts:
516-
self.trace("processing argument", initialpart)
516+
for fspath, parts in self._initial_parts:
517+
self.trace("processing argument", (fspath, parts))
517518
self.trace.root.indent += 1
518519
try:
519-
yield from self._collect(initialpart)
520+
yield from self._collect(fspath, parts)
520521
except NoMatch:
521-
report_arg = "::".join(map(str, initialpart))
522+
report_arg = "::".join((str(fspath), *parts))
522523
# we are inside a make_report hook so
523524
# we cannot directly pass through the exception
524525
self._notfound.append((report_arg, sys.exc_info()[1]))
@@ -527,12 +528,9 @@ def collect(self):
527528
self._collection_node_cache.clear()
528529
self._collection_pkg_roots.clear()
529530

530-
def _collect(self, arg):
531+
def _collect(self, argpath, names):
531532
from _pytest.python import Package
532533

533-
names = arg[:]
534-
argpath = names.pop(0)
535-
536534
# Start with a Session root, and delve to argpath item (dir or file)
537535
# and stack all Packages found on the way.
538536
# No point in finding packages when collecting doctests
@@ -556,7 +554,7 @@ def _collect(self, arg):
556554
# If it's a directory argument, recurse and look for any Subpackages.
557555
# Let the Package collector deal with subnodes, don't collect here.
558556
if argpath.check(dir=1):
559-
assert not names, "invalid arg {!r}".format(arg)
557+
assert not names, "invalid arg {!r}".format((argpath, names))
560558

561559
seen_dirs = set()
562560
for path in argpath.visit(
@@ -666,19 +664,19 @@ def _tryconvertpyarg(self, x):
666664

667665
def _parsearg(self, arg):
668666
""" return (fspath, names) tuple after checking the file exists. """
669-
parts = str(arg).split("::")
667+
strpath, *parts = str(arg).split("::")
670668
if self.config.option.pyargs:
671-
parts[0] = self._tryconvertpyarg(parts[0])
672-
relpath = parts[0].replace("/", os.sep)
673-
path = self.config.invocation_dir.join(relpath, abs=True)
674-
if not path.check():
669+
strpath = self._tryconvertpyarg(strpath)
670+
relpath = strpath.replace("/", os.sep)
671+
fspath = self.config.invocation_dir.join(relpath, abs=True)
672+
if not fspath.check():
675673
if self.config.option.pyargs:
676674
raise UsageError(
677675
"file or package not found: " + arg + " (missing __init__.py?)"
678676
)
679677
raise UsageError("file not found: " + arg)
680-
parts[0] = path.realpath()
681-
return parts
678+
fspath = fspath.realpath()
679+
return (fspath, parts)
682680

683681
def matchnodes(self, matching, names):
684682
self.trace("matchnodes", matching, names)

testing/test_collection.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ def pytest_collect_file(path, parent):
438438

439439

440440
class TestSession:
441-
def test_parsearg(self, testdir):
441+
def test_parsearg(self, testdir) -> None:
442442
p = testdir.makepyfile("def test_func(): pass")
443443
subdir = testdir.mkdir("sub")
444444
subdir.ensure("__init__.py")
@@ -448,14 +448,14 @@ def test_parsearg(self, testdir):
448448
config = testdir.parseconfig(p.basename)
449449
rcol = Session.from_config(config)
450450
assert rcol.fspath == subdir
451-
parts = rcol._parsearg(p.basename)
451+
fspath, parts = rcol._parsearg(p.basename)
452452

453-
assert parts[0] == target
453+
assert fspath == target
454+
assert len(parts) == 0
455+
fspath, parts = rcol._parsearg(p.basename + "::test_func")
456+
assert fspath == target
457+
assert parts[0] == "test_func"
454458
assert len(parts) == 1
455-
parts = rcol._parsearg(p.basename + "::test_func")
456-
assert parts[0] == target
457-
assert parts[1] == "test_func"
458-
assert len(parts) == 2
459459

460460
def test_collect_topdir(self, testdir):
461461
p = testdir.makepyfile("def test_func(): pass")

0 commit comments

Comments
 (0)