Skip to content
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

Detect and warn/ignore local python installations #2566

Merged
merged 5 commits into from Jul 13, 2017
Merged

Detect and warn/ignore local python installations #2566

merged 5 commits into from Jul 13, 2017

Conversation

ghost
Copy link

@ghost ghost commented Jul 11, 2017

This should address / close ticket #2518. The behaviour implemented is as follows:

  1. During collection, if pytest detects that the directory it is considering is sys.prefix, the directory and any tests it contains will be ignored and a helpful warning will be issued.
  2. If --collect-in-virtualenv (a new CLI flag) is passed, pytest will collect anyways.
  3. If the relevant path is explicitly ignored; i.e. --ignore=./.env or what have you, the warning is silenced.

I tried to write a test but couldn't quite figure out how to effectively mock sys.prefix; I'd appreciate some help there. Other feedback is also totally welcome.

@ghost ghost changed the title Iss2518 Detect and warn/ignore local python installations Jul 11, 2017
@RonnyPfannschmidt
Copy link
Member

hi @jmsdvl - first thanks for this piece of work, while it makes the situation better, its however not addressing #2518 since it does not detect virtualenvs and instead takes a look at the current virtualenv only

second there should be a way to unittest however it seems rather tricky with the current infrastucture - i#ll try to take a deeper look this week

@ghost
Copy link
Author

ghost commented Jul 11, 2017

@RonnyPfannschmidt is there a bulletproof way to detect a virtualenv that isn't active? I guess I could just have the code sniff around the directory structure looking for the python executable and / or a site-packages directory. Might get expensive if its run in pytest_ignore_collect though. I just wanna help out and learn your codebase ;)

@RonnyPfannschmidt
Copy link
Member

@jmsdvl i would propose to check for the platform specific virtualenv activation scripts, so it would be one check per directory

@nicoddemus any oppinion?

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 91.876% when pulling c2d49e3 on jmsdvl:iss2518 into d9aaab7 on pytest-dev:features.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 91.876% when pulling 676c4f9 on jmsdvl:iss2518 into d9aaab7 on pytest-dev:features.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 91.859% when pulling b32cfc8 on jmsdvl:iss2518 into d9aaab7 on pytest-dev:features.

@nicoddemus
Copy link
Member

i would propose to check for the platform specific virtualenv activation scripts,

Sounds like a good idea to me. 👍

Is there legitimate cases you guys can think of for searching for tests inside a virtual environment?

@ghost
Copy link
Author

ghost commented Jul 11, 2017

Is there legitimate cases you guys can think of for searching for tests inside a virtual environment?

@nicoddemus not really, unless you're working on the virtual environment itself or tools that heavily interact with it. But then that's why there's a CLI override option.

I implemented the check for a relevant activate script. If that, by whatever slim chance, gives false positives, it would be fairly trivial to add an extra check for another file indicative of a virtual env (say, a python binary) in the same directory as the activate script.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome @jmsdvl, thanks a ton for the PR.

@@ -0,0 +1 @@
Collection ignores the currently active Python installation by default; `--collect-in-virtualenv` overrides this behavior.
Copy link
Member

@nicoddemus nicoddemus Jul 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the note to mention that now we detect virtual environments.

@@ -0,0 +1 @@
Collection ignores the currently active Python installation by default; `--collect-in-virtualenv` overrides this behavior.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I suggest we add a blurb next to norecursedirs explaining that by default pytest will also skip any virtual environments, detected by their activation script, and that can be bypassed with --collect-in-virtualenv.

@@ -70,6 +70,8 @@ def pytest_addoption(parser):
group.addoption('--keepduplicates', '--keep-duplicates', action="store_true",
dest="keepduplicates", default=False,
help="Keep duplicate tests.")
group.addoption('--collect-in-virtualenv', action='store_true',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a default=False here to be explicit, otherwise I believe the default is None.

@@ -167,6 +169,17 @@ def pytest_runtestloop(session):
return True


def _in_venv(path):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice going making this a separate function. I suggest we unittest it directly by creating directories with fake activation scripts and calling it accordingly; we want to exercise it on CI to avoid someone touching it and breaking it by accident.

@@ -177,6 +190,15 @@ def pytest_ignore_collect(path, config):
if py.path.local(path) in ignore_paths:
return True

allow_in_venv = config.getoption("collect_in_virtualenv")
if _in_venv(path) and not allow_in_venv:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should emit this warning; the common case is for users to have some virtual environment locally, so we would generate needless warnings all the time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to make this check only if the user did not explicitly passed the path into the command line, like what we do to while collecting python test files in python.py.

IOW, pytest .env should collect everything under .env even if .env is a virtual environment directory.

@nicoddemus
Copy link
Member

nicoddemus commented Jul 12, 2017

But then that's why there's a CLI override option.

Oh sorry I did not look at the code until now. Just playing devil's advocate there. 😁

@nicoddemus
Copy link
Member

Btw,

I just wanna help out and learn your codebase ;)

Awesome, we can always use more help. Feel free to dig around, triage issues and participate on PR reviews. 👍

@ghost
Copy link
Author

ghost commented Jul 12, 2017

Requested changes, from the top:

  • note has been updated
  • docs are updated with a blurb next to norecursedirs
  • default and dest arguments added
  • there are tests for _in_venv directly and for pytest's overall behavior, including the --collect-in-virtualenv flag and its precedence (see overall behavior below)
  • the warning is removed
  • there's no need to check if the virtualenv was passed in explicitly; the whole hook is only called if it wasn't

So the overall behavior at this point is that

  1. If a directory has an activation script in a bin directory we ignore it, unless
  2. the user passes --collect-in-virtualenv on the CLI, unless
  3. the directory name matches a pattern in norecursedirs (i.e. .env won't get picked up regardless of --collect-in-virtualenv because it matches .* in norecursedirs), unless
  4. the path was given explicitly on the command line, in which case it is never ignored.

And its all tested and in the docs. 💥

@coveralls
Copy link

Coverage Status

Coverage increased (+0.009%) to 91.901% when pulling 67fca04 on jmsdvl:iss2518 into d9aaab7 on pytest-dev:features.

@nicoddemus
Copy link
Member

Great, thanks a lot! 🙌

@RonnyPfannschmidt RonnyPfannschmidt merged commit 1485a3a into pytest-dev:features Jul 13, 2017
@ghost ghost deleted the iss2518 branch July 13, 2017 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants