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

Add new INI config key 'required_plugins' that defines a list of plugins that must be present for a run of pytest #7330

Merged
merged 12 commits into from
Jun 12, 2020

Conversation

gnikonorov
Copy link
Member

@gnikonorov gnikonorov commented Jun 6, 2020

closes #7305

Changes:

  • Introduce a new config key called require_plugins that is a space separated list of plugins required for pytest to run
  • Make the --strict-config flag ( added here treat these warnings as errors instead

@gnikonorov gnikonorov changed the title Issue 7305 Add new INI config key 'require_plugins' that defines a list of plugins that must be present for a run of pytest Jun 6, 2020
@gnikonorov
Copy link
Member Author

gnikonorov commented Jun 6, 2020

Hey @RonnyPfannschmidt - I think we have a flaky test for py36. What's the process for dealing with it? Looking at the logs I don't think it's related to my change

Also, I ran tox -e py36 locally on my machine ( I'm on an Ubuntu ), and all seemed to pass

(.venv) gnikonorov:pytest [issue_7305] $ cat /proc/version
Linux version 4.15.0-34-generic (buildd@lgw01-amd64-047) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #37-Ubuntu SMP Mon Aug 27 15:21:48 UTC 2018
(.venv) gnikonorov:pytest [issue_7305] $

@RonnyPfannschmidt
Copy link
Member

I retried the build

@gnikonorov
Copy link
Member Author

Thanks @RonnyPfannschmidt - looks like that fixed the build ( fingers crossed for no flaky tests in py37 )

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.

Hi @gnikonorov,

Thanks a lot for the contribution!

Everything looks good to me, left a couple of suggestions regarding documentation though. 👍

changelog/7305.feature.rst Outdated Show resolved Hide resolved
doc/en/reference.rst Outdated Show resolved Hide resolved
@gnikonorov
Copy link
Member Author

Thanks for the review, @nicoddemus! I updated the documentation like you suggested

@gnikonorov
Copy link
Member Author

Friendly ping for a merge @nicoddemus, @RonnyPfannschmidt. Or, should I merge myself now that I have the ability to and this has been approved?

@RonnyPfannschmidt
Copy link
Member

Sorry for the delay, I'm moving

@gnikonorov
Copy link
Member Author

No worries @RonnyPfannschmidt, hope your move goes smoothly. Looks like py36 is flaky on the same tests as last time

changelog/7305.feature.rst Outdated Show resolved Hide resolved
doc/en/reference.rst Outdated Show resolved Hide resolved
@gnikonorov
Copy link
Member Author

( should be ) good to merge now @nicoddemus

@gnikonorov
Copy link
Member Author

The failure seems to be the same unrelated flaky one from before. @RonnyPfannschmidt's re-run of the build 'fixed' it last time

@gnikonorov
Copy link
Member Author

Friendly bump for a test rerun and/or merge @nicoddemus

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.

Oh my, sorry, these last comments have been left "Pending" here in GitHub, my bad. 🙄

src/_pytest/config/__init__.py Outdated Show resolved Hide resolved
src/_pytest/config/__init__.py Outdated Show resolved Hide resolved
doc/en/reference.rst Outdated Show resolved Hide resolved
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.

As discussed:

  • Use dist-info instead of plugin/module name
  • Missing plugins should stop pytest immediately, showing all plugins which are not installed.
  • Change option to required_plugins

@gnikonorov
Copy link
Member Author

Thanks for the review and thoughtful feedback. Updated the PR @nicoddemus and @RonnyPfannschmidt

@gnikonorov gnikonorov changed the title Add new INI config key 'require_plugins' that defines a list of plugins that must be present for a run of pytest Add new INI config key 'required_plugins' that defines a list of plugins that must be present for a run of pytest Jun 10, 2020
@gnikonorov
Copy link
Member Author

#7346 made to track @RonnyPfannschmidt's suggestion of specifying version constraints

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.

Thanks a lot @gnikonorov!

I've left a few minor suggestions, otherwise LGTM! 👍

src/_pytest/config/__init__.py Outdated Show resolved Hide resolved
src/_pytest/config/__init__.py Outdated Show resolved Hide resolved
src/_pytest/config/__init__.py Outdated Show resolved Hide resolved
@gnikonorov
Copy link
Member Author

Thank you @nicoddemus! Looking forward to getting this in and starting on the followup task

changelog/7305.feature.rst Outdated Show resolved Hide resolved
doc/en/reference.rst Outdated Show resolved Hide resolved
Comment on lines +1094 to +1095
if not required_plugins:
return
Copy link
Member

Choose a reason for hiding this comment

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

I'd omit these two lines as they're not really necessary.

Suggested change
if not required_plugins:
return

Copy link
Member Author

Choose a reason for hiding this comment

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

This was intentional. The point is to not fetch plugin info if it’s not necessary. The function is useless if there are no required plugins, so we exit

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this optimization is worth it, the code below doesn't do anything expensive. I think it is better to avoid special cases when they are not necessary. But it's OK if you want to keep it.

Copy link
Member Author

Choose a reason for hiding this comment

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

The call to get dist info is expensive ( as per @nicoddemus’ earlier comment )

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I was under that impression, but I was wrong, sorry for not doing the proper research before.

Regardless I think the change is harmless and particularly I would prefer to bail out early. 😁

Copy link
Member Author

Choose a reason for hiding this comment

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

+1 on bailing early. It’s unnecessary otherwise. We’re not writing high frequency trading software but at the same time we should do basic optimizations

Copy link
Member

Choose a reason for hiding this comment

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

The main thing is that the condition makes it look like a Falsey required_plugins has a special meaning. If it is removed, the reader doesn't need to figure out that it doesn't.

But just in general, if I see e.g. sum implemented like this:

def sum(xs):
    if not xs:
        return 0
    s = 0
    for x in xs:
        s += x
    return s

that seems redundant...

Copy link
Member Author

@gnikonorov gnikonorov Jun 12, 2020

Choose a reason for hiding this comment

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

I mean, technically speaking a falsey required_plugins means to the function and the reader of the function "nothing important to do here now, just carry on"

In this case we also don't have to assemble plugin_dist_names plugin_dist_names = [dist.project_name for _, dist in plugin_info] which we still would if we don't bail early

Also, doing the None check informs future readers that this item is not guaranteed to be populated which isn’t obvious otherwise

if not required_plugins:
return

plugin_info = self.pluginmanager.list_plugin_distinfo()
Copy link
Member

Choose a reason for hiding this comment

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

Any particular reason to only include setuptools plugins here?

Copy link
Member Author

Choose a reason for hiding this comment

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

This isn’t just setup tools it is all plugins, but with the proper distribution info. Correct me if I’m wrong @nicoddemus

Copy link
Member Author

Choose a reason for hiding this comment

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

Resolving as above. Please reopen if I’m wrong

Copy link
Member

Choose a reason for hiding this comment

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

list_plugin_distinfo only lists setuptools plugins, at least this is what I understand from the pluggy code. That might be what we want here, not sure myself, but unresolving so can figure it out.

Copy link
Member

@nicoddemus nicoddemus Jun 12, 2020

Choose a reason for hiding this comment

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

Good point @bluetech.

Should we consider somehow plugins specified via -p and PYTEST_PLUGINS? How would that look like?

Copy link
Member Author

@gnikonorov gnikonorov Jun 12, 2020

Choose a reason for hiding this comment

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

Do we want to add support for -p and PYTEST_PLUGINS in a follow up PR or does that feel like we’re submitting a half complete feature @nicoddemus @bluetech ( asking since I'm not familiar with the usage of -p and PYTEST_PLUGINS

Copy link
Member

Choose a reason for hiding this comment

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

I haven't checked what each means, but just from perusing the PlugingManager code, list_name_plugin() seems good?

I guess it depends on why the code uses dist.project_name instead of the name the plugin was registered with? (Sorry if was discussed before)

Copy link
Member Author

Choose a reason for hiding this comment

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

This was discussed here: #7330 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

From reading the help, I think we should defer -p if we add it at all. It sounds like a user is intentionally fiddling around with the run

-p name               early-load given plugin module name or entry point
                            (multi-allowed).

The same goes for the environment variable PYTEST_PLUGINS. I'm not opposed to adding them in, but to me it really sounds like they're a different use case than this and would warrant their own PR

Copy link
Member

Choose a reason for hiding this comment

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

Agree, not sure this makes sense when used with -p or PYTEST_PLUGINS.

src/_pytest/config/__init__.py Show resolved Hide resolved
Co-authored-by: Ran Benita <ran@unusedvar.com>
@bluetech
Copy link
Member

Sorry for being extra nitpicky @gnikonorov :)

@gnikonorov
Copy link
Member Author

No need to be sorry at all! I appreciate the thoroughness, thank you!

@gnikonorov
Copy link
Member Author

Friendly ping to @RonnyPfannschmidt for a review

@gnikonorov
Copy link
Member Author

@nicoddemus and/or @bluetech if there are no more questions can we actually merge this into master? It’s blocking a few issues I want to start working on

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.

LGTM, let's wait for @bluetech and @RonnyPfannschmidt to take a final look before mergin. 👍

@gnikonorov
Copy link
Member Author

Thanks for the thoughtful reviews @nicoddemus and @bluetech
I’ll wait for @RonnyPfannschmidt

@nicoddemus nicoddemus merged commit aaa6f1c into pytest-dev:master Jun 12, 2020
@nicoddemus
Copy link
Member

Thanks @gnikonorov!

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.

Create new INI key that contains a list of required plugins
4 participants