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 name parameter to PluginManager.load_setuptools_entrypoints #189

Merged
merged 2 commits into from Feb 21, 2019

Conversation

nicoddemus
Copy link
Member

@RonnyPfannschmidt
Copy link
Member

im wondering if we ought to consider the loading/naming of plugins for a own object that manages it
this would allow to expand further into having auto-loading plugins vs requestable but named plugin

it could also enable reordering by request before autoloading

@nicoddemus
Copy link
Member Author

@RonnyPfannschmidt can you elaborate a little more what you mean? I can kind of guess what you mean, but would like to avoid having to guess and get the gist directly instead. 😉

Also I assume the topic you're bringing up is for another PR, not something to be done in this one. 👍

@RonnyPfannschmidt
Copy link
Member

yes, this is actually better put up as a followup,

the key idea is to encapsulate plugin naming and loading in a way that enables not just affecting the order of entry-point loading, but also enables to create entry-points for opt-in plugins

also it would enable to abstract the loader backend, after all, @asottile demonstrated in pre-commit that the entry-points package can shave quite some time off startup, and thats something we want to have for consumers of pluggy, in particular consumers like pytest and tox, where shaving off might safe users quite a while of time

same goes for deeper control of what plugins to load from where

@asottile
Copy link
Member

asottile commented Feb 8, 2019

for completeness, here's where I replaced pkg_resources with entrypoints for flake8 resulting in a 26.6% startup savings: https://gitlab.com/pycqa/flake8/merge_requests/264#note_118110874

@nicoddemus
Copy link
Member Author

Ready for review!

Once this gets merged, I plan to release 0.9 with this in order to finish pytest-dev/pytest#4727. 👍

@nicoddemus nicoddemus changed the title WIP: Add name parameter to PluginManager.load_setuptools_entrypoints Add name parameter to PluginManager.load_setuptools_entrypoints Feb 8, 2019
from pkg_resources import (
iter_entry_points,
DistributionNotFound,
VersionConflict,
)

for ep in iter_entry_points(entrypoint_name):
count = 0
for ep in iter_entry_points(group, name=name):
Copy link
Contributor

Choose a reason for hiding this comment

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

for count, ep in enumerate(iter_entry_points(group, name=name)): maybe a little cleaner?

Copy link
Member

Choose a reason for hiding this comment

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

it would be wrong ^^ - see the continue cases

Copy link
Contributor

Choose a reason for hiding this comment

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

a good call. missed that cause of the stacked diff 😖

Copy link
Contributor

@goodboy goodboy left a comment

Choose a reason for hiding this comment

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

@nicoddemus one little comment but looks good.

@asottile
Copy link
Member

this might make #190 more difficult to implement 🤔

@nicoddemus nicoddemus merged commit 3c384dd into pytest-dev:master Feb 21, 2019
@nicoddemus nicoddemus deleted the early-load-4718 branch February 21, 2019 22:20
@nicoddemus
Copy link
Member Author

this might make #190 more difficult to implement

Shouldn't really, should be a matter of just adapting the iteration to return only the entry points requested. See the original implementation:

https://github.com/pypa/pkg_resources/blob/6f81a44010d1266494025647dd1e1f0befa5b26b/pkg_resources/__init__.py#L743

@asottile
Copy link
Member

this might make #190 more difficult to implement

Shouldn't really, should be a matter of just adapting the iteration to return only the entry points requested. See the original implementation:

https://github.com/pypa/pkg_resources/blob/6f81a44010d1266494025647dd1e1f0befa5b26b/pkg_resources/__init__.py#L743

importlib_metadata doesn't currently have an api for that as far as I know :S - I can copy the implementation of their current api and stick an if in the inner loop but it might not be pretty :(

@nicoddemus
Copy link
Member Author

It is just a matter of skipping the entry points with that name. The current code is:

pluggy/pluggy/manager.py

Lines 269 to 272 in 3c384dd

for ep in iter_entry_points(group, name=name):
# is the plugin registered or blocked?
if self.get_plugin(ep.name) or self.is_blocked(ep.name):
continue

Unless I'm missing something, based on #190, we would need to change it to:

        for ep in importlib_metadata.entry_points().get(entrypoint_name, ()):
            # only get entry points with the given name
            if name is not None and ep.name != name:
                continue
            # is the plugin registered or blocked?
            if self.get_plugin(ep.name) or self.is_blocked(ep.name):
                continue

@asottile
Copy link
Member

ah yeah the difference there is that does a full scan of site-packages per call

@nicoddemus
Copy link
Member Author

nicoddemus commented Feb 21, 2019

You mean iter_entry_points doesn't? I didn't look too deep, but the implementation doesn't seem to do anything to avoid doing a full scan:

    def iter_entry_points(self, group, name=None):
        """Yield entry point objects from `group` matching `name`
        If `name` is None, yields all entry points in `group` from all
        distributions in the working set, otherwise only ones matching
        both `group` and `name` are yielded (in distribution order).
        """
        for dist in self:
            entries = dist.get_entry_map(group)
            if name is None:
                for ep in entries.values():
                    yield ep
            elif name in entries:
                yield entries[name]

Anyway even if it does a full-scan, it is not a big-deal for pytest's case because the name parameter is only given for each -p call given in the command-line, which I suspect will be only 1 or 2, tops.

@asottile
Copy link
Member

pkg_resources builds the set as an import side-effect (most of the rationale for why it is slow and why we want to eliminate it) -- the apis are then just an iteration over the in-memory mappings

@nicoddemus
Copy link
Member Author

Oh OK, thanks for the explanation!

It is not clear to me yet why this change would make it harder for us to land importlib_metadata later though... 🤔

@asottile
Copy link
Member

we'll see, I'll do some profiling once importlib-metadata 0.9 gets released 🙃

@nicoddemus
Copy link
Member Author

Oh you mean there might be a performance issue? Sorry, I thought it wouldn't be possible, that's why I was curious.

Hmm I'm just seeing that the name parameter has been removed in https://gitlab.com/python-devs/importlib_metadata/merge_requests/39... that's the reason of your unease about this change? Perhaps we can contribute implementing it?

@asottile
Copy link
Member

I suspect the answer might be building a global cache inside pluggy, but I'll wait until the release happens to poke around -- nothing urgent I think

@nicoddemus
Copy link
Member Author

I suspect the answer might be building a global cache inside pluggy, but I'll wait until the release happens to poke around -- nothing urgent I think

Sure thing

bors bot added a commit to mozilla/normandy that referenced this pull request Feb 26, 2019
1760: Scheduled weekly dependency update for week 08 r=peterbe a=pyup-bot






### Update [botocore](https://pypi.org/project/botocore) from **1.12.96** to **1.12.101**.


<details>
  <summary>Changelog</summary>
  
  
   ### 1.12.101
   ```
   ========

* api-change:``athena``: Update athena client to latest version
* api-change:``glue``: Update glue client to latest version
* api-change:``stepfunctions``: Update stepfunctions client to latest version
* api-change:``cloud9``: Update cloud9 client to latest version
   ```
   
  
  
   ### 1.12.100
   ```
   ========

* api-change:``kinesis-video-archived-media``: Update kinesis-video-archived-media client to latest version
* api-change:``workdocs``: Update workdocs client to latest version
* api-change:``codebuild``: Update codebuild client to latest version
* api-change:``cloudwatch``: Update cloudwatch client to latest version
* api-change:``organizations``: Update organizations client to latest version
* api-change:``kinesisvideo``: Update kinesisvideo client to latest version
* api-change:``kinesis-video-media``: Update kinesis-video-media client to latest version
* api-change:``transfer``: Update transfer client to latest version
   ```
   
  
  
   ### 1.12.99
   ```
   =======

* api-change:``codecommit``: Update codecommit client to latest version
* api-change:``directconnect``: Update directconnect client to latest version
* api-change:``medialive``: Update medialive client to latest version
   ```
   
  
  
   ### 1.12.98
   ```
   =======

* api-change:``iot``: Update iot client to latest version
* api-change:``ssm``: Update ssm client to latest version
* api-change:``ds``: Update ds client to latest version
* enhancement:Paginator: Add additional paginators for CloudFormation
* api-change:``efs``: Update efs client to latest version
   ```
   
  
  
   ### 1.12.97
   ```
   =======

* api-change:``athena``: Update athena client to latest version
* api-change:``secretsmanager``: Update secretsmanager client to latest version
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/botocore
  - Changelog: https://pyup.io/changelogs/botocore/
  - Repo: https://github.com/boto/botocore
</details>





### Update [jmespath](https://pypi.org/project/jmespath) from **0.9.3** to **0.9.4**.


<details>
  <summary>Changelog</summary>
  
  
   ### 0.9.4
   ```
   =====

* Fix ``min_by``/``max_by`` with empty lists
  `(`issue 151 &lt;https://github.com/jmespath/jmespath.py/pull/151&gt;`__)
* Fix reverse type for ``null`` type
  (`issue 145 &lt;https://github.com/jmespath/jmespath.py/pull/145&gt;`__)
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/jmespath
  - Changelog: https://pyup.io/changelogs/jmespath/
  - Repo: https://github.com/jmespath/jmespath.py
</details>





### Update [MarkupSafe](https://pypi.org/project/MarkupSafe) from **1.1.0** to **1.1.1**.


*The bot wasn't able to find a changelog for this release. [Got an idea?](https://github.com/pyupio/changelogs/issues/new)*

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/markupsafe
  - Changelog: https://pyup.io/changelogs/markupsafe/
  - Homepage: https://palletsprojects.com/p/markupsafe/
</details>





### Update [pluggy](https://pypi.org/project/pluggy) from **0.8.1** to **0.9.0**.


<details>
  <summary>Changelog</summary>
  
  
   ### 0.9.0
   ```
   =========================

Features
--------

- `189 &lt;https://github.com/pytest-dev/pluggy/issues/189&gt;`_: ``PluginManager.load_setuptools_entrypoints`` now accepts a ``name`` parameter that when given will
  load only entry points with that name.

  ``PluginManager.load_setuptools_entrypoints`` also now returns the number of plugins loaded by the
  call, as opposed to the number of all plugins loaded by all calls to this method.



Bug Fixes
---------

- `187 &lt;https://github.com/pytest-dev/pluggy/issues/187&gt;`_: Fix internal ``varnames`` function for PyPy3.
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/pluggy
  - Changelog: https://pyup.io/changelogs/pluggy/
  - Repo: https://github.com/pytest-dev/pluggy
</details>





### Update [py](https://pypi.org/project/py) from **1.7.0** to **1.8.0**.


<details>
  <summary>Changelog</summary>
  
  
   ### 1.8.0
   ```
   ==================

- add ``&quot;importlib&quot;`` pyimport mode for python3.5+, allowing unimportable test suites
  to contain identically named modules.

- fix ``LocalPath.as_cwd()`` not calling ``os.chdir()`` with ``None``, when
  being invoked from a non-existing directory.
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/py
  - Changelog: https://pyup.io/changelogs/py/
  - Docs: http://py.readthedocs.io/
</details>





### Update [google-auth](https://pypi.org/project/google-auth) from **1.6.2** to **1.6.3**.


<details>
  <summary>Changelog</summary>
  
  
   ### 1.6.3
   ```
   ------

02-15-2019 9:31 PST

Implementation Changes
+++++++++++++

- follow rfc 7515 : strip padding from JWS segments 324 (`324 &lt;https://github.com/googleapis/google-auth-library-python/pull/324&gt;`_)
- Add retry to _metadata.ping() (`323 &lt;https://github.com/googleapis/google-auth-library-python/pull/323&gt;`_)
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/google-auth
  - Changelog: https://pyup.io/changelogs/google-auth/
  - Repo: https://github.com/GoogleCloudPlatform/google-auth-library-python
</details>





### Update [boto3](https://pypi.org/project/boto3) from **1.9.96** to **1.9.101**.


<details>
  <summary>Changelog</summary>
  
  
   ### 1.9.101
   ```
   =======

* api-change:``athena``: [``botocore``] Update athena client to latest version
* api-change:``glue``: [``botocore``] Update glue client to latest version
* api-change:``stepfunctions``: [``botocore``] Update stepfunctions client to latest version
* api-change:``cloud9``: [``botocore``] Update cloud9 client to latest version
   ```
   
  
  
   ### 1.9.100
   ```
   =======

* api-change:``kinesis-video-archived-media``: [``botocore``] Update kinesis-video-archived-media client to latest version
* api-change:``workdocs``: [``botocore``] Update workdocs client to latest version
* api-change:``codebuild``: [``botocore``] Update codebuild client to latest version
* api-change:``cloudwatch``: [``botocore``] Update cloudwatch client to latest version
* api-change:``organizations``: [``botocore``] Update organizations client to latest version
* api-change:``kinesisvideo``: [``botocore``] Update kinesisvideo client to latest version
* api-change:``kinesis-video-media``: [``botocore``] Update kinesis-video-media client to latest version
* api-change:``transfer``: [``botocore``] Update transfer client to latest version
   ```
   
  
  
   ### 1.9.99
   ```
   ======

* api-change:``codecommit``: [``botocore``] Update codecommit client to latest version
* api-change:``directconnect``: [``botocore``] Update directconnect client to latest version
* api-change:``medialive``: [``botocore``] Update medialive client to latest version
   ```
   
  
  
   ### 1.9.98
   ```
   ======

* api-change:``iot``: [``botocore``] Update iot client to latest version
* api-change:``ssm``: [``botocore``] Update ssm client to latest version
* api-change:``ds``: [``botocore``] Update ds client to latest version
* enhancement:Paginator: [``botocore``] Add additional paginators for CloudFormation
* api-change:``efs``: [``botocore``] Update efs client to latest version
   ```
   
  
  
   ### 1.9.97
   ```
   ======

* api-change:``athena``: [``botocore``] Update athena client to latest version
* api-change:``secretsmanager``: [``botocore``] Update secretsmanager client to latest version
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/boto3
  - Changelog: https://pyup.io/changelogs/boto3/
  - Repo: https://github.com/boto/boto3
</details>





### Update [flake8](https://pypi.org/project/flake8) from **3.7.5** to **3.7.7**.


<details>
  <summary>Changelog</summary>
  
  
   ### 3.7.7
   ```
   -------------------

You can view the `3.7.7 milestone`_ on GitLab for more details.

Bugs Fixed
~~~~~~~~~~

- Fix crahes in plugins causing ``flake8`` to hang while unpickling errors (See
  also `GitLab!308`_, `GitLab505`_)


.. all links
.. _3.7.7 milestone:
    https://gitlab.com/pycqa/flake8/milestones/30

.. issue links
.. _GitLab505:
    https://gitlab.com/pycqa/flake8/issues/505

.. merge request links
.. _GitLab!308:
    https://gitlab.com/pycqa/flake8/merge_requests/308
   ```
   
  
  
   ### 3.7.6
   ```
   -------------------

You can view the `3.7.6 milestone`_ on GitLab for more details.

Bugs Fixed
~~~~~~~~~~

- Fix ``--per-file-ignores`` for multi-letter error codes (See also
  `GitLab!303`_, `GitLab507`_)

- Improve flake8 speed when only 1 filename is passed (See also `GitLab!305`_)


.. all links
.. _3.7.6 milestone:
    https://gitlab.com/pycqa/flake8/milestones/29

.. issue links
.. _GitLab507:
    https://gitlab.com/pycqa/flake8/issues/507

.. merge request links
.. _GitLab!303:
    https://gitlab.com/pycqa/flake8/merge_requests/303
.. _GitLab!305:
    https://gitlab.com/pycqa/flake8/merge_requests/305
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/flake8
  - Changelog: https://pyup.io/changelogs/flake8/
  - Repo: https://gitlab.com/pycqa/flake8
</details>





### Update [jsonschema](https://pypi.org/project/jsonschema) from **2.6.0** to **3.0.0**.


<details>
  <summary>Changelog</summary>
  
  
   ### 3.0.0
   ```
   ------

* Support for Draft 6 and Draft 7
* Draft 7 is now the default
* New ``TypeChecker`` object for more complex type definitions (and overrides)
* Falling back to isodate for the date-time format checker is no longer
  attempted, in accordance with the specification
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/jsonschema
  - Changelog: https://pyup.io/changelogs/jsonschema/
  - Repo: https://github.com/Julian/jsonschema
</details>





### Update [pytest](https://pypi.org/project/pytest) from **4.2.1** to **4.3.0**.


<details>
  <summary>Changelog</summary>
  
  
   ### 4.3.0
   ```
   =========================

Deprecations
------------

- `4724 &lt;https://github.com/pytest-dev/pytest/issues/4724&gt;`_: ``pytest.warns()`` now emits a warning when it receives unknown keyword arguments.

  This will be changed into an error in the future.



Features
--------

- `2753 &lt;https://github.com/pytest-dev/pytest/issues/2753&gt;`_: Usage errors from argparse are mapped to pytest&#39;s ``UsageError``.


- `3711 &lt;https://github.com/pytest-dev/pytest/issues/3711&gt;`_: Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards.
  Add the ``collect_ignore_glob`` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards.


- `4698 &lt;https://github.com/pytest-dev/pytest/issues/4698&gt;`_: The warning about Python 2.7 and 3.4 not being supported in pytest 5.0 has been removed.

  In the end it was considered to be more
  of a nuisance than actual utility and users of those Python versions shouldn&#39;t have problems as ``pip`` will not
  install pytest 5.0 on those interpreters.


- `4707 &lt;https://github.com/pytest-dev/pytest/issues/4707&gt;`_: With the help of new ``set_log_path()`` method there is a way to set ``log_file`` paths from hooks.



Bug Fixes
---------

- `4651 &lt;https://github.com/pytest-dev/pytest/issues/4651&gt;`_: ``--help`` and ``--version`` are handled with ``UsageError``.


- `4782 &lt;https://github.com/pytest-dev/pytest/issues/4782&gt;`_: Fix ``AssertionError`` with collection of broken symlinks with packages.
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/pytest
  - Changelog: https://pyup.io/changelogs/pytest/
  - Homepage: https://docs.pytest.org/en/latest/
</details>







Co-authored-by: pyup-bot <github-bot@pyup.io>
Co-authored-by: Mike Cooper <mythmon@gmail.com>
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.

None yet

4 participants