Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/features' into features
Browse files Browse the repository at this point in the history
  • Loading branch information
ceridwen committed Mar 22, 2016
2 parents 4405dd0 + da10451 commit 1f46015
Show file tree
Hide file tree
Showing 40 changed files with 433 additions and 117 deletions.
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Thanks for submitting an issue!

Here's a quick checklist in what to include:

[ ] Include a detailed description of the bug or suggestion
[ ] `pip list` of the virtual environment you are using
[ ] py.test and operating system versions
[ ] Minimal example if possible
- [ ] Include a detailed description of the bug or suggestion
- [ ] `pip list` of the virtual environment you are using
- [ ] py.test and operating system versions
- [ ] Minimal example if possible
8 changes: 4 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Thanks for submitting a PR, your contribution is really appreciated!

Here's a quick checklist that should be present in PRs:

[ ] Target: for bug or doc fixes, target `master`; for new features, target `features`
[ ] Make sure to include one or more tests for your change
[ ] Add yourself to `AUTHORS`
[ ] Add a new entry to the `CHANGELOG` (choose any open position to avoid merge conflicts with other PRs)
- [ ] Target: for bug or doc fixes, target `master`; for new features, target `features`
- [ ] Make sure to include one or more tests for your change
- [ ] Add yourself to `AUTHORS`
- [ ] Add a new entry to the `CHANGELOG` (choose any open position to avoid merge conflicts with other PRs)
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Andy Freeland
Anthon van der Neut
Armin Rigo
Aron Curzon
Aviv Palivoda
Benjamin Peterson
Bob Ippolito
Brian Dorsey
Expand All @@ -23,6 +24,7 @@ Christian Theunert
Christian Tismer
Christopher Gilling
Daniel Grana
Daniel Hahler
Daniel Nuri
Dave Hunt
David Mohr
Expand Down Expand Up @@ -60,6 +62,7 @@ Marc Schlaich
Mark Abramowitz
Markus Unterwaditzer
Martijn Faassen
Matt Bachmann
Matt Williams
Michael Aquilina
Michael Birtwell
Expand Down
42 changes: 41 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
explicitly passed parametrize ids do not get escaped to ascii.
Thanks `@ceridwen`_ for the PR.

* parametrize ids can accept None as specific test id. The
automatically generated id for that argument will be used.

*

*
Expand All @@ -42,17 +45,54 @@
.. _#1454: https://github.com/pytest-dev/pytest/pull/1454


2.9.1.dev1
2.9.2.dev1
==========

**Bug Fixes**

* When receiving identical test ids in parametrize we generate unique test ids.

*

*

*


2.9.1
=====

**Bug Fixes**

* Improve error message when a plugin fails to load.
Thanks `@nicoddemus`_ for the PR.

* Fix (`#1178 <https://github.com/pytest-dev/pytest/issues/1178>`_):
``pytest.fail`` with non-ascii characters raises an internal pytest error.
Thanks `@nicoddemus`_ for the PR.

* Fix (`#469`_): junit parses report.nodeid incorrectly, when params IDs
contain ``::``. Thanks `@tomviner`_ for the PR (`#1431`_).

* Fix (`#578 <https://github.com/pytest-dev/pytest/issues/578>`_): SyntaxErrors
containing non-ascii lines at the point of failure generated an internal
py.test error.
Thanks `@asottile`_ for the report and `@nicoddemus`_ for the PR.

* Fix (`#1437`_): When passing in a bytestring regex pattern to parameterize
attempt to decode it as utf-8 ignoring errors.

* Fix (`#649`_): parametrized test nodes cannot be specified to run on the command line.


.. _#1437: https://github.com/pytest-dev/pytest/issues/1437
.. _#469: https://github.com/pytest-dev/pytest/issues/469
.. _#1431: https://github.com/pytest-dev/pytest/pull/1431
.. _#649: https://github.com/pytest-dev/pytest/issues/649

.. _@asottile: https://github.com/asottile


2.9.0
=====

Expand Down
1 change: 1 addition & 0 deletions _pytest/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#

__version__ = '2.10.0.dev1'
4 changes: 3 additions & 1 deletion _pytest/_code/_py2traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ def format_exception_only(etype, value):
filename = filename or "<string>"
lines.append(' File "%s", line %d\n' % (filename, lineno))
if badline is not None:
lines.append(' %s\n' % badline.strip())
if isinstance(badline, bytes): # python 2 only
badline = badline.decode('utf-8', 'replace')
lines.append(u' %s\n' % badline.strip())
if offset is not None:
caretspace = badline.rstrip('\n')[:offset].lstrip()
# non-space whitespace (likes tabs) must be kept for alignment
Expand Down
4 changes: 3 additions & 1 deletion _pytest/cacheprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ def pytest_sessionfinish(self, session):
config = self.config
if config.getvalue("cacheshow") or hasattr(config, "slaveinput"):
return
config.cache.set("cache/lastfailed", self.lastfailed)
prev_failed = config.cache.get("cache/lastfailed", None) is not None
if (session.testscollected and prev_failed) or self.lastfailed:
config.cache.set("cache/lastfailed", self.lastfailed)


def pytest_addoption(parser):
Expand Down
9 changes: 7 additions & 2 deletions _pytest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,13 @@ def import_plugin(self, modname):
importspec = modname
try:
__import__(importspec)
except ImportError:
raise
except ImportError as e:
new_exc = ImportError('Error importing plugin "%s": %s' % (modname, e))
# copy over name and path attributes
for attr in ('name', 'path'):
if hasattr(e, attr):
setattr(new_exc, attr, getattr(e, attr))
raise new_exc
except Exception as e:
import pytest
if not hasattr(pytest, 'skip') or not isinstance(e, pytest.skip.Exception):
Expand Down
17 changes: 7 additions & 10 deletions _pytest/hookspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,14 @@ def pytest_plugin_registered(plugin, manager):

@hookspec(historic=True)
def pytest_addoption(parser):
"""register argparse-style options and ini-style config values.
"""register argparse-style options and ini-style config values,
called once at the beginning of a test run.
.. warning::
.. note::
This function must be implemented in a :ref:`plugin <pluginorder>`
and is called once at the beginning of a test run.
Implementing this hook from ``conftest.py`` files is **strongly**
discouraged because ``conftest.py`` files are lazily loaded and
may give strange *unknown option* errors depending on the directory
``py.test`` is invoked from.
This function should be implemented only in plugins or ``conftest.py``
files situated at the tests root directory due to how py.test
:ref:`discovers plugins during startup <pluginorder>`.
:arg parser: To add command line options, call
:py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`.
Expand Down Expand Up @@ -84,7 +81,7 @@ def pytest_cmdline_main(config):
""" called for performing the main command line action. The default
implementation will invoke the configure hooks and runtest_mainloop. """

def pytest_load_initial_conftests(args, early_config, parser):
def pytest_load_initial_conftests(early_config, parser, args):
""" implements the loading of initial conftest files ahead
of command line option parsing. """

Expand Down
17 changes: 14 additions & 3 deletions _pytest/junitxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class Junit(py.xml.Namespace):
del _legal_ranges
del _legal_xml_re

_py_ext_re = re.compile(r"\.py$")


def bin_xml_escape(arg):
def repl(matchobj):
Expand Down Expand Up @@ -89,7 +91,7 @@ def make_properties_node(self):

def record_testreport(self, testreport):
assert not self.testcase
names = mangle_testnames(testreport.nodeid.split("::"))
names = mangle_test_address(testreport.nodeid)
classnames = names[:-1]
if self.xml.prefix:
classnames.insert(0, self.xml.prefix)
Expand Down Expand Up @@ -235,9 +237,18 @@ def pytest_unconfigure(config):
config.pluginmanager.unregister(xml)


def mangle_testnames(names):
names = [x.replace(".py", "") for x in names if x != '()']
def mangle_test_address(address):
path, possible_open_bracket, params = address.partition('[')
names = path.split("::")
try:
names.remove('()')
except ValueError:
pass
# convert file path to dotted path
names[0] = names[0].replace("/", '.')
names[0] = _py_ext_re.sub("", names[0])
# put any params back
names[-1] += possible_open_bracket + params
return names


Expand Down
3 changes: 2 additions & 1 deletion _pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,8 @@ def _matchnodes(self, matching, names):
if rep.passed:
has_matched = False
for x in rep.result:
if x.name == name:
# TODO: remove parametrized workaround once collection structure contains parametrization
if x.name == name or x.name.split("[")[0] == name:
resultnodes.extend(self.matchnodes([x], nextnames))
has_matched = True
# XXX accept IDs that don't have "()" for class instances
Expand Down
32 changes: 16 additions & 16 deletions _pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ def _prunetraceback(self, excinfo):
def _repr_failure_py(self, excinfo, style="long"):
if excinfo.errisinstance(pytest.fail.Exception):
if not excinfo.value.pytrace:
return str(excinfo.value)
return py._builtin._totext(excinfo.value)
return super(FunctionMixin, self)._repr_failure_py(excinfo,
style=style)

Expand Down Expand Up @@ -967,7 +967,8 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None,
:arg ids: list of string ids, or a callable.
If strings, each is corresponding to the argvalues so that they are
part of the test id.
part of the test id. If None is given as id of specific test, the
automatically generated id for that argument will be used.
If callable, it should take one argument (a single argvalue) and return
a string or return None. If None, the automatically generated id for that
argument will be used.
Expand Down Expand Up @@ -1025,14 +1026,10 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None,
if callable(ids):
idfn = ids
ids = None
if ids:
if len(ids) != len(argvalues):
raise ValueError('%d tests specified with %d ids' %(
len(argvalues), len(ids)))
else:
ids = [_escape_strings(i) for i in ids]
if not ids:
ids = idmaker(argnames, argvalues, idfn)
if ids and len(ids) != len(argvalues):
raise ValueError('%d tests specified with %d ids' %(
len(argvalues), len(ids)))
ids = idmaker(argnames, argvalues, idfn, ids)
newcalls = []
for callspec in self._calls or [CallSpec2(self)]:
for param_index, valset in enumerate(argvalues):
Expand Down Expand Up @@ -1153,13 +1150,16 @@ def _idval(val, argname, idx, idfn):
return val.__name__
return str(argname)+str(idx)

def _idvalset(idx, valset, argnames, idfn):
this_id = [_idval(val, argname, idx, idfn)
for val, argname in zip(valset, argnames)]
return "-".join(this_id)
def _idvalset(idx, valset, argnames, idfn, ids):
if ids is None or ids[idx] is None:
this_id = [_idval(val, argname, idx, idfn)
for val, argname in zip(valset, argnames)]
return "-".join(this_id)
else:
return _escape_strings(ids[idx])

def idmaker(argnames, argvalues, idfn=None):
ids = [_idvalset(valindex, valset, argnames, idfn)
def idmaker(argnames, argvalues, idfn=None, ids=None):
ids = [_idvalset(valindex, valset, argnames, idfn, ids)
for valindex, valset in enumerate(argvalues)]
if len(set(ids)) < len(ids):
# user may have provided a bad idfn which means the ids are not unique
Expand Down
5 changes: 4 additions & 1 deletion _pytest/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,10 @@ def __init__(self, msg=None, pytrace=True):

def __repr__(self):
if self.msg:
return str(self.msg)
val = self.msg
if isinstance(val, bytes):
val = py._builtin._totext(val, errors='replace')
return val
return "<%s instance>" %(self.__class__.__name__,)
__str__ = __repr__

Expand Down
65 changes: 65 additions & 0 deletions doc/en/announce/release-2.9.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
pytest-2.9.1
============

pytest is a mature Python testing tool with more than a 1100 tests
against itself, passing on many different interpreters and platforms.

See below for the changes and see docs at:

http://pytest.org

As usual, you can upgrade from pypi via::

pip install -U pytest

Thanks to all who contributed to this release, among them:

Bruno Oliveira
Daniel Hahler
Dmitry Malinovsky
Florian Bruhin
Floris Bruynooghe
Matt Bachmann
Ronny Pfannschmidt
TomV
Vladimir Bolshakov
Zearin
palaviv


Happy testing,
The py.test Development Team


2.9.1 (compared to 2.9.0)
-------------------------

**Bug Fixes**

* Improve error message when a plugin fails to load.
Thanks `@nicoddemus`_ for the PR.

* Fix (`#1178 <https://github.com/pytest-dev/pytest/issues/1178>`_):
``pytest.fail`` with non-ascii characters raises an internal pytest error.
Thanks `@nicoddemus`_ for the PR.

* Fix (`#469`_): junit parses report.nodeid incorrectly, when params IDs
contain ``::``. Thanks `@tomviner`_ for the PR (`#1431`_).

* Fix (`#578 <https://github.com/pytest-dev/pytest/issues/578>`_): SyntaxErrors
containing non-ascii lines at the point of failure generated an internal
py.test error.
Thanks `@asottile`_ for the report and `@nicoddemus`_ for the PR.

* Fix (`#1437`_): When passing in a bytestring regex pattern to parameterize
attempt to decode it as utf-8 ignoring errors.

* Fix (`#649`_): parametrized test nodes cannot be specified to run on the command line.


.. _#1437: https://github.com/pytest-dev/pytest/issues/1437
.. _#469: https://github.com/pytest-dev/pytest/issues/469
.. _#1431: https://github.com/pytest-dev/pytest/pull/1431
.. _#649: https://github.com/pytest-dev/pytest/issues/649

.. _@asottile: https://github.com/asottile
4 changes: 2 additions & 2 deletions doc/en/assert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ you will see the return value of the function call::

$ py.test test_assert1.py
======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
Expand Down Expand Up @@ -143,7 +143,7 @@ if you run this module::

$ py.test test_assert2.py
======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1
platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
Expand Down
Loading

0 comments on commit 1f46015

Please sign in to comment.