Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pytest-dev/pluggy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.11.0
Choose a base ref
...
head repository: pytest-dev/pluggy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.12.0
Choose a head ref

Commits on May 7, 2019

  1. fixup release script

    asottile committed May 7, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    e28defc View commit details
  2. Merge pull request #208 from asottile/release-0.11.0

    Preparing release 0.11.0
    asottile authored May 7, 2019
    Copy the full SHA
    68c8a2e View commit details
  3. fixup release script (#207)

    fixup release script
    nicoddemus authored May 7, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    8e34a1f View commit details
  4. Move pluggy -> src

    nicoddemus committed May 7, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    b46ac5f View commit details
  5. Copy the full SHA
    c86cc29 View commit details

Commits on May 10, 2019

  1. Use src-layout (#203)

    Use src-layout
    nicoddemus authored May 10, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    f8af26c View commit details

Commits on May 13, 2019

  1. Convert hooks.varnames() to inspect.signature() on Python 3

    Avoids a possible deprecation warning with inspect.getfullargspec()
    
    Fixes #209
    hroncok committed May 13, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    ec28f02 View commit details

Commits on May 14, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    04ef193 View commit details
  2. Use --force-reinstall when installing tox

    As described in:
    
    tox-dev/tox#791
    nicoddemus committed May 14, 2019
    Copy the full SHA
    6504cb3 View commit details
  3. Use funcsigs on Python 2

    See #209
    hroncok committed May 14, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    62f28ac View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    68e56e5 View commit details
  5. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    0a7fec2 View commit details
  6. Check for funcsigs using sys.version_info

    Using this instead of catching an ImportError provides better
    messages when this happens in broken envirnments
    nicoddemus committed May 14, 2019
    Copy the full SHA
    2008a3d View commit details
  7. Add CHANGELOG for #209

    nicoddemus committed May 14, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    39c6247 View commit details
  8. Convert hooks.varnames() to inspect.signature() on Python 3 (#210)

    Convert hooks.varnames() to inspect.signature() on Python 3
    nicoddemus authored May 14, 2019
    Copy the full SHA
    f8108d7 View commit details

Commits on May 16, 2019

  1. Fix a regression with keyword only arguments

    Introduced in #210
    
    Note: In "normal" Python, exec exports the defined names,
    however in pytest, I needed to use globals.
    hroncok committed May 16, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    bebd024 View commit details
  2. Fix a regression with keyword only arguments (#213)

    Fix a regression with keyword only arguments
    nicoddemus authored May 16, 2019
    Copy the full SHA
    d4d45c9 View commit details

Commits on May 23, 2019

  1. Revert varnames() refactor to use inspect.Signature

    As discussed in #212
    
    This reverts commits:
    
    * bebd024
    * 39c6247
    * 2008a3d
    * 68e56e5
    * 62f28ac
    * ec28f02
    
    Closes #212
    nicoddemus committed May 23, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    4e728aa View commit details

Commits on May 25, 2019

  1. Merge pull request #214 from nicoddemus/revert-signature

    Revert varnames() refactor to use inspect.Signature
    asottile authored May 25, 2019
    Copy the full SHA
    7f8f8eb View commit details
  2. Revert "Merge pull request #206 from asottile/revert-199-importlib_me…

    …tadata_v2"
    
    This reverts commit 07f4434, reversing
    changes made to d7a9792.
    asottile committed May 25, 2019
    Copy the full SHA
    b0f3b6d View commit details

Commits on May 27, 2019

  1. Copy the full SHA
    94ab205 View commit details
  2. importlib-metadata again (#215)

    importlib-metadata again
    nicoddemus authored May 27, 2019
    Copy the full SHA
    69deb13 View commit details
  3. Preparing release 0.12.0

    asottile committed May 27, 2019
    Copy the full SHA
    a878c47 View commit details
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ target/
*.swp

# generated by setuptools_scm
pluggy/_version.py
src/pluggy/_version.py

# generated by pip
pip-wheel-metadata/
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -30,6 +30,8 @@ jobs:
env: TOXENV=pypy3-pytestrelease-coverage
- python: '3.7'
env: TOXENV=py37-pytestrelease-coverage
- python: '3.8-dev'
env: TOXENV=py38-pytestrelease-coverage
- python: '2.7'
env: TOXENV=py27-pytestmaster-coverage
- python: '2.7'
@@ -58,8 +60,8 @@ jobs:
repo: pytest-dev/pluggy

install:
- pip install -U setuptools pip
- pip install -U tox
- pip install -U pip
- pip install -U --force-reinstall setuptools tox

script:
- tox
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -4,6 +4,15 @@ Changelog

.. towncrier release notes start
pluggy 0.12.0 (2019-05-27)
==========================

Features
--------

- `#215 <https://github.com/pytest-dev/pluggy/issues/215>`_: Switch from ``pkg_resources`` to ``importlib-metadata`` for entrypoint detection for improved performance and import time. This time with ``.egg`` support.


pluggy 0.11.0 (2019-05-07)
==========================

3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -26,7 +26,8 @@ install:
- echo PyPy installed
- pypy --version

- C:\Python35\python -m pip install tox
- C:\Python35\python -m pip install -U pip
- C:\Python35\python -m pip install -U --force-reinstall setuptools tox

build: false # Not a C# project, build stuff at the test step instead.

9 changes: 4 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
import pkg_resources
import importlib_metadata


extensions = [
@@ -20,14 +20,13 @@

# General information about the project.

dist = pkg_resources.get_distribution("pluggy")
project = dist.project_name
project = "pluggy"
copyright = u"2016, Holger Krekel"
author = "Holger Krekel"

release = dist.version
release = importlib_metadata.version(project)
# The short X.Y version.
version = u".".join(dist.version.split(".")[:2])
version = u".".join(release.split(".")[:2])


language = None
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ requires = [

[tool.towncrier]
package = "pluggy"
package_dir = "pluggy"
package_dir = "src/pluggy"
filename = "CHANGELOG.rst"
directory = "changelog/"
title_format = "pluggy {version} ({project_date})"
4 changes: 2 additions & 2 deletions scripts/release.py
Original file line number Diff line number Diff line change
@@ -28,9 +28,9 @@ def get_upstream(repo: Repo) -> Remote:
"""Find upstream repository for pluggy on the remotes"""
for remote in repo.remotes:
for url in remote.urls:
if url.endswith("pytest-dev/pluggy.git"):
if url.endswith(("pytest-dev/pluggy.git", "pytest-dev/pluggy")):
return remote
raise RuntimeError("could not find tox-dev/tox.git remote")
raise RuntimeError("could not find pytest-dev/pluggy remote")


def pre_release(version):
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,8 @@
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
] + [
("Programming Language :: Python :: %s" % x) for x in "2 2.7 3 3.4 3.5 3.6".split()
("Programming Language :: Python :: %s" % x)
for x in "2 2.7 3 3.4 3.5 3.6 3.7 3.8".split()
]

with open("README.rst", "rb") as fd:
@@ -28,17 +29,19 @@ def main():
name="pluggy",
description="plugin and hook calling mechanisms for python",
long_description=long_description,
use_scm_version={"write_to": "pluggy/_version.py"},
use_scm_version={"write_to": "src/pluggy/_version.py"},
setup_requires=["setuptools-scm"],
license="MIT license",
platforms=["unix", "linux", "osx", "win32"],
author="Holger Krekel",
author_email="holger@merlinux.eu",
url="https://github.com/pytest-dev/pluggy",
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
install_requires=["importlib-metadata>=0.12"],
extras_require={"dev": ["pre-commit", "tox"]},
classifiers=classifiers,
packages=["pluggy"],
package_dir={"": "src"},
)


File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
53 changes: 32 additions & 21 deletions pluggy/manager.py → src/pluggy/manager.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@
from .hooks import HookImpl, _HookRelay, _HookCaller, normalize_hookimpl_opts
import warnings

import importlib_metadata


def _warn_for_function(warning, function):
warnings.warn_explicit(
@@ -25,6 +27,23 @@ def __init__(self, plugin, message):
super(Exception, self).__init__(message)


class DistFacade(object):
"""Emulate a pkg_resources Distribution"""

def __init__(self, dist):
self._dist = dist

@property
def project_name(self):
return self.metadata["name"]

def __getattr__(self, attr, default=None):
return getattr(self._dist, attr, default)

def __dir__(self):
return sorted(dir(self._dist) + ["_dist", "project_name"])


class PluginManager(object):
""" Core Pluginmanager class which manages registration
of plugin objects and 1:N hook calling.
@@ -259,29 +278,21 @@ def load_setuptools_entrypoints(self, group, name=None):
:rtype: int
:return: return the number of loaded plugins by this call.
"""
from pkg_resources import (
iter_entry_points,
DistributionNotFound,
VersionConflict,
)

count = 0
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
try:
for dist in importlib_metadata.distributions():
for ep in dist.entry_points:
if (
ep.group != group
or (name is not None and ep.name != name)
# already registered
or self.get_plugin(ep.name)
or self.is_blocked(ep.name)
):
continue
plugin = ep.load()
except DistributionNotFound:
continue
except VersionConflict as e:
raise PluginValidationError(
plugin=None,
message="Plugin %r could not be loaded: %s!" % (ep.name, e),
)
self.register(plugin, name=ep.name)
self._plugin_distinfo.append((plugin, ep.dist))
count += 1
self.register(plugin, name=ep.name)
self._plugin_distinfo.append((plugin, DistFacade(dist)))
count += 1
return count

def list_plugin_distinfo(self):
21 changes: 21 additions & 0 deletions testing/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from pluggy.hooks import varnames
from pluggy.manager import _formatdef

import sys
import pytest


def test_varnames():
def f(x):
@@ -47,6 +50,24 @@ class F(object):
assert varnames(F) == ((), ())


@pytest.mark.skipif(
sys.version_info < (3,), reason="Keyword only arguments are Python 3 only"
)
def test_varnames_keyword_only():
# SyntaxError on Python 2, so we exec
ns = {}
exec(
"def f1(x, *, y): pass\n"
"def f2(x, *, y=3): pass\n"
"def f3(x=1, *, y=3): pass\n",
ns,
)

assert varnames(ns["f1"]) == (("x",), ())
assert varnames(ns["f2"]) == (("x",), ())
assert varnames(ns["f3"]) == ((), ("x",))


def test_formatdef():
def function1():
pass
66 changes: 21 additions & 45 deletions testing/test_pluginmanager.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
"""
import pytest
import types
import sys
import importlib_metadata
from pluggy import (
PluginManager,
PluginValidationError,
@@ -447,64 +447,40 @@ def example_hook():


def test_load_setuptools_instantiation(monkeypatch, pm):
pkg_resources = pytest.importorskip("pkg_resources")
class EntryPoint(object):
name = "myname"
group = "hello"
value = "myname:foo"

def my_iter(group, name=None):
assert group == "hello"
def load(self):
class PseudoPlugin(object):
x = 42

class EntryPoint(object):
name = "myname"
dist = None
return PseudoPlugin()

def load(self):
class PseudoPlugin(object):
x = 42
class Distribution(object):
entry_points = (EntryPoint(),)

return PseudoPlugin()
dist = Distribution()

return iter([EntryPoint()])
def my_distributions():
return (dist,)

monkeypatch.setattr(pkg_resources, "iter_entry_points", my_iter)
monkeypatch.setattr(importlib_metadata, "distributions", my_distributions)
num = pm.load_setuptools_entrypoints("hello")
assert num == 1
plugin = pm.get_plugin("myname")
assert plugin.x == 42
assert pm.list_plugin_distinfo() == [(plugin, None)]
ret = pm.list_plugin_distinfo()
# poor man's `assert ret == [(plugin, mock.ANY)]`
assert len(ret) == 1
assert len(ret[0]) == 2
assert ret[0][0] == plugin
assert ret[0][1]._dist == dist
num = pm.load_setuptools_entrypoints("hello")
assert num == 0 # no plugin loaded by this call


def test_load_setuptools_version_conflict(monkeypatch, pm):
"""Check that we properly handle a VersionConflict problem when loading entry points"""
pkg_resources = pytest.importorskip("pkg_resources")

def my_iter(group, name=None):
assert group == "hello"

class EntryPoint(object):
name = "myname"
dist = None

def load(self):
raise pkg_resources.VersionConflict("Some conflict")

return iter([EntryPoint()])

monkeypatch.setattr(pkg_resources, "iter_entry_points", my_iter)
with pytest.raises(
PluginValidationError,
match="Plugin 'myname' could not be loaded: Some conflict!",
):
pm.load_setuptools_entrypoints("hello")


def test_load_setuptools_not_installed(monkeypatch, pm):
monkeypatch.setitem(sys.modules, "pkg_resources", types.ModuleType("pkg_resources"))

with pytest.raises(ImportError):
pm.load_setuptools_entrypoints("qwe")


def test_add_tracefuncs(he_pm):
out = []