From fd8f92d0e706f4ec1d2a9815859e5e5189aaae18 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 14 Jul 2019 18:07:04 +0300 Subject: [PATCH 1/7] Run mypy on src/ and testing/ together This makes testing/ actually pick up the pytest imports -- otherwise they are opaque and we don't actually test the types. A single run is also a bit faster and simpler. The original reason why we split it is no longer relevant (we fixed the problems). --- .pre-commit-config.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fce7978c418..2b0d6e49f9c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,12 +47,7 @@ repos: rev: v0.711 hooks: - id: mypy - name: mypy (src) - files: ^src/ - args: [] - - id: mypy - name: mypy (testing) - files: ^testing/ + files: ^(src/|testing/) args: [] - repo: local hooks: From 104f8fc8364c66425191e3937708153f1ee154aa Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 14 Jul 2019 18:14:34 +0300 Subject: [PATCH 2/7] Update mypy from 0.711 to 0.720 Release notes: http://mypy-lang.blogspot.com/2019/07/mypy-0720-released.html --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2b0d6e49f9c..59128a4fb28 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,7 +44,7 @@ repos: hooks: - id: rst-backticks - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.711 + rev: v0.720 hooks: - id: mypy files: ^(src/|testing/) From 8d413c1926e489e49f0a1b4df92b071288ec5d2b Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Tue, 16 Jul 2019 23:25:13 +0300 Subject: [PATCH 3/7] Allow tuple of exceptions in ExceptionInfo.errisinstance isinstance() accepts it and some code does pass a tuple. Fixup for commit 55a570e5135cc8e08f242794b2b7a38677d81838. --- src/_pytest/_code/code.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 30ab0123565..7d72234e7cb 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -520,7 +520,9 @@ def exconly(self, tryshort: bool = False) -> str: text = text[len(self._striptext) :] return text - def errisinstance(self, exc: "Type[BaseException]") -> bool: + def errisinstance( + self, exc: Union["Type[BaseException]", Tuple["Type[BaseException]", ...]] + ) -> bool: """ return True if the exception is an instance of exc """ return isinstance(self.value, exc) From 65aee1e0c877def80e32b95be60f0edcb2cb7d5c Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 14 Jul 2019 18:27:09 +0300 Subject: [PATCH 4/7] Allow bytes for OutcomeException(msg=...) It's __repr__ explicitly handles it so allow it. --- src/_pytest/outcomes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index aaf0b35fbb2..df37312ba15 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -5,6 +5,7 @@ import sys from typing import Any from typing import Optional +from typing import Union from packaging.version import Version @@ -17,7 +18,9 @@ class OutcomeException(BaseException): contain info about test and collection outcomes. """ - def __init__(self, msg: Optional[str] = None, pytrace: bool = True) -> None: + def __init__( + self, msg: Optional[Union[str, bytes]] = None, pytrace: bool = True + ) -> None: BaseException.__init__(self, msg) self.msg = msg self.pytrace = pytrace From 7d1c697c306929e5a02dd34268dba865dfdd33b6 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 14 Jul 2019 18:26:05 +0300 Subject: [PATCH 5/7] Remove a no-longer-needed check if enum is available Not needed since 4d49ba65297102110ae8aeecdb3b82b23a231fba. --- src/_pytest/python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 8e5a022922b..82ed8b9cf18 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1164,7 +1164,7 @@ def _idval(val, argname, idx, idfn, item, config): return str(val) elif isinstance(val, REGEX_TYPE): return ascii_escaped(val.pattern) - elif enum is not None and isinstance(val, enum.Enum): + elif isinstance(val, enum.Enum): return str(val) elif (inspect.isclass(val) or inspect.isfunction(val)) and hasattr(val, "__name__"): return val.__name__ From 0b532fda76813ae4793669be5c439f8075bfd9ff Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Mon, 15 Jul 2019 22:09:01 +0300 Subject: [PATCH 6/7] Remove unnecessary checks from SetupState Since 4622c28ffdd10ff3b3e7c9d4c59ab7c0d1284cc3, _finalizers cannot contain Nones or tuples, so these checks are not longer needed. --- src/_pytest/runner.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index edaee9725a3..8aae163c3d0 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -278,10 +278,7 @@ def __init__(self): self._finalizers = {} def addfinalizer(self, finalizer, colitem): - """ attach a finalizer to the given colitem. - if colitem is None, this will add a finalizer that - is called at the end of teardown_all(). - """ + """ attach a finalizer to the given colitem. """ assert colitem and not isinstance(colitem, tuple) assert callable(finalizer) # assert colitem in self.stack # some unit tests don't setup stack :/ @@ -309,12 +306,9 @@ def _callfinalizers(self, colitem): def _teardown_with_finalization(self, colitem): self._callfinalizers(colitem) - if hasattr(colitem, "teardown"): - colitem.teardown() + colitem.teardown() for colitem in self._finalizers: - assert ( - colitem is None or colitem in self.stack or isinstance(colitem, tuple) - ) + assert colitem in self.stack def teardown_all(self): while self.stack: From 675e9507d80fc477d416d38781e6bccc8bb5c0c2 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Wed, 17 Jul 2019 10:33:10 +0300 Subject: [PATCH 7/7] Don't accept bytes message in pytest.{fail,xfail,skip} It seems to have been added in #1439 to fix #1178. This was only relevant for Python 2 where it was tempting to use str (== bytes) literals instead of unicode literals. In Python 3, it is unlikely that anyone passes bytes to these functions. --- changelog/5615.removal.rst | 7 +++++++ src/_pytest/outcomes.py | 10 ++-------- 2 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 changelog/5615.removal.rst diff --git a/changelog/5615.removal.rst b/changelog/5615.removal.rst new file mode 100644 index 00000000000..6dd9aec1de5 --- /dev/null +++ b/changelog/5615.removal.rst @@ -0,0 +1,7 @@ +``pytest.fail``, ``pytest.xfail`` and ``pytest.skip`` no longer support bytes for the message argument. + +This was supported for Python 2 where it was tempting to use ``"message"`` +instead of ``u"message"``. + +Python 3 code is unlikely to pass ``bytes`` to these functions. If you do, +please decode it to an ``str`` beforehand. diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index df37312ba15..a5a4e655b0e 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -5,7 +5,6 @@ import sys from typing import Any from typing import Optional -from typing import Union from packaging.version import Version @@ -18,19 +17,14 @@ class OutcomeException(BaseException): contain info about test and collection outcomes. """ - def __init__( - self, msg: Optional[Union[str, bytes]] = None, pytrace: bool = True - ) -> None: + def __init__(self, msg: Optional[str] = None, pytrace: bool = True) -> None: BaseException.__init__(self, msg) self.msg = msg self.pytrace = pytrace def __repr__(self) -> str: if self.msg: - val = self.msg - if isinstance(val, bytes): - val = val.decode("UTF-8", errors="replace") - return val + return self.msg return "<{} instance>".format(self.__class__.__name__) __str__ = __repr__