-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditionally ignore collection of setuptools dirnames #12918
base: main
Are you sure you want to change the base?
Conversation
4f259e0
to
2ecca4e
Compare
src/_pytest/main.py
Outdated
@@ -423,6 +430,10 @@ def pytest_ignore_collect(collection_path: Path, config: Config) -> bool | None: | |||
if any(fnmatch_ex(pat, collection_path) for pat in norecursepatterns): | |||
return True | |||
|
|||
if any(fnmatch_ex(pat, collection_path) for pat in ("build", "dist")): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be wrapped by a "allow_in_setuptools" like they do for a venv?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't understand this reference at first. But now I realize that this is what I've been thinking of when I wrote another comment @ #12918 (comment). So I'd say yes. This would improve the maintainability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have rewritten this in light of what I understood from our conversation, please let me know if this is the direction we want to go in
src/_pytest/main.py
Outdated
indicators = ("setup.py", "setup.cfg", "pyproject.toml") | ||
return any((path / f).exists() for f in indicators) | ||
indicators = ("setup.py", "setup.cfg") | ||
if any((path / f).exists() for f in indicators): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if any((path / f).exists() for f in indicators): | |
if any((path / f).is_file() for f in indicators): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -0,0 +1,2 @@ | |||
Conditionally ignore collection of setuptools artifacts dirnames only if the | |||
directories reside inside a setuptools project, i.e. `setup.cfg`, is present, etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, enumerate all the files taken into consideration in this logic. Change notes are targeting the end-users who would not be able to guess. It might also be a good idea to mention the same somewhere in the regular docs, additionally.
src/_pytest/main.py
Outdated
except tomllib.TOMLDecodeError as exc: | ||
raise UsageError(f"{toml_file}: {exc}") from exc | ||
|
||
result = config.get("build-system", {}).get("requires", {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend using a more verbose variable name, one that is not generic but corresponds to the data being assigned to it. This is because we should optimize for readability, since any code is read much more often than it's written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted, for now this code has been removed
src/_pytest/main.py
Outdated
@@ -423,6 +450,10 @@ def pytest_ignore_collect(collection_path: Path, config: Config) -> bool | None: | |||
if any(fnmatch_ex(pat, collection_path) for pat in norecursepatterns): | |||
return True | |||
|
|||
if any(fnmatch_ex(pat, collection_path) for pat in ("build", "dist")): | |||
if _is_setuptools_project(collection_path.parent): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case does not need a nested block. Instead, both conditions could be merged using and
. The line would be quite long, though, so it might be a good idea to assign that to a variable that would also be an opportunity to assign semantics to this check through naming the var with something that corresponds to the high-level purpose of the check.
For example, using is_distributable_library
would make that check if is_distributable_library:
, which is both short and communicates what the list of low-level checks mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tried an allow_in_build
approach, let me know what you think
4e4ef2e
to
71fc2ad
Compare
@@ -63,9 +63,7 @@ def pytest_addoption(parser: Parser) -> None: | |||
"*.egg", | |||
".*", | |||
"_darcs", | |||
"build", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the description string above should mention that these are still conditionally excluded by default.
@@ -367,6 +365,22 @@ def pytest_runtestloop(session: Session) -> bool: | |||
return True | |||
|
|||
|
|||
def _in_build(path: Path) -> bool: | |||
"""Attempt to detect if ``path`` is the root of a buildsystem's artifacts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like this isn't just an attempt but a complete piece of logic. So I'd just go with “Detect” since it seems more accurate.
"""Attempt to detect if ``path`` is the root of a buildsystem's artifacts | |
"""Detect if ``path`` is the root of a buildsystem's artifacts |
src/_pytest/main.py
Outdated
return False | ||
|
||
if any(fnmatch_ex(pat, path) for pat in ("build", "dist")): | ||
indicators = ("setup.py", "setup.cfg", "pyproject.toml") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is important of understand that setup.cfg
can be an indicator only in case pyproject.toml
with setuptools pointers exists, or setup.py
is present.
So the check would need to be more involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to verify my understanding of the logic required. I've re-written it and the tests to reflect how I currently understood the discussion here and in #12625, basically, we first need to see setup.cfg
, and then only if setup.py
or pyproject.toml
with appropriate setuptools pointers exist then we'll ignore collecting build
and dist
src/_pytest/main.py
Outdated
|
||
if any(fnmatch_ex(pat, path) for pat in ("build", "dist")): | ||
indicators = ("setup.py", "setup.cfg", "pyproject.toml") | ||
if any((path.parent / f).is_file() for f in indicators): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like this is cheaper than fnmatch. Could you try adding a “guard expression” and bailing early if none of these exist?
71fc2ad
to
232d614
Compare
6d9cb54
to
c8f095b
Compare
build_system = parsed_toml.get("build-system", {}).get("requires") | ||
if "setuptools" in build_system: | ||
return True | ||
except Exception: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to avoid using a except Exception
here unless absolute necessary -- from what I see on the code inside the try/except block, seems that we are taking in account missing keys already.
Did you account that tomlib.loads
might fail due to a malformed TOML file? If so let's catch the precise exception here instead.
@@ -418,6 +457,10 @@ def pytest_ignore_collect(collection_path: Path, config: Config) -> bool | None: | |||
if not allow_in_venv and _in_venv(collection_path): | |||
return True | |||
|
|||
allow_in_build = False # config.getoption("collect_in_build") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left over?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just so everyone is on the same page, marking the PR as "request changes" to make it clear there are a number of comments that need addressing.
Thanks again @sus-pe for the contribution. 👍
Fix #12625