Merge remote-tracking branch 'upstream/master' into pastebin-py3
This commit is contained in:
		
						commit
						a54e4e64cd
					
				|  | @ -9,6 +9,12 @@ | |||
| - fix #1198: ``--pastebin`` option now works on Python 3. Thanks | ||||
|   Mehdy Khoshnoody for the PR. | ||||
| 
 | ||||
| - fix #1204: another error when collecting with a nasty __getattr__(). | ||||
|   Thanks Florian Bruhin for the PR. | ||||
| 
 | ||||
| - fix the summary printed when no tests did run. | ||||
|   Thanks Florian Bruhin for the PR. | ||||
| 
 | ||||
| 2.8.3 | ||||
| ----- | ||||
| 
 | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ tags: feature | |||
| 
 | ||||
| - introduce pytest.mark.nocollect for not considering a function for | ||||
|   test collection at all.  maybe also introduce a pytest.mark.test to | ||||
|   explicitely mark a function to become a tested one.  Lookup JUnit ways | ||||
|   explicitly mark a function to become a tested one.  Lookup JUnit ways | ||||
|   of tagging tests. | ||||
| 
 | ||||
| introduce pytest.mark.importorskip | ||||
|  |  | |||
|  | @ -384,12 +384,13 @@ class PyobjMixin(PyobjContext): | |||
|     def reportinfo(self): | ||||
|         # XXX caching? | ||||
|         obj = self.obj | ||||
|         if hasattr(obj, 'compat_co_firstlineno'): | ||||
|         compat_co_firstlineno = getattr(obj, 'compat_co_firstlineno', None) | ||||
|         if isinstance(compat_co_firstlineno, int): | ||||
|             # nose compatibility | ||||
|             fspath = sys.modules[obj.__module__].__file__ | ||||
|             if fspath.endswith(".pyc"): | ||||
|                 fspath = fspath[:-1] | ||||
|             lineno = obj.compat_co_firstlineno | ||||
|             lineno = compat_co_firstlineno | ||||
|         else: | ||||
|             fspath, lineno = getfslineno(obj) | ||||
|         modpath = self.getmodpath() | ||||
|  | @ -405,7 +406,10 @@ class PyCollector(PyobjMixin, pytest.Collector): | |||
|         """ Look for the __test__ attribute, which is applied by the | ||||
|         @nose.tools.istest decorator | ||||
|         """ | ||||
|         return safe_getattr(obj, '__test__', False) | ||||
|         # We explicitly check for "is True" here to not mistakenly treat | ||||
|         # classes with a custom __getattr__ returning something truthy (like a | ||||
|         # function) as test classes. | ||||
|         return safe_getattr(obj, '__test__', False) is True | ||||
| 
 | ||||
|     def classnamefilter(self, name): | ||||
|         return self._matches_prefix_or_glob_option('python_classes', name) | ||||
|  |  | |||
|  | @ -469,7 +469,7 @@ def skip(msg=""): | |||
| skip.Exception = Skipped | ||||
| 
 | ||||
| def fail(msg="", pytrace=True): | ||||
|     """ explicitely fail an currently-executing test with the given Message. | ||||
|     """ explicitly fail an currently-executing test with the given Message. | ||||
| 
 | ||||
|     :arg pytrace: if false the msg represents the full failure information | ||||
|                   and no python traceback will be reported. | ||||
|  |  | |||
|  | @ -544,7 +544,11 @@ def build_summary_stats_line(stats): | |||
|         if val: | ||||
|             key_name = key_translation.get(key, key) | ||||
|             parts.append("%d %s" % (len(val), key_name)) | ||||
|     line = ", ".join(parts) | ||||
| 
 | ||||
|     if parts: | ||||
|         line = ", ".join(parts) | ||||
|     else: | ||||
|         line = "no tests ran" | ||||
| 
 | ||||
|     if 'failed' in stats or 'error' in stats: | ||||
|         color = 'red' | ||||
|  |  | |||
|  | @ -573,7 +573,7 @@ class _MultiCall: | |||
| 
 | ||||
|     # XXX note that the __multicall__ argument is supported only | ||||
|     # for pytest compatibility reasons.  It was never officially | ||||
|     # supported there and is explicitely deprecated since 2.8 | ||||
|     # supported there and is explicitly 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. | ||||
| 
 | ||||
|  |  | |||
|  | @ -219,7 +219,7 @@ For an example on how to add and work with markers from a plugin, see | |||
| 
 | ||||
| .. note:: | ||||
| 
 | ||||
|     It is recommended to explicitely register markers so that: | ||||
|     It is recommended to explicitly register markers so that: | ||||
| 
 | ||||
|     * there is one place in your test suite defining your markers | ||||
| 
 | ||||
|  |  | |||
|  | @ -386,7 +386,7 @@ are expected. | |||
| 
 | ||||
| For an example, see `newhooks.py`_ from :ref:`xdist`. | ||||
| 
 | ||||
| .. _`newhooks.py`: https://bitbucket.org/pytest-dev/pytest-xdist/src/52082f70e7dd04b00361091b8af906c60fd6700f/xdist/newhooks.py?at=default | ||||
| .. _`newhooks.py`: https://github.com/pytest-dev/pytest-xdist/blob/974bd566c599dc6a9ea291838c6f226197208b46/xdist/newhooks.py | ||||
| 
 | ||||
| 
 | ||||
| Optionally using hooks from 3rd party plugins | ||||
|  |  | |||
|  | @ -880,6 +880,21 @@ class TestReportInfo: | |||
|                     pass | ||||
|        """ | ||||
| 
 | ||||
|     def test_reportinfo_with_nasty_getattr(self, testdir): | ||||
|         # https://github.com/pytest-dev/pytest/issues/1204 | ||||
|         modcol = testdir.getmodulecol(""" | ||||
|             # lineno 0 | ||||
|             class TestClass: | ||||
|                 def __getattr__(self, name): | ||||
|                     return "this is not an int" | ||||
| 
 | ||||
|                 def test_foo(self): | ||||
|                     pass | ||||
|         """) | ||||
|         classcol = testdir.collect_by_name(modcol, "TestClass") | ||||
|         instance = classcol.collect()[0] | ||||
|         fspath, lineno, msg = instance.reportinfo() | ||||
| 
 | ||||
| 
 | ||||
| def test_customized_python_discovery(testdir): | ||||
|     testdir.makeini(""" | ||||
|  |  | |||
|  | @ -283,6 +283,35 @@ class TestNoselikeTestAttribute: | |||
|         assert len(call.items) == 1 | ||||
|         assert call.items[0].cls.__name__ == "TC" | ||||
| 
 | ||||
|     def test_class_with_nasty_getattr(self, testdir): | ||||
|         """Make sure we handle classes with a custom nasty __getattr__ right. | ||||
| 
 | ||||
|         With a custom __getattr__ which e.g. returns a function (like with a | ||||
|         RPC wrapper), we shouldn't assume this meant "__test__ = True". | ||||
|         """ | ||||
|         # https://github.com/pytest-dev/pytest/issues/1204 | ||||
|         testdir.makepyfile(""" | ||||
|             class MetaModel(type): | ||||
| 
 | ||||
|                 def __getattr__(cls, key): | ||||
|                     return lambda: None | ||||
| 
 | ||||
| 
 | ||||
|             BaseModel = MetaModel('Model', (), {}) | ||||
| 
 | ||||
| 
 | ||||
|             class Model(BaseModel): | ||||
| 
 | ||||
|                 __metaclass__ = MetaModel | ||||
| 
 | ||||
|                 def test_blah(self): | ||||
|                     pass | ||||
|         """) | ||||
|         reprec = testdir.inline_run() | ||||
|         assert not reprec.getfailedcollections() | ||||
|         call = reprec.getcalls("pytest_collection_modifyitems")[0] | ||||
|         assert not call.items | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.issue351 | ||||
| class TestParameterize: | ||||
|  |  | |||
|  | @ -779,10 +779,10 @@ def test_terminal_summary(testdir): | |||
|     ("green", "1 passed, 1 xpassed", {"xpassed": (1,), "passed": (1,)}), | ||||
| 
 | ||||
|     # Likewise if no tests were found at all | ||||
|     ("yellow", "", {}), | ||||
|     ("yellow", "no tests ran", {}), | ||||
| 
 | ||||
|     # Test the empty-key special case | ||||
|     ("yellow", "", {"": (1,)}), | ||||
|     ("yellow", "no tests ran", {"": (1,)}), | ||||
|     ("green", "1 passed", {"": (1,), "passed": (1,)}), | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue