Compare commits

...

57 Commits
3.0.2 ... 3.0.3

Author SHA1 Message Date
Bruno Oliveira
ba6ecc14c8 Include release-3.0.3 into the announce toctree 2016-09-28 17:16:57 -04:00
Bruno Oliveira
41d3b3f4f9 Regendoc for version 3.0.3 2016-09-28 16:36:15 -04:00
Bruno Oliveira
dda17994ec Prepare for 3.0.3 release 2016-09-28 16:33:38 -04:00
Bruno Oliveira
427cee109a Merge pull request #1964 from nicoddemus/pluggy-0.4.0
Vendor pluggy 0.4.0
2016-09-27 17:35:51 -03:00
Florian Bruhin
30d459e2e3 Merge pull request #1968 from nicoddemus/use-latest-hypothesis
Use hypothesis >= 3.5.2
2016-09-26 15:01:09 +02:00
Bruno Oliveira
f31447b82b Use hypothesis >= 3.5.2
Related to #1962
2016-09-26 09:08:30 -03:00
Florian Bruhin
b071fdc633 Merge pull request #1960 from nicoddemus/skip-module-level-doc
Add a note about pytest.skip not being allowed at module level
2016-09-26 08:37:14 +02:00
Bruno Oliveira
19766ef0bc Add a summary on how to skip all tests in a module in different situations 2016-09-25 23:36:25 -03:00
Bruno Oliveira
94155ee62a Add a note about pytest.skip not being allowed at module level 2016-09-25 23:36:25 -03:00
Bruno Oliveira
835328d862 Vendor pluggy 0.4.0
Fix #1637
2016-09-25 23:36:02 -03:00
Bruno Oliveira
8dc497b54b Merge pull request #1966 from nicoddemus/disable-pypy-windows
Disable pypy on AppVeyor until #1963 gets fixed
2016-09-25 23:34:59 -03:00
Bruno Oliveira
da201c7d29 Disable pypy on AppVeyor until #1963 gets fixed 2016-09-25 23:21:37 -03:00
Bruno Oliveira
01068e5571 Merge pull request #1962 from nicoddemus/fix-ci
Pin hypothesis to 3.5.0 because 3.5.1 breaks the test suite
2016-09-25 21:17:17 -03:00
Bruno Oliveira
73cab77249 Pin hypothesis to 3.5.0 because 3.5.1 breaks the test suite
Related to HypothesisWorks/hypothesis-python#368
2016-09-25 18:52:27 -03:00
Bruno Oliveira
09bcf7f170 Merge pull request #1958 from rowillia/master
Remove implementation of `__getslice__`
2016-09-24 08:39:58 -03:00
Roy Williams
f1c4cfea2c Remove implementation of __getslice__
`__getslice__` has been Deprecated since Python 2.0 and is removed in Python 3.  See
https://docs.python.org/2/reference/datamodel.html#object.__getslice__

Unfortunately, Python 2 will still dispatch to `__getslice__` over `__getitem__`, See
http://bugs.python.org/issue2041, which causes Warnings when running with `-3` in 2.7.
2016-09-23 09:52:30 -07:00
Bruno Oliveira
e5deb8a927 Merge pull request #1955 from rowillia/fix_python3_deprecation_warnings
Fix `DeprecationWarnings` found when running py.test in Python 2.7 with the -3 flag.
2016-09-22 17:37:52 -03:00
Roy Williams
24db3c123d Explicitly set to None to have consistent behavior in Python 2 and Python 3 2016-09-22 09:22:12 -07:00
Roy Williams
940ed7e943 Fix DeprecationWarnings found when running py.test in Python 2.7 with the -3 flag.
Running through some of my tests with the `-3` flag in python2.7 I encountered some errors within py.test itself.  This fixes those errors so we can use py.test in order to identify problems with Python 3.
2016-09-21 17:44:25 -07:00
Bruno Oliveira
f279bd2bd5 Merge pull request #1918 from tgoodlet/explain_bad_scope
Explain a bad scope value to the user
2016-09-21 18:58:03 -03:00
Tyler Goodlet
6db2f315fa Explain a bad scope value to the user 2016-09-21 16:40:58 -04:00
Florian Bruhin
7660a19d0a Merge pull request #1945 from axil/master
AttributeError chaining bug #1944 fix
2016-09-20 08:36:04 +02:00
Lev Maximov
8cba033bbb added a test 2016-09-20 02:47:59 +07:00
Lev Maximov
6b56c36ae7 added to changelog and authors 2016-09-20 02:47:59 +07:00
Lev Maximov
65be1231b1 AttributeError chaining bug #1944 fix 2016-09-20 02:20:13 +07:00
Floris Bruynooghe
8639bf7554 fixup! Merge pkg_resources workaround 2016-09-19 10:20:36 +01:00
Floris Bruynooghe
f484e7c9ca Merge pkg_resources workaround
Merge branch 'pkg_resources_bugfix' of github.com:raquel-ucl/pytest into pkg-resources

This is an odd case and doesn't really make sense, it is working around a bug
in maven/jython and the old version or weird packaging of setuptools they use.
But we used to do this in the past so might as well keep doing this.
2016-09-19 10:14:41 +01:00
Ronny Pfannschmidt
2bafa74765 Merge pull request #1942 from mbyt/better_doc_for_1890
better doc for #1890 based on #1932
2016-09-17 20:14:44 +02:00
mbyt
77d842ceb2 better doc for #1890 based on #1932 2016-09-17 19:58:27 +02:00
Bruno Oliveira
863b7d0c50 Merge pull request #1933 from pytest-dev/metafunc-members-docs
Remove duplicated for Metafunc members on docs
2016-09-15 12:43:54 -03:00
Ronny Pfannschmidt
40ec35767f Merge pull request #1935 from nicoddemus/assert-rewrite-dev-plugins
Fixed assertion rewriting for plugins in development mode
2016-09-15 08:45:23 +02:00
Bruno Oliveira
04cf5e1df4 Fixed assertion rewriting for plugins in development mode
Fix #1934
2016-09-14 21:59:33 -03:00
Bruno Oliveira
138e255631 Remove duplicated for Metafunc members on docs
Fix #1924
2016-09-14 17:11:58 -03:00
Bruno Oliveira
51378aba01 Merge pull request #1919 from The-Compiler/pdf
Fix link to PDF docs
2016-09-07 16:23:26 -03:00
Florian Bruhin
8e67dd13e7 Fix link to PDF docs
Fixes #1917
2016-09-06 21:17:54 +02:00
Bruno Oliveira
99efc281ee Merge pull request #1914 from RonnyPfannschmidt/docs-remove-getdoctarget
docs: remove the need for special scripts
2016-09-05 16:38:41 -03:00
Ronny Pfannschmidt
a2b8981b50 docs: remove unused helper script 2016-09-05 21:03:22 +02:00
Ronny Pfannschmidt
e21ae3991d docs: remove the need for special scripts
* import version from pytest since it is importable
* remove makefile bits from legacy hosting
* remove the script to determine the version for legacy hosting
2016-09-05 16:42:33 +02:00
Florian Bruhin
8a41b26f56 Merge pull request #1908 from nicoddemus/parametrize-unicode-id
The "ids" argument to "parametrize" again accepts unicode strings in Python 2
2016-09-05 15:09:12 +02:00
Ronny Pfannschmidt
b6f766ae87 Merge pull request #1912 from flub/reg-assert-rewrite-changelog
Mention register_assert_rewrite explicitly
2016-09-05 14:36:05 +02:00
Floris Bruynooghe
ceeb5149f3 Mention register_assert_rewrite explicitly
It helps mentioning this explicitly in the changelog.
Fixes #1871.
2016-09-05 13:09:36 +01:00
Florian Bruhin
b38cf77562 Merge pull request #1911 from irachex/patch-1
Fix keyword docs
2016-09-05 11:27:49 +02:00
Huayi Zhang
c60854474a Fix keyword docs 2016-09-05 16:48:04 +08:00
Ronny Pfannschmidt
c69fbd79a9 Merge pull request #1910 from nicoddemus/monkeypatch-members-docs
Fix reference docs for monkeypatch
2016-09-03 21:13:54 +02:00
Bruno Oliveira
183f3737d4 Fix reference docs for monkeypatch
Fix #1909
2016-09-03 15:47:54 -03:00
Bruno Oliveira
1e10de574d The "ids" argument to "parametrize" again accepts unicode strings in Python 2
Fixes #1905
2016-09-02 18:38:15 -03:00
Florian Bruhin
722f9eadcd Merge pull request #1906 from pytest-dev/adjustment-how-to-release
Send only minor/major release announces to TIP mailing list
2016-09-02 18:10:29 +02:00
Bruno Oliveira
7a4fe7582c Send only minor/major release announces to TIP mailing list
As discussed recently on the testing-in-python mailing list, people have asked 
to restrict the amount of announcements there only to major/minor 
pytest releases
2016-09-02 12:27:06 -03:00
Bruno Oliveira
96a1d2941b Merge pull request #1900 from nicoddemus/finalize-3.0.2-release
Finalize 3.0.2 release
2016-09-01 23:05:39 -03:00
Bruno Oliveira
ee284ec587 Set version to 3.0.3.dev0
Also, using "dev0" as development suffix otherwise distutils gives a warning during "setup.py develop":

UserWarning: Normalizing '3.0.3.dev' to '3.0.3.dev0'
  normalized_version,
2016-09-01 21:34:54 -03:00
Bruno Oliveira
927f411ee2 Fix release 3.0.2 release announcement list of authors 2016-09-01 21:28:30 -03:00
Bruno Oliveira
919f50a3bd Merge pull request #1896 from nicoddemus/release-3.0.2
Release 3.0.2
2016-09-01 21:19:50 -03:00
Raquel Alegre
8f516d27fa Moved import pkg_resources to else clause. 2016-08-24 10:25:01 +01:00
Raquel Alegre
d3f4b3d14a mend 2016-08-23 16:50:00 +01:00
Raquel Alegre
a1597aca89 Added #1853 to changelog as requested on PR. 2016-08-23 16:48:24 +01:00
Raquel Alegre
7d498fdc82 Added myself as AUTHOR as requested on PR. 2016-08-23 16:47:15 +01:00
Raquel Alegre
2f11a85698 Import pkg_resources only when necessary. 2016-08-23 16:41:11 +01:00
54 changed files with 389 additions and 175 deletions

View File

@@ -78,6 +78,7 @@ Kale Kundert
Katarzyna Jachim
Kevin Cox
Lee Kamentsky
Lev Maximov
Lukas Bednar
Maciek Fijalkowski
Maho
@@ -106,6 +107,7 @@ Punyashloka Biswal
Quentin Pradet
Ralf Schmitt
Raphael Pierzina
Raquel Alegre
Roberto Polli
Romain Dorgueil
Roman Bolshakov
@@ -125,6 +127,7 @@ Ted Xiao
Thomas Grainger
Tom Viner
Trevor Bekolay
Tyler Goodlet
Vasily Kuznetsov
Wouter van Ackooy
Xuecong Liao

View File

@@ -1,3 +1,41 @@
3.0.3
=====
* The ``ids`` argument to ``parametrize`` again accepts ``unicode`` strings
in Python 2 (`#1905`_).
Thanks `@philpep`_ for the report and `@nicoddemus`_ for the PR.
* Assertions are now being rewritten for plugins in development mode
(``pip install -e``) (`#1934`_).
Thanks `@nicoddemus`_ for the PR.
* Fix pkg_resources import error in Jython projects (`#1853`).
Thanks `@raquel-ucl`_ for the PR.
* Got rid of ``AttributeError: 'Module' object has no attribute '_obj'`` exception
in Python 3 (`#1944`_).
Thanks `@axil`_ for the PR.
* Explain a bad scope value passed to ``@fixture`` declarations or
a ``MetaFunc.parametrize()`` call. Thanks `@tgoodlet`_ for the PR.
* This version includes ``pluggy-0.4.0``, which correctly handles
``VersionConflict`` errors in plugins (`#704`_).
Thanks `@nicoddemus`_ for the PR.
.. _@philpep: https://github.com/philpep
.. _@raquel-ucl: https://github.com/raquel-ucl
.. _@axil: https://github.com/axil
.. _@tgoodlet: https://github.com/tgoodlet
.. _#1905: https://github.com/pytest-dev/pytest/issues/1905
.. _#1934: https://github.com/pytest-dev/pytest/issues/1934
.. _#1944: https://github.com/pytest-dev/pytest/issues/1944
.. _#704: https://github.com/pytest-dev/pytest/issues/704
3.0.2
=====
@@ -75,7 +113,11 @@ time or change existing behaviors in order to make them less surprising/more use
* Reinterpretation mode has now been removed. Only plain and rewrite
mode are available, consequently the ``--assert=reinterp`` option is
no longer available. Thanks `@flub`_ for the PR.
no longer available. This also means files imported from plugins or
``conftest.py`` will not benefit from improved assertions by
default, you should use ``pytest.register_assert_rewrite()`` to
explicitly turn on assertion rewriting for those files. Thanks
`@flub`_ for the PR.
* The following deprecated commandline options were removed:

View File

@@ -54,8 +54,8 @@ Note: this assumes you have already registered on pypi.
11. Send release announcement to mailing lists:
- pytest-dev@python.org
- testing-in-python@lists.idyll.org
- python-announce-list@python.org
- testing-in-python@lists.idyll.org (only for minor/major releases)
And announce the release on Twitter, making sure to add the hashtag ``#pytest``.
@@ -64,19 +64,19 @@ Note: this assumes you have already registered on pypi.
a. **patch release (2.8.3)**:
1. Checkout ``master``.
2. Update version number in ``_pytest/__init__.py`` to ``"2.8.4.dev"``.
3. Create a new section in ``CHANGELOG.rst`` titled ``2.8.4.dev`` and add a few bullet points as placeholders for new entries.
2. Update version number in ``_pytest/__init__.py`` to ``"2.8.4.dev0"``.
3. Create a new section in ``CHANGELOG.rst`` titled ``2.8.4.dev0`` and add a few bullet points as placeholders for new entries.
4. Commit and push.
b. **minor release (2.9.0)**:
1. Merge ``features`` into ``master``.
2. Checkout ``master``.
3. Follow the same steps for a **patch release** above, using the next patch release: ``2.9.1.dev``.
3. Follow the same steps for a **patch release** above, using the next patch release: ``2.9.1.dev0``.
4. Commit ``master``.
5. Checkout ``features`` and merge with ``master`` (should be a fast-forward at this point).
6. Update version number in ``_pytest/__init__.py`` to the next minor release: ``"2.10.0.dev"``.
7. Create a new section in ``CHANGELOG.rst`` titled ``2.10.0.dev``, above ``2.9.1.dev``, and add a few bullet points as placeholders for new entries.
6. Update version number in ``_pytest/__init__.py`` to the next minor release: ``"2.10.0.dev0"``.
7. Create a new section in ``CHANGELOG.rst`` titled ``2.10.0.dev0``, above ``2.9.1.dev0``, and add a few bullet points as placeholders for new entries.
8. Commit ``features``.
9. Push ``master`` and ``features``.

View File

@@ -1,2 +1,2 @@
#
__version__ = '3.0.2'
__version__ = '3.0.3'

View File

@@ -12,6 +12,7 @@ if sys.version_info[0] >= 3:
else:
from ._py2traceback import format_exception_only
class Code(object):
""" wrapper around Python code objects """
def __init__(self, rawcode):
@@ -28,6 +29,8 @@ class Code(object):
def __eq__(self, other):
return self.raw == other.raw
__hash__ = None
def __ne__(self, other):
return not self == other

View File

@@ -52,22 +52,21 @@ class Source(object):
return str(self) == other
return False
__hash__ = None
def __getitem__(self, key):
if isinstance(key, int):
return self.lines[key]
else:
if key.step not in (None, 1):
raise IndexError("cannot slice a Source with a step")
return self.__getslice__(key.start, key.stop)
newsource = Source()
newsource.lines = self.lines[key.start:key.stop]
return newsource
def __len__(self):
return len(self.lines)
def __getslice__(self, start, end):
newsource = Source()
newsource.lines = self.lines[start:end]
return newsource
def strip(self):
""" return new source object with trailing
and leading blank lines removed.

View File

@@ -105,7 +105,7 @@ except NameError:
def assertrepr_compare(config, op, left, right):
"""Return specialised explanations for some operators/operands"""
width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op
left_repr = py.io.saferepr(left, maxsize=int(width/2))
left_repr = py.io.saferepr(left, maxsize=int(width//2))
right_repr = py.io.saferepr(right, maxsize=width-len(left_repr))
summary = u('%s %s %s') % (ecu(left_repr), op, ecu(right_repr))

View File

@@ -5,7 +5,6 @@ import traceback
import types
import warnings
import pkg_resources
import py
# DON't import pytest here because it causes import cycle troubles
import sys, os
@@ -952,18 +951,24 @@ class Config(object):
except SystemError:
mode = 'plain'
else:
import pkg_resources
self.pluginmanager.rewrite_hook = hook
for entrypoint in pkg_resources.iter_entry_points('pytest11'):
for entry in entrypoint.dist._get_metadata('RECORD'):
fn = entry.split(',')[0]
is_simple_module = os.sep not in fn and fn.endswith('.py')
is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py')
if is_simple_module:
module_name, ext = os.path.splitext(fn)
hook.mark_rewrite(module_name)
elif is_package:
package_name = os.path.dirname(fn)
hook.mark_rewrite(package_name)
# 'RECORD' available for plugins installed normally (pip install)
# 'SOURCES.txt' available for plugins installed in dev mode (pip install -e)
# for installed plugins 'SOURCES.txt' returns an empty list, and vice-versa
# so it shouldn't be an issue
for metadata in ('RECORD', 'SOURCES.txt'):
for entry in entrypoint.dist._get_metadata(metadata):
fn = entry.split(',')[0]
is_simple_module = os.sep not in fn and fn.endswith('.py')
is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py')
if is_simple_module:
module_name, ext = os.path.splitext(fn)
hook.mark_rewrite(module_name)
elif is_package:
package_name = os.path.dirname(fn)
hook.mark_rewrite(package_name)
self._warn_about_missing_assertion(mode)
def _warn_about_missing_assertion(self, mode):

View File

@@ -599,12 +599,29 @@ class ScopeMismatchError(Exception):
which has a lower scope (e.g. a Session one calls a function one)
"""
scopes = "session module class function".split()
scopenum_function = scopes.index("function")
def scopemismatch(currentscope, newscope):
return scopes.index(newscope) > scopes.index(currentscope)
def scope2index(scope, descr, where=None):
"""Look up the index of ``scope`` and raise a descriptive value error
if not defined.
"""
try:
return scopes.index(scope)
except ValueError:
raise ValueError(
"{0} {1}has an unsupported scope value '{2}'".format(
descr, 'from {0} '.format(where) if where else '',
scope)
)
class FixtureLookupError(LookupError):
""" could not return a requested Fixture (missing or invalid). """
def __init__(self, argname, request, msg=None):
@@ -703,6 +720,7 @@ def call_fixture_func(fixturefunc, request, kwargs):
res = fixturefunc(**kwargs)
return res
class FixtureDef:
""" A container for a factory definition. """
def __init__(self, fixturemanager, baseid, argname, func, scope, params,
@@ -713,7 +731,11 @@ class FixtureDef:
self.func = func
self.argname = argname
self.scope = scope
self.scopenum = scopes.index(scope or "function")
self.scopenum = scope2index(
scope or "function",
descr='fixture {0}'.format(func.__name__),
where=baseid
)
self.params = params
startindex = unittest and 1 or None
self.argnames = getfuncargnames(func, startindex=startindex)

View File

@@ -19,7 +19,7 @@ def pytest_addoption(parser):
help="only run tests which match the given substring expression. "
"An expression is a python evaluatable expression "
"where all names are substring-matched against test names "
"and their parent classes. Example: -k 'test_method or test "
"and their parent classes. Example: -k 'test_method or test_"
"other' matches all test functions and classes whose name "
"contains 'test_method' or 'test_other'. "
"Additionally keywords are matched to classes and functions "

View File

@@ -205,11 +205,10 @@ class PyobjContext(object):
class PyobjMixin(PyobjContext):
def obj():
def fget(self):
try:
return self._obj
except AttributeError:
obj = getattr(self, '_obj', None)
if obj is None:
self._obj = obj = self._getobj()
return obj
return obj
def fset(self, value):
self._obj = value
return property(fget, fset, None, "underlying python object")
@@ -771,7 +770,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
It will also override any fixture-function defined scope, allowing
to set a dynamic scope using test context or configuration.
"""
from _pytest.fixtures import scopes
from _pytest.fixtures import scope2index
from _pytest.mark import extract_argvalue
from py.io import saferepr
@@ -800,7 +799,8 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
if scope is None:
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)
scopenum = scopes.index(scope)
scopenum = scope2index(
scope, descr='call to {0}'.format(self.parametrize))
valtypes = {}
for arg in argnames:
if arg not in self.fixturenames:
@@ -832,7 +832,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
raise ValueError('%d tests specified with %d ids' %(
len(argvalues), len(ids)))
for id_value in ids:
if id_value is not None and not isinstance(id_value, str):
if id_value is not None and not isinstance(id_value, py.builtin._basestring):
msg = 'ids must be list of strings, found: %s (type: %s)'
raise ValueError(msg % (saferepr(id_value), type(id_value).__name__))
ids = idmaker(argnames, argvalues, idfn, ids, self.config)
@@ -1357,6 +1357,8 @@ class approx(object):
return False
return all(a == x for a, x in zip(actual, self.expected))
__hash__ = None
def __ne__(self, actual):
return not (actual == self)
@@ -1436,6 +1438,8 @@ class ApproxNonIterable(object):
# Return true if the two numbers are within the tolerance.
return abs(self.expected - actual) <= self.tolerance
__hash__ = None
def __ne__(self, actual):
return not (actual == self)

View File

@@ -10,4 +10,4 @@ $ pip install -U pluggy==<version> --no-compile --target=_pytest/vendored_packag
```
And commit the modified files. The `pluggy-<version>.dist-info` directory
created by `pip` should be ignored.
created by `pip` should be added as well.

View File

@@ -1,8 +0,0 @@
pluggy.py,sha256=v_RfWzyW6DPU1cJu_EFoL_OHq3t13qloVdR6UaMCXQA,29862
pluggy-0.3.1.dist-info/top_level.txt,sha256=xKSCRhai-v9MckvMuWqNz16c1tbsmOggoMSwTgcpYHE,7
pluggy-0.3.1.dist-info/pbr.json,sha256=xX3s6__wOcAyF-AZJX1sdZyW6PUXT-FkfBlM69EEUCg,47
pluggy-0.3.1.dist-info/RECORD,,
pluggy-0.3.1.dist-info/metadata.json,sha256=nLKltOT78dMV-00uXD6Aeemp4xNsz2q59j6ORSDeLjw,1027
pluggy-0.3.1.dist-info/METADATA,sha256=1b85Ho2u4iK30M099k7axMzcDDhLcIMb-A82JUJZnSo,1334
pluggy-0.3.1.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110
pluggy-0.3.1.dist-info/DESCRIPTION.rst,sha256=P5Akh1EdIBR6CeqtV2P8ZwpGSpZiTKPw0NyS7jEiD-g,306

View File

@@ -1 +0,0 @@
{"license": "MIT license", "name": "pluggy", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "summary": "plugin and hook calling mechanisms for python", "platform": "unix", "version": "0.3.1", "extensions": {"python.details": {"document_names": {"description": "DESCRIPTION.rst"}, "contacts": [{"role": "author", "email": "holger at merlinux.eu", "name": "Holger Krekel"}]}}, "classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Libraries", "Topic :: Utilities", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"]}

View File

@@ -1 +0,0 @@
{"is_release": false, "git_version": "7d4c9cd"}

View File

@@ -1,3 +1,4 @@
Plugin registration and hook calling for Python
===============================================

View File

@@ -0,0 +1 @@
pip

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 holger krekel (rather uses bitbucket/hpk42)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,8 +1,8 @@
Metadata-Version: 2.0
Name: pluggy
Version: 0.3.1
Version: 0.4.0
Summary: plugin and hook calling mechanisms for python
Home-page: UNKNOWN
Home-page: https://github.com/pytest-dev/pluggy
Author: Holger Krekel
Author-email: holger at merlinux.eu
License: MIT license
@@ -27,6 +27,7 @@ Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Plugin registration and hook calling for Python
===============================================

View File

@@ -0,0 +1,9 @@
pluggy.py,sha256=u0oG9cv-oLOkNvEBlwnnu8pp1AyxpoERgUO00S3rvpQ,31543
pluggy-0.4.0.dist-info/DESCRIPTION.rst,sha256=ltvjkFd40LW_xShthp6RRVM6OB_uACYDFR3kTpKw7o4,307
pluggy-0.4.0.dist-info/LICENSE.txt,sha256=ruwhUOyV1HgE9F35JVL9BCZ9vMSALx369I4xq9rhpkM,1134
pluggy-0.4.0.dist-info/METADATA,sha256=pe2hbsqKFaLHC6wAQPpFPn0KlpcPfLBe_BnS4O70bfk,1364
pluggy-0.4.0.dist-info/RECORD,,
pluggy-0.4.0.dist-info/WHEEL,sha256=9Z5Xm-eel1bTS7e6ogYiKz0zmPEqDwIypurdHN1hR40,116
pluggy-0.4.0.dist-info/metadata.json,sha256=T3go5L2qOa_-H-HpCZi3EoVKb8sZ3R-fOssbkWo2nvM,1119
pluggy-0.4.0.dist-info/top_level.txt,sha256=xKSCRhai-v9MckvMuWqNz16c1tbsmOggoMSwTgcpYHE,7
pluggy-0.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4

View File

@@ -1,5 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.24.0)
Generator: bdist_wheel (0.29.0)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@@ -0,0 +1 @@
{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Libraries", "Topic :: Utilities", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"], "extensions": {"python.details": {"contacts": [{"email": "holger at merlinux.eu", "name": "Holger Krekel", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://github.com/pytest-dev/pluggy"}}}, "generator": "bdist_wheel (0.29.0)", "license": "MIT license", "metadata_version": "2.0", "name": "pluggy", "platform": "unix", "summary": "plugin and hook calling mechanisms for python", "version": "0.4.0"}

View File

@@ -67,8 +67,9 @@ Pluggy currently consists of functionality for:
import sys
import inspect
__version__ = '0.3.1'
__all__ = ["PluginManager", "PluginValidationError",
__version__ = '0.4.0'
__all__ = ["PluginManager", "PluginValidationError", "HookCallError",
"HookspecMarker", "HookimplMarker"]
_py3 = sys.version_info > (3, 0)
@@ -308,7 +309,7 @@ class PluginManager(object):
""" Core Pluginmanager class which manages registration
of plugin objects and 1:N hook calling.
You can register new hooks by calling ``addhooks(module_or_class)``.
You can register new hooks by calling ``add_hookspec(module_or_class)``.
You can register plugin objects (which contain hooks) by calling
``register(plugin)``. The Pluginmanager is initialized with a
prefix that is searched for in the names of the dict of registered
@@ -374,7 +375,10 @@ class PluginManager(object):
def parse_hookimpl_opts(self, plugin, name):
method = getattr(plugin, name)
res = getattr(method, self.project_name + "_impl", None)
try:
res = getattr(method, self.project_name + "_impl", None)
except Exception:
res = {}
if res is not None and not isinstance(res, dict):
# false positive
res = None
@@ -455,6 +459,10 @@ class PluginManager(object):
""" Return a plugin or None for the given name. """
return self._name2plugin.get(name)
def has_plugin(self, name):
""" Return True if a plugin with the given name is registered. """
return self.get_plugin(name) is not None
def get_name(self, plugin):
""" Return name for registered plugin or None if not registered. """
for name, val in self._name2plugin.items():
@@ -492,7 +500,8 @@ class PluginManager(object):
def load_setuptools_entrypoints(self, entrypoint_name):
""" Load modules from querying the specified setuptools entrypoint name.
Return the number of loaded plugins. """
from pkg_resources import iter_entry_points, DistributionNotFound
from pkg_resources import (iter_entry_points, DistributionNotFound,
VersionConflict)
for ep in iter_entry_points(entrypoint_name):
# is the plugin registered or blocked?
if self.get_plugin(ep.name) or self.is_blocked(ep.name):
@@ -501,6 +510,9 @@ class PluginManager(object):
plugin = ep.load()
except DistributionNotFound:
continue
except VersionConflict as e:
raise PluginValidationError(
"Plugin %r could not be loaded: %s!" % (ep.name, e))
self.register(plugin, name=ep.name)
self._plugin_distinfo.append((plugin, ep.dist))
return len(self._plugin_distinfo)
@@ -573,7 +585,7 @@ class _MultiCall:
# XXX note that the __multicall__ argument is supported only
# for pytest compatibility reasons. It was never officially
# supported there and is explicitly deprecated since 2.8
# supported there and is explicitely deprecated since 2.8
# so we can remove it soon, allowing to avoid the below recursion
# in execute() and simplify/speed up the execute loop.
@@ -590,7 +602,13 @@ class _MultiCall:
while self.hook_impls:
hook_impl = self.hook_impls.pop()
args = [all_kwargs[argname] for argname in hook_impl.argnames]
try:
args = [all_kwargs[argname] for argname in hook_impl.argnames]
except KeyError:
for argname in hook_impl.argnames:
if argname not in all_kwargs:
raise HookCallError(
"hook call must provide argument %r" % (argname,))
if hook_impl.hookwrapper:
return _wrapped_call(hook_impl.function(*args), self.execute)
res = hook_impl.function(*args)
@@ -629,7 +647,10 @@ def varnames(func, startindex=None):
startindex = 1
else:
if not inspect.isfunction(func) and not inspect.ismethod(func):
func = getattr(func, '__call__', func)
try:
func = getattr(func, '__call__', func)
except Exception:
return ()
if startindex is None:
startindex = int(inspect.ismethod(func))
@@ -763,6 +784,10 @@ class PluginValidationError(Exception):
""" plugin failed validation. """
class HookCallError(Exception):
""" Hook was called wrongly. """
if hasattr(inspect, 'signature'):
def _formatdef(func):
return "%s%s" % (

View File

@@ -8,7 +8,8 @@ environment:
matrix:
# create multiple jobs to execute a set of tox runs on each; this is to workaround having
# builds timing out in AppVeyor
- TOXENV: "linting,py26,py27,py33,py34,py35,pypy"
# pypy is disabled until #1963 gets fixed
- TOXENV: "linting,py26,py27,py33,py34,py35"
- TOXENV: "py27-pexpect,py27-xdist,py27-trial,py35-pexpect,py35-xdist,py35-trial"
- TOXENV: "py27-nobyte,doctesting,freeze,docs"

View File

@@ -19,10 +19,9 @@ REGENDOC_ARGS := \
--normalize "@/tmp/pytest-of-.*/pytest-\d+@PYTEST_TMPDIR@" \
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@@ -36,22 +35,6 @@ help:
clean:
-rm -rf $(BUILDDIR)/*
SITETARGET=$(shell ./_getdoctarget.py)
showtarget:
@echo $(SITETARGET)
install: html
# for access talk to someone with login rights to
# pytest-dev@pytest.org to add your ssh key
rsync -avz _build/html/ pytest-dev@pytest.org:pytest.org/$(SITETARGET)
installpdf: latexpdf
@scp $(BUILDDIR)/latex/pytest.pdf pytest-dev@pytest.org:pytest.org/$(SITETARGET)
installall: clean install installpdf
@echo "done"
regen:
PYTHONDONTWRITEBYTECODE=1 COLUMNS=76 regendoc --update *.rst */*.rst ${REGENDOC_ARGS}

View File

@@ -1,16 +0,0 @@
#!/usr/bin/env python
import py
def get_version_string():
fn = py.path.local(__file__).join("..", "..", "..",
"_pytest", "__init__.py")
for line in fn.readlines():
if "version" in line and not line.strip().startswith('#'):
return eval(line.split("=")[-1])
def get_minor_version_string():
return ".".join(get_version_string().split(".")[:2])
if __name__ == "__main__":
print (get_minor_version_string())

View File

@@ -6,6 +6,6 @@
<li><a href="https://github.com/pytest-dev/pytest/">pytest @ GitHub</a></li>
<li><a href="http://plugincompat.herokuapp.com/">3rd party plugins</a></li>
<li><a href="https://github.com/pytest-dev/pytest/issues">Issue Tracker</a></li>
<li><a href="http://pytest.org/latest/pytest.pdf">PDF Documentation</a>
<li><a href="https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf">PDF Documentation</a>
</ul>

View File

@@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2
release-3.0.3
release-3.0.2
release-3.0.1
release-3.0.0

View File

@@ -12,15 +12,13 @@ The changelog is available at http://doc.pytest.org/en/latest/changelog.html.
Thanks to all who contributed to this release, among them:
* Adam Chainz
* Andrew Svetlov
* Ahn Ki-Wook
* Bruno Oliveira
* Daniel Hahler
* Dmitry Dygalo
* Florian Bruhin
* Marcin Bachry
* Jordan Guymon
* Raphael Pierzina
* Ronny Pfannschmidt
* matthiasha
* mbyt
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,27 @@
pytest-3.0.3
============
pytest 3.0.3 has just been released to PyPI.
This release fixes some regressions and bugs reported in the last version,
being a drop-in replacement. To upgrade::
pip install --upgrade pytest
The changelog is available at http://doc.pytest.org/en/latest/changelog.html.
Thanks to all who contributed to this release, among them:
* Bruno Oliveira
* Florian Bruhin
* Floris Bruynooghe
* Huayi Zhang
* Lev Maximov
* Raquel Alegre
* Ronny Pfannschmidt
* Roy Williams
* Tyler Goodlet
* mbyt
Happy testing,
The pytest Development Team

View File

@@ -26,7 +26,7 @@ you will see the return value of the function call::
$ pytest test_assert1.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -170,7 +170,7 @@ if you run this module::
$ pytest test_assert2.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -80,7 +80,7 @@ If you then run it with ``--lf``::
$ pytest --lf
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
run-last-failure: rerun last 2 failures
rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items
@@ -122,7 +122,7 @@ of ``FF`` and dots)::
$ pytest --ff
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
run-last-failure: rerun last 2 failures first
rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items
@@ -227,7 +227,7 @@ You can always peek at the content of the cache using the
$ py.test --cache-show
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
cachedir: $REGENDOC_TMPDIR/.cache
------------------------------- cache values -------------------------------

View File

@@ -64,7 +64,7 @@ of the failing function and hide the other one::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -19,11 +19,8 @@
# The short X.Y version.
import os, sys
sys.path.insert(0, os.path.dirname(__file__))
import _getdoctarget
version = _getdoctarget.get_minor_version_string()
release = _getdoctarget.get_version_string()
from _pytest import __version__ as version
release = ".".join(version.split(".")[:2])
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the

View File

@@ -49,7 +49,7 @@ then you can just invoke ``pytest`` without command line options::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 items

View File

@@ -31,7 +31,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
$ pytest -v -m webtest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -45,7 +45,7 @@ Or the inverse, running all tests except the webtest ones::
$ pytest -v -m "not webtest"
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -66,7 +66,7 @@ tests based on their module, class, method, or function name::
$ pytest -v test_server.py::TestClass::test_method
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 5 items
@@ -79,7 +79,7 @@ You can also select on the class::
$ pytest -v test_server.py::TestClass
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -92,7 +92,7 @@ Or select multiple nodes::
$ pytest -v test_server.py::TestClass test_server.py::test_send_http
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items
@@ -130,7 +130,7 @@ select tests based on their names::
$ pytest -v -k http # running with the above defined example module
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -144,7 +144,7 @@ And you can also run all tests except the ones that match the keyword::
$ pytest -k "not send_http" -v
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -160,7 +160,7 @@ Or to select "http" and "quick" tests::
$ pytest -k "http or quick" -v
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -352,7 +352,7 @@ the test needs::
$ pytest -E stage2
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -364,7 +364,7 @@ and here is one that specifies exactly the environment needed::
$ pytest -E stage1
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -485,7 +485,7 @@ then you will see two test skipped and two executed tests as expected::
$ pytest -rs # this option reports skip reasons
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -499,7 +499,7 @@ Note that if you specify a platform via the marker-command line option like this
$ pytest -m linux2
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -551,7 +551,7 @@ We can now use the ``-m option`` to select one set::
$ pytest -m interface --tb=short
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -573,7 +573,7 @@ or to select both "event" and "interface" tests::
$ pytest -m "interface or event" --tb=short
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items

View File

@@ -27,7 +27,7 @@ now execute the test specification::
nonpython $ pytest test_simple.yml
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
@@ -59,7 +59,7 @@ consulted when reporting in ``verbose`` mode::
nonpython $ pytest -v
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collecting ... collected 2 items
@@ -81,7 +81,7 @@ interesting to just look at the collection tree::
nonpython $ pytest --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
<YamlFile 'test_simple.yml'>

View File

@@ -130,7 +130,7 @@ objects, they are still using the default pytest representation::
$ pytest test_time.py --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 6 items
<Module 'test_time.py'>
@@ -181,7 +181,7 @@ this is a fully self-contained example which you can run with::
$ pytest test_scenarios.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -194,7 +194,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
$ pytest --collect-only test_scenarios.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
<Module 'test_scenarios.py'>
@@ -259,7 +259,7 @@ Let's first see how it looks like at collection time::
$ pytest test_backends.py --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
<Module 'test_backends.py'>
@@ -320,7 +320,7 @@ The result of this test will be successful::
$ pytest test_indirect_list.py --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
<Module 'test_indirect_list.py'>
@@ -447,7 +447,7 @@ If you run this with reporting for skips enabled::
$ pytest -rs test_module.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -117,7 +117,7 @@ then the test collection looks like this::
$ pytest --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 2 items
<Module 'check_myapp.py'>
@@ -163,7 +163,7 @@ You can always peek at the collection tree without running tests like this::
. $ pytest --collect-only pythoncollection.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 3 items
<Module 'CWD/pythoncollection.py'>
@@ -230,7 +230,7 @@ will be left out::
$ pytest --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 0 items

View File

@@ -11,7 +11,7 @@ get on the terminal - we are working on that)::
assertion $ pytest failure_demo.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR/assertion, inifile:
collected 42 items

View File

@@ -113,7 +113,7 @@ directory with the above conftest.py::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
@@ -164,7 +164,7 @@ and when running it will see a skipped "slow" test::
$ pytest -rs # "-rs" means report details on the little 's'
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -178,7 +178,7 @@ Or run it including the ``slow`` marked test::
$ pytest --runslow
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -302,7 +302,7 @@ which will add the string to the test header accordingly::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
project deps: mylib-1.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
@@ -327,7 +327,7 @@ which will add info only when run with "--v"::
$ pytest -v
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
info1: did you know that ...
did you?
@@ -340,7 +340,7 @@ and nothing when run plainly::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
@@ -374,7 +374,7 @@ Now we can profile which test functions execute the slowest::
$ pytest --durations=3
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -440,7 +440,7 @@ If we run this::
$ pytest -rx
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -519,7 +519,7 @@ We can run this::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 7 items
@@ -627,7 +627,7 @@ and run them::
$ pytest test_module.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -721,7 +721,7 @@ and run it::
$ pytest -s test_module.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items

View File

@@ -70,7 +70,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
$ pytest test_smtpsimple.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -188,7 +188,7 @@ inspect what is going on and can now run the tests::
$ pytest test_module.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -516,7 +516,7 @@ Running the above tests results in the following test IDs being used::
$ pytest --collect-only
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 11 items
<Module 'test_anothersmtp.py'>
@@ -569,7 +569,7 @@ Here we declare an ``app`` fixture which receives the previously defined
$ pytest -v test_appsetup.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 2 items
@@ -638,7 +638,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
$ pytest -v -s test_module.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items

View File

@@ -26,7 +26,7 @@ Installation::
To check your installation has installed the correct version::
$ pytest --version
This is pytest version 3.0.2, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py
This is pytest version 3.0.3, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py
.. _`simpletest`:
@@ -46,7 +46,7 @@ That's it. You can execute the test function now::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -25,7 +25,7 @@ To execute it::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -59,6 +59,7 @@ Method reference of the monkeypatch fixture
-------------------------------------------
.. autoclass:: MonkeyPatch
:members:
``monkeypatch.setattr/delattr/delitem/delenv()`` all
by default raise an Exception if the target does not exist.

View File

@@ -55,7 +55,7 @@ them in turn::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -103,7 +103,7 @@ Let's run this::
$ pytest
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -216,6 +216,3 @@ The **metafunc** object
.. currentmodule:: _pytest.python
.. autoclass:: Metafunc
:members:
.. automethod:: Metafunc.parametrize
.. automethod:: Metafunc.addcall(funcargs=None,id=_notexists,param=_notexists)

View File

@@ -224,7 +224,7 @@ Running it with the report-on-xfail option gives this output::
example $ pytest -rx xfail_demo.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR/example, inifile:
collected 7 items
@@ -293,6 +293,20 @@ imperatively, in test or setup code::
# or
pytest.skip("unsupported configuration")
Note that calling ``pytest.skip`` at the module level
is not allowed since pytest 3.0. If you are upgrading
and ``pytest.skip`` was being used at the module level, you can set a
``pytestmark`` variable:
.. code-block:: python
# before pytest 3.0
pytest.skip('skipping all tests because of reasons')
# after pytest 3.0
pytestmark = pytest.mark.skip('skipping all tests because of reasons')
``pytestmark`` applies a mark or list of marks to all tests in a module.
Skipping on a missing import dependency
--------------------------------------------------
@@ -371,3 +385,27 @@ The equivalent with "boolean conditions" is::
imported before pytest's argument parsing takes place. For example,
``conftest.py`` files are imported before command line parsing and thus
``config.getvalue()`` will not execute correctly.
Summary
-------
Here's a quick guide on how to skip tests in a module in different situations:
1. Skip all tests in a module unconditionally:
.. code-block:: python
pytestmark = pytest.mark.skip('all tests still WIP')
2. Skip all tests in a module based on some condition:
.. code-block:: python
pytestmark = pytest.mark.skipif(sys.platform == 'win32', 'tests for linux only')
3. Skip all tests in a module if some import is missing:
.. code-block:: python
pexpect = pytest.importorskip('pexpect')

View File

@@ -29,7 +29,7 @@ Running this would result in a passed test except for the last
$ pytest test_tmpdir.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -38,7 +38,11 @@ the general ``pytest`` documentation for many more examples.
Running tests from ``unittest.TestCase`` subclasses with ``--pdb`` will
disable tearDown and cleanup methods for the case that an Exception
occurs. This allows proper post mortem debugging for all applications
which have significant logic in their tearDown machinery.
which have significant logic in their tearDown machinery. However,
supporting this feature has the following side effect: If people
overwrite ``unittest.TestCase`` ``__call__`` or ``run``, they need to
to overwrite ``debug`` in the same way (this is also true for standard
unittest).
Mixing pytest fixtures into unittest.TestCase style tests
-----------------------------------------------------------
@@ -96,7 +100,7 @@ the ``self.db`` values in the traceback::
$ pytest test_unittest_db.py
======= test session starts ========
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -1063,6 +1063,22 @@ class TestFixtureUsages:
"*1 error*"
])
def test_invalid_scope(self, testdir):
testdir.makepyfile("""
import pytest
@pytest.fixture(scope="functions")
def badscope():
pass
def test_nothing(badscope):
pass
""")
result = testdir.runpytest_inprocess()
result.stdout.fnmatch_lines(
("*ValueError: fixture badscope from test_invalid_scope.py has an unsupported"
" scope value 'functions'")
)
def test_funcarg_parametrized_and_used_twice(self, testdir):
testdir.makepyfile("""
import pytest

View File

@@ -96,6 +96,14 @@ class TestMetafunc:
pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6]))
pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6]))
def test_parametrize_bad_scope(self, testdir):
def func(x): pass
metafunc = self.Metafunc(func)
try:
metafunc.parametrize("x", [1], scope='doggy')
except ValueError as ve:
assert "has an unsupported scope value 'doggy'" in str(ve)
def test_parametrize_and_id(self):
def func(x, y): pass
metafunc = self.Metafunc(func)
@@ -105,6 +113,14 @@ class TestMetafunc:
ids = [x.id for x in metafunc._calls]
assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"]
def test_parametrize_and_id_unicode(self):
"""Allow unicode strings for "ids" parameter in Python 2 (##1905)"""
def func(x): pass
metafunc = self.Metafunc(func)
metafunc.parametrize("x", [1, 2], ids=[u'basic', u'advanced'])
ids = [x.id for x in metafunc._calls]
assert ids == [u"basic", u"advanced"]
def test_parametrize_with_wrong_number_of_ids(self, testdir):
def func(x, y): pass
metafunc = self.Metafunc(func)

View File

@@ -108,7 +108,8 @@ class TestImportHookInstallation:
assert result.ret == 0
@pytest.mark.parametrize('mode', ['plain', 'rewrite'])
def test_installed_plugin_rewrite(self, testdir, mode):
@pytest.mark.parametrize('plugin_state', ['development', 'installed'])
def test_installed_plugin_rewrite(self, testdir, mode, plugin_state):
# Make sure the hook is installed early enough so that plugins
# installed via setuptools are re-written.
testdir.tmpdir.join('hampkg').ensure(dir=1)
@@ -135,13 +136,22 @@ class TestImportHookInstallation:
'mainwrapper.py': """
import pytest, pkg_resources
plugin_state = "{plugin_state}"
class DummyDistInfo:
project_name = 'spam'
version = '1.0'
def _get_metadata(self, name):
return ['spamplugin.py,sha256=abc,123',
'hampkg/__init__.py,sha256=abc,123']
# 'RECORD' meta-data only available in installed plugins
if name == 'RECORD' and plugin_state == "installed":
return ['spamplugin.py,sha256=abc,123',
'hampkg/__init__.py,sha256=abc,123']
# 'SOURCES.txt' meta-data only available for plugins in development mode
elif name == 'SOURCES.txt' and plugin_state == "development":
return ['spamplugin.py',
'hampkg/__init__.py']
return []
class DummyEntryPoint:
name = 'spam'
@@ -159,7 +169,7 @@ class TestImportHookInstallation:
pkg_resources.iter_entry_points = iter_entry_points
pytest.main()
""",
""".format(plugin_state=plugin_state),
'test_foo.py': """
def test(check_first):
check_first([10, 30], 30)
@@ -854,3 +864,15 @@ def test_assert_with_unicode(monkeypatch, testdir):
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines(['*AssertionError*'])
def test_issue_1944(testdir):
testdir.makepyfile("""
def f():
return
assert f() == 10
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines(["*1 error*"])
assert "AttributeError: 'Module' object has no attribute '_obj'" not in result.stdout.str()

11
tox.ini
View File

@@ -10,8 +10,8 @@ envlist=
[testenv]
commands= pytest --lsof -rfsxX {posargs:testing}
passenv = USER USERNAME
deps=
hypothesis
deps=
hypothesis>=3.5.2
nose
mock
requests
@@ -47,7 +47,7 @@ commands = flake8 pytest.py _pytest testing
deps=pytest-xdist>=1.13
mock
nose
hypothesis
hypothesis>=3.5.2
commands=
pytest -n1 -rfsxX {posargs:testing}
@@ -71,8 +71,9 @@ commands=
pytest -rfsxX test_pdb.py test_terminal.py test_unittest.py
[testenv:py27-nobyte]
deps=pytest-xdist>=1.13
hypothesis
deps=
pytest-xdist>=1.13
hypothesis>=3.5.2
distribute=true
setenv=
PYTHONDONTWRITEBYTECODE=1