From a6282b5c6770a5215d77487ede7f6d339222c71b Mon Sep 17 00:00:00 2001 From: Robbins Date: Fri, 28 Sep 2018 13:00:30 -0700 Subject: [PATCH 01/20] added changes to runner.py --- src/_pytest/runner.py | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 1ba9ff310b7..8302d15c736 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -335,9 +335,44 @@ def teardown_all(self): self._teardown_with_finalization(key) assert not self._finalizers + def _callfinalizer(self,colitem,finalizer_index): + exc = None + fin = self._finalizers[colitem].pop(finalizer_index) + try: + fin() + except TEST_OUTCOM: + if exc is None: + exc = sys.exc_info() + if exc: + six.reaise(*exc) + + def _teardown_to_finalizer(self,colitem_index,finalizer_index): + colitem = self.stack[colitem_index] + finalizer = self._finalizers[colitem][finalizer_index] + while self.stack[colitem_index+1:] != []: + self._pop_and_teardown() + while finalizer in self._finalizers[colitem]: + self._callfinalizer(colitem,finalizer_index) + if len(self._finalizers[colitem]) == 0: + self._teardown_with_finalization(colitem) + def teardown_exact(self, item, nextitem): - needed_collectors = nextitem and nextitem.listchain() or [] - self._teardown_towards(needed_collectors) + for colitem_index in range(len(item.listchain())-1,-1,-1): + colitem = item.listchain()[colitem_index] + if nextitem is None: + self.teardown_all() + break + elif colitem not in nextitem.listchain(): + while colitem in self.stack: + self._pop_and_teardown() + elif colitem in self._finalizers.keys(): + for finalizer_index in range(len(self._finalizers[colitem])-1,-1,-1): + finalizer = self._finalizers[colitem][finalizer_index] + finalizer_fix_name = finalizer.keywords['request'].fixturename + if finalizer_fix_name not in nextitem.fixturenames: + self._teardown_to_finalizer(colitem_index,finalizer_index) + elif finalizer_fix_name in nextitem.fixturenames and item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name]: + self._teardown_to_finalizer(colitem_index,finalizer_index) def _teardown_towards(self, needed_collectors): exc = None From 1778f68213c9c41535f48cf9bf0248a7ff02ce32 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 13:17:12 -0700 Subject: [PATCH 02/20] Create 4038.bugfix.rst --- changelog/4038.bugfix.rst | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/4038.bugfix.rst diff --git a/changelog/4038.bugfix.rst b/changelog/4038.bugfix.rst new file mode 100644 index 00000000000..372be13f327 --- /dev/null +++ b/changelog/4038.bugfix.rst @@ -0,0 +1,5 @@ +Changes teardown behavior for parameterized fixtures as follows: + +1. Teardown code will be called from within the pytest_runtest_teardown hook. +2. If a fixture is parameterized and the next item requires the next index, all lower scoped fixtures are torn down. +3. If a fixture of equal scope needs to be torn down and the next item requires the next index, all fixtures that were setup after the fixture are torn down, but not fixtures of equal scope that were set up earlier. From 83e94341f344a24d889f48afeeaf9f8a96788945 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 13:26:28 -0700 Subject: [PATCH 03/20] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 2be74441a27..0a6fc96fa96 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,6 +15,7 @@ Anatoly Bubenkoff Anders Hovmöller Andras Tim Andreas Zeidler +Andrew Robbins Andrzej Ostrowski Andy Freeland Anthon van der Neut From 9b2987f127b1213b8a0d91e5130bfdab2078d4db Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 13:34:29 -0700 Subject: [PATCH 04/20] Document changes to teardown_exact method --- changelog/4038.bugfix.rst | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/4038.bugfix.rst diff --git a/changelog/4038.bugfix.rst b/changelog/4038.bugfix.rst new file mode 100644 index 00000000000..372be13f327 --- /dev/null +++ b/changelog/4038.bugfix.rst @@ -0,0 +1,5 @@ +Changes teardown behavior for parameterized fixtures as follows: + +1. Teardown code will be called from within the pytest_runtest_teardown hook. +2. If a fixture is parameterized and the next item requires the next index, all lower scoped fixtures are torn down. +3. If a fixture of equal scope needs to be torn down and the next item requires the next index, all fixtures that were setup after the fixture are torn down, but not fixtures of equal scope that were set up earlier. From ae7878f7df98e908474e4aeac56f25375b2b9db5 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 13:35:11 -0700 Subject: [PATCH 05/20] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 2be74441a27..0a6fc96fa96 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,6 +15,7 @@ Anatoly Bubenkoff Anders Hovmöller Andras Tim Andreas Zeidler +Andrew Robbins Andrzej Ostrowski Andy Freeland Anthon van der Neut From 1f0f9ca18d4c04715ad979c5cc0970fee1299c2c Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 15:03:46 -0700 Subject: [PATCH 06/20] Update runner.py --- src/_pytest/runner.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 8302d15c736..7a6965b7323 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -371,8 +371,13 @@ def teardown_exact(self, item, nextitem): finalizer_fix_name = finalizer.keywords['request'].fixturename if finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) - elif finalizer_fix_name in nextitem.fixturenames and item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name]: - self._teardown_to_finalizer(colitem_index,finalizer_index) + elif finalizer_fix_name in nextitem.fixturenames: + if not hasattr(item,'callspec') and not hasattr(item,'callspec'): + pass + if ( hasattr(item,'callspec') and not hasattr(item,'callspec') ) or \ + ( not hasattr(item,'callspec') and hasattr(item,'callspec') ) or \ + ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): + self._teardown_to_finalizer(colitem_index,finalizer_index) def _teardown_towards(self, needed_collectors): exc = None From 3b8b9d3f630d12d28b356df6c74d69ae4eed39af Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 15:21:33 -0700 Subject: [PATCH 07/20] Update runner.py --- src/_pytest/runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 7a6965b7323..05b276b0946 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -372,10 +372,10 @@ def teardown_exact(self, item, nextitem): if finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) elif finalizer_fix_name in nextitem.fixturenames: - if not hasattr(item,'callspec') and not hasattr(item,'callspec'): + if not hasattr(item,'callspec') and not hasattr(nextitem,'callspec'): pass - if ( hasattr(item,'callspec') and not hasattr(item,'callspec') ) or \ - ( not hasattr(item,'callspec') and hasattr(item,'callspec') ) or \ + if ( hasattr(item,'callspec') and not hasattr(nextitem,'callspec') ) or \ + ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): self._teardown_to_finalizer(colitem_index,finalizer_index) From f408ce1724cb13cc928ffa8d92d5ffa7ace1e03a Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 16:26:58 -0700 Subject: [PATCH 08/20] Update runner.py --- src/_pytest/runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 05b276b0946..09fb33a8b6b 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -374,9 +374,9 @@ def teardown_exact(self, item, nextitem): elif finalizer_fix_name in nextitem.fixturenames: if not hasattr(item,'callspec') and not hasattr(nextitem,'callspec'): pass - if ( hasattr(item,'callspec') and not hasattr(nextitem,'callspec') ) or \ - ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ - ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): + elif ( hasattr(item,'callspec') and not hasattr(nextitem,'callspec') ) or \ + ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ + ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): self._teardown_to_finalizer(colitem_index,finalizer_index) def _teardown_towards(self, needed_collectors): From 30973c0b4fe288721e12408dfd10cbfd82d0168d Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 16:49:20 -0700 Subject: [PATCH 09/20] Update runner.py --- src/_pytest/runner.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 09fb33a8b6b..bbb10b60b6c 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -368,15 +368,17 @@ def teardown_exact(self, item, nextitem): elif colitem in self._finalizers.keys(): for finalizer_index in range(len(self._finalizers[colitem])-1,-1,-1): finalizer = self._finalizers[colitem][finalizer_index] + if 'request' not in finalizer.keywords.keys(): continue finalizer_fix_name = finalizer.keywords['request'].fixturename + if 'tmpdir_factory' == finalizer_fix_name: continue if finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) elif finalizer_fix_name in nextitem.fixturenames: if not hasattr(item,'callspec') and not hasattr(nextitem,'callspec'): pass elif ( hasattr(item,'callspec') and not hasattr(nextitem,'callspec') ) or \ - ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ - ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): + ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ + ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): self._teardown_to_finalizer(colitem_index,finalizer_index) def _teardown_towards(self, needed_collectors): From 62afc29597174fed2ac16de6b063efc2201a5774 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 17:03:00 -0700 Subject: [PATCH 10/20] Update runner.py --- src/_pytest/runner.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index bbb10b60b6c..719f43e455a 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -368,14 +368,15 @@ def teardown_exact(self, item, nextitem): elif colitem in self._finalizers.keys(): for finalizer_index in range(len(self._finalizers[colitem])-1,-1,-1): finalizer = self._finalizers[colitem][finalizer_index] - if 'request' not in finalizer.keywords.keys(): continue + if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys(): continue finalizer_fix_name = finalizer.keywords['request'].fixturename - if 'tmpdir_factory' == finalizer_fix_name: continue if finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) elif finalizer_fix_name in nextitem.fixturenames: if not hasattr(item,'callspec') and not hasattr(nextitem,'callspec'): pass + elif 'tmpdir_factory' == finalizer_fix_name: + continue elif ( hasattr(item,'callspec') and not hasattr(nextitem,'callspec') ) or \ ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): From 8bb554b11b55b064fba5cceca9f76f259fd9e7b2 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 17:16:40 -0700 Subject: [PATCH 11/20] Update runner.py --- src/_pytest/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 719f43e455a..4193c0a16af 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -368,7 +368,7 @@ def teardown_exact(self, item, nextitem): elif colitem in self._finalizers.keys(): for finalizer_index in range(len(self._finalizers[colitem])-1,-1,-1): finalizer = self._finalizers[colitem][finalizer_index] - if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys(): continue + if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys() or not hasattr(finalizer.keywords['request'],'fixturename'): continue finalizer_fix_name = finalizer.keywords['request'].fixturename if finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) From b8992db3b87ad6b38a492ed29067f982b5667877 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Fri, 28 Sep 2018 17:44:40 -0700 Subject: [PATCH 12/20] Update runner.py --- src/_pytest/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 4193c0a16af..fb84bee5837 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -359,7 +359,7 @@ def _teardown_to_finalizer(self,colitem_index,finalizer_index): def teardown_exact(self, item, nextitem): for colitem_index in range(len(item.listchain())-1,-1,-1): colitem = item.listchain()[colitem_index] - if nextitem is None: + if nextitem is None or not hasattr(nextitem,'fixturenames'): self.teardown_all() break elif colitem not in nextitem.listchain(): From 83749572a6a19adc2c069b3eba12d64027e5adaa Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 14:12:11 -0700 Subject: [PATCH 13/20] Update runner.py --- src/_pytest/runner.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index fb84bee5837..5e398841418 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -356,10 +356,19 @@ def _teardown_to_finalizer(self,colitem_index,finalizer_index): if len(self._finalizers[colitem]) == 0: self._teardown_with_finalization(colitem) + def _get_fixture_index(self,item_object,finalizer_fix_name): + if not hasattr(item_object,'callspec'): + return None + if not hasattr(item_object.callspec,'indices'): + return None + if finalizer_fix_name not in item_object.callspec.indices: + return None + return item_object.callspec.indices[finalizer_fix_name] + def teardown_exact(self, item, nextitem): for colitem_index in range(len(item.listchain())-1,-1,-1): colitem = item.listchain()[colitem_index] - if nextitem is None or not hasattr(nextitem,'fixturenames'): + if nextitem is None: self.teardown_all() break elif colitem not in nextitem.listchain(): @@ -368,18 +377,13 @@ def teardown_exact(self, item, nextitem): elif colitem in self._finalizers.keys(): for finalizer_index in range(len(self._finalizers[colitem])-1,-1,-1): finalizer = self._finalizers[colitem][finalizer_index] - if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys() or not hasattr(finalizer.keywords['request'],'fixturename'): continue + if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys() or not hasattr(finalizer.keywords['request'],'fixturename'): + continue finalizer_fix_name = finalizer.keywords['request'].fixturename if finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) elif finalizer_fix_name in nextitem.fixturenames: - if not hasattr(item,'callspec') and not hasattr(nextitem,'callspec'): - pass - elif 'tmpdir_factory' == finalizer_fix_name: - continue - elif ( hasattr(item,'callspec') and not hasattr(nextitem,'callspec') ) or \ - ( not hasattr(item,'callspec') and hasattr(nextitem,'callspec') ) or \ - ( item.callspec.indices[finalizer_fix_name] != nextitem.callspec.indices[finalizer_fix_name] ): + if self._get_fixture_index(item,finalizer_fix_name) != self._get_fixture_index(nextitem,finalizer_fix_name): self._teardown_to_finalizer(colitem_index,finalizer_index) def _teardown_towards(self, needed_collectors): From 33230a4d61012612adf1650be80195dd43ece836 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 14:30:29 -0700 Subject: [PATCH 14/20] Update runner.py --- src/_pytest/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 5e398841418..be56566ae2a 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -380,7 +380,7 @@ def teardown_exact(self, item, nextitem): if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys() or not hasattr(finalizer.keywords['request'],'fixturename'): continue finalizer_fix_name = finalizer.keywords['request'].fixturename - if finalizer_fix_name not in nextitem.fixturenames: + if not hasattr(nextitem,'fixturenames') or finalizer_fix_name not in nextitem.fixturenames: self._teardown_to_finalizer(colitem_index,finalizer_index) elif finalizer_fix_name in nextitem.fixturenames: if self._get_fixture_index(item,finalizer_fix_name) != self._get_fixture_index(nextitem,finalizer_fix_name): From 773b5891f226018f3bd8dc1b15164add2f73446b Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 15:50:27 -0700 Subject: [PATCH 15/20] Update runner.py --- src/_pytest/runner.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index be56566ae2a..43624b46359 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -336,15 +336,12 @@ def teardown_all(self): assert not self._finalizers def _callfinalizer(self,colitem,finalizer_index): - exc = None fin = self._finalizers[colitem].pop(finalizer_index) try: fin() except TEST_OUTCOM: - if exc is None: - exc = sys.exc_info() - if exc: - six.reaise(*exc) + if self.exc is None: + self.exc = sys.exc_info() def _teardown_to_finalizer(self,colitem_index,finalizer_index): colitem = self.stack[colitem_index] @@ -366,10 +363,11 @@ def _get_fixture_index(self,item_object,finalizer_fix_name): return item_object.callspec.indices[finalizer_fix_name] def teardown_exact(self, item, nextitem): + self.exc = None for colitem_index in range(len(item.listchain())-1,-1,-1): colitem = item.listchain()[colitem_index] if nextitem is None: - self.teardown_all() + self._teardown_towards([]) break elif colitem not in nextitem.listchain(): while colitem in self.stack: @@ -385,7 +383,9 @@ def teardown_exact(self, item, nextitem): elif finalizer_fix_name in nextitem.fixturenames: if self._get_fixture_index(item,finalizer_fix_name) != self._get_fixture_index(nextitem,finalizer_fix_name): self._teardown_to_finalizer(colitem_index,finalizer_index) - + if self.exc: + six.reraise(*self.exc) + def _teardown_towards(self, needed_collectors): exc = None while self.stack: From 38a9ea4ee2b8b3c11112ddebca2392ba39cea5fd Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 16:23:25 -0700 Subject: [PATCH 16/20] Update runner.py --- src/_pytest/runner.py | 44 ++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 43624b46359..8cfc2440b5c 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -334,8 +334,7 @@ def teardown_all(self): for key in list(self._finalizers): self._teardown_with_finalization(key) assert not self._finalizers - - def _callfinalizer(self,colitem,finalizer_index): + def _callfinalizer(self, colitem, finalizer_index): fin = self._finalizers[colitem].pop(finalizer_index) try: fin() @@ -343,20 +342,20 @@ def _callfinalizer(self,colitem,finalizer_index): if self.exc is None: self.exc = sys.exc_info() - def _teardown_to_finalizer(self,colitem_index,finalizer_index): + def _teardown_to_finalizer(self, colitem_index, finalizer_index): colitem = self.stack[colitem_index] finalizer = self._finalizers[colitem][finalizer_index] - while self.stack[colitem_index+1:] != []: + while self.stack[colitem_index + 1 :] != []: self._pop_and_teardown() while finalizer in self._finalizers[colitem]: - self._callfinalizer(colitem,finalizer_index) + self._callfinalizer(colitem, finalizer_index) if len(self._finalizers[colitem]) == 0: self._teardown_with_finalization(colitem) - def _get_fixture_index(self,item_object,finalizer_fix_name): - if not hasattr(item_object,'callspec'): + def _get_fixture_index(self, item_object, finalizer_fix_name): + if not hasattr(item_object, "callspec"): return None - if not hasattr(item_object.callspec,'indices'): + if not hasattr(item_object.callspec, "indices"): return None if finalizer_fix_name not in item_object.callspec.indices: return None @@ -364,7 +363,7 @@ def _get_fixture_index(self,item_object,finalizer_fix_name): def teardown_exact(self, item, nextitem): self.exc = None - for colitem_index in range(len(item.listchain())-1,-1,-1): + for colitem_index in range(len(item.listchain()) - 1, -1, -1): colitem = item.listchain()[colitem_index] if nextitem is None: self._teardown_towards([]) @@ -373,18 +372,29 @@ def teardown_exact(self, item, nextitem): while colitem in self.stack: self._pop_and_teardown() elif colitem in self._finalizers.keys(): - for finalizer_index in range(len(self._finalizers[colitem])-1,-1,-1): + for finalizer_index in range( + len(self._finalizers[colitem]) - 1, -1, -1 + ): finalizer = self._finalizers[colitem][finalizer_index] - if not hasattr(finalizer,'keywords') or 'request' not in finalizer.keywords.keys() or not hasattr(finalizer.keywords['request'],'fixturename'): + if ( + not hasattr(finalizer, "keywords") + or "request" not in finalizer.keywords.keys() + or not hasattr(finalizer.keywords["request"], "fixturename") + ): continue - finalizer_fix_name = finalizer.keywords['request'].fixturename - if not hasattr(nextitem,'fixturenames') or finalizer_fix_name not in nextitem.fixturenames: - self._teardown_to_finalizer(colitem_index,finalizer_index) + finalizer_fix_name = finalizer.keywords["request"].fixturename + if ( + not hasattr(nextitem, "fixturenames") + or finalizer_fix_name not in nextitem.fixturenames + ): + self._teardown_to_finalizer(colitem_index, finalizer_index) elif finalizer_fix_name in nextitem.fixturenames: - if self._get_fixture_index(item,finalizer_fix_name) != self._get_fixture_index(nextitem,finalizer_fix_name): - self._teardown_to_finalizer(colitem_index,finalizer_index) + if self._get_fixture_index( + item, finalizer_fix_name + ) != self._get_fixture_index(nextitem, finalizer_fix_name): + self._teardown_to_finalizer(colitem_index, finalizer_index) if self.exc: - six.reraise(*self.exc) + six.reaise(*self.exc) def _teardown_towards(self, needed_collectors): exc = None From b8c845d3223f7e291f1d4435cb8e1824121f9d39 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 16:33:51 -0700 Subject: [PATCH 17/20] Update runner.py --- src/_pytest/runner.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 8cfc2440b5c..ccacfcac365 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -334,6 +334,7 @@ def teardown_all(self): for key in list(self._finalizers): self._teardown_with_finalization(key) assert not self._finalizers + def _callfinalizer(self, colitem, finalizer_index): fin = self._finalizers[colitem].pop(finalizer_index) try: @@ -394,7 +395,7 @@ def teardown_exact(self, item, nextitem): ) != self._get_fixture_index(nextitem, finalizer_fix_name): self._teardown_to_finalizer(colitem_index, finalizer_index) if self.exc: - six.reaise(*self.exc) + six.reraise(*self.exc) def _teardown_towards(self, needed_collectors): exc = None From bc77e13b41bf0c8aacd74afcf1b54f412e99845c Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 16:42:59 -0700 Subject: [PATCH 18/20] Update runner.py --- src/_pytest/runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index ccacfcac365..2ff3d1618f0 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -327,14 +327,14 @@ def _teardown_with_finalization(self, colitem): assert ( colitem is None or colitem in self.stack or isinstance(colitem, tuple) ) - + def teardown_all(self): while self.stack: self._pop_and_teardown() for key in list(self._finalizers): self._teardown_with_finalization(key) assert not self._finalizers - + def _callfinalizer(self, colitem, finalizer_index): fin = self._finalizers[colitem].pop(finalizer_index) try: @@ -396,7 +396,7 @@ def teardown_exact(self, item, nextitem): self._teardown_to_finalizer(colitem_index, finalizer_index) if self.exc: six.reraise(*self.exc) - + def _teardown_towards(self, needed_collectors): exc = None while self.stack: From 84e56db6004d24d24d13ab4f5b5d187abb61e02d Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 16:50:04 -0700 Subject: [PATCH 19/20] Update runner.py --- src/_pytest/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 2ff3d1618f0..515cb5a4254 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -327,7 +327,7 @@ def _teardown_with_finalization(self, colitem): assert ( colitem is None or colitem in self.stack or isinstance(colitem, tuple) ) - + def teardown_all(self): while self.stack: self._pop_and_teardown() From 5f3278640d1d8a41a990d19f92d9afef83a61610 Mon Sep 17 00:00:00 2001 From: arobbins805 Date: Sat, 29 Sep 2018 16:58:27 -0700 Subject: [PATCH 20/20] Update runner.py --- src/_pytest/runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 515cb5a4254..db04ee45932 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -339,7 +339,7 @@ def _callfinalizer(self, colitem, finalizer_index): fin = self._finalizers[colitem].pop(finalizer_index) try: fin() - except TEST_OUTCOM: + except TEST_OUTCOME: if self.exc is None: self.exc = sys.exc_info()