9
9
import os
10
10
import sys
11
11
import warnings
12
+ from functools import partial
12
13
from textwrap import dedent
13
14
14
15
import py
@@ -435,9 +436,66 @@ def _getobj(self):
435
436
return self ._importtestmodule ()
436
437
437
438
def collect (self ):
439
+ self ._inject_setup_module_fixture ()
440
+ self ._inject_setup_function_fixture ()
438
441
self .session ._fixturemanager .parsefactories (self )
439
442
return super (Module , self ).collect ()
440
443
444
+ def _inject_setup_module_fixture (self ):
445
+ # setup_method = _get_xunit_setup_teardown(
446
+ # self.obj, "setup_method", param_obj=self.obj
447
+ # )
448
+ setup_module = _get_xunit_func (self .obj , "setUpModule" )
449
+ if setup_module is None :
450
+ setup_module = _get_xunit_func (self .obj , "setup_module" )
451
+ # if setup_module is not None:
452
+ # setup_module()
453
+ teardown_module = _get_xunit_func (self .obj , "tearDownModule" )
454
+ if teardown_module is None :
455
+ teardown_module = _get_xunit_func (self .obj , "teardown_module" )
456
+ if setup_module is None and teardown_module is None :
457
+ return
458
+ # if teardown_module is not None:
459
+ # self.addfinalizer(teardown_module)
460
+
461
+ @fixtures .fixture (autouse = True , scope = "module" )
462
+ def xunit_setup_module_fixture (request ):
463
+ if setup_module is not None :
464
+ _call_with_optional_argument (setup_module , request .module )
465
+ # setup_method(request.instance, request.function)
466
+ yield
467
+ if teardown_module is not None :
468
+ _call_with_optional_argument (teardown_module , request .module )
469
+ # self.addfinalizer(lambda: fin_class(self.obj))
470
+
471
+ self .obj .__pytest_setup_module = xunit_setup_module_fixture
472
+
473
+ def _inject_setup_function_fixture (self ):
474
+ # setup_method = _get_xunit_setup_teardown(
475
+ # self.obj, "setup_method", param_obj=self.obj
476
+ # )
477
+ setup_function = _get_xunit_func (self .obj , "setup_function" )
478
+ teardown_function = _get_xunit_func (self .obj , "teardown_function" )
479
+ if setup_function is None and teardown_function is None :
480
+ return
481
+ # if teardown_module is not None:
482
+ # self.addfinalizer(teardown_module)
483
+
484
+ @fixtures .fixture (autouse = True , scope = "function" )
485
+ def xunit_setup_function_fixture (request ):
486
+ if request .instance is not None :
487
+ yield
488
+ return # we need to let setup_method take over
489
+ if setup_function is not None :
490
+ _call_with_optional_argument (setup_function , request .function )
491
+ # setup_method(request.instance, request.function)
492
+ yield
493
+ if teardown_function is not None :
494
+ _call_with_optional_argument (teardown_function , request .function )
495
+ # self.addfinalizer(lambda: fin_class(self.obj))
496
+
497
+ self .obj .__pytest_setup_function = xunit_setup_function_fixture
498
+
441
499
def _importtestmodule (self ):
442
500
# we assume we are only called once per module
443
501
importmode = self .config .getoption ("--import-mode" )
@@ -488,18 +546,19 @@ def _importtestmodule(self):
488
546
self .config .pluginmanager .consider_module (mod )
489
547
return mod
490
548
491
- def setup (self ):
492
- setup_module = _get_xunit_setup_teardown (self .obj , "setUpModule" )
493
- if setup_module is None :
494
- setup_module = _get_xunit_setup_teardown (self .obj , "setup_module" )
495
- if setup_module is not None :
496
- setup_module ()
497
-
498
- teardown_module = _get_xunit_setup_teardown (self .obj , "tearDownModule" )
499
- if teardown_module is None :
500
- teardown_module = _get_xunit_setup_teardown (self .obj , "teardown_module" )
501
- if teardown_module is not None :
502
- self .addfinalizer (teardown_module )
549
+ # def setup(self):
550
+ # return
551
+ # setup_module = _get_xunit_setup_teardown(self.obj, "setUpModule")
552
+ # if setup_module is None:
553
+ # setup_module = _get_xunit_setup_teardown(self.obj, "setup_module")
554
+ # if setup_module is not None:
555
+ # setup_module()
556
+ #
557
+ # teardown_module = _get_xunit_setup_teardown(self.obj, "tearDownModule")
558
+ # if teardown_module is None:
559
+ # teardown_module = _get_xunit_setup_teardown(self.obj, "teardown_module")
560
+ # if teardown_module is not None:
561
+ # self.addfinalizer(teardown_module)
503
562
504
563
505
564
class Package (Module ):
@@ -513,6 +572,22 @@ def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None):
513
572
self ._norecursepatterns = session ._norecursepatterns
514
573
self .fspath = fspath
515
574
575
+ def setup (self ):
576
+ # not using fixtures to call setup_module here because autouse fixtures
577
+ # from packages are not called automatically (#4085)
578
+ setup_module = _get_xunit_func (self .obj , "setUpModule" )
579
+ if setup_module is None :
580
+ setup_module = _get_xunit_func (self .obj , "setup_module" )
581
+ if setup_module is not None :
582
+ _call_with_optional_argument (setup_module , self .obj )
583
+
584
+ teardown_module = _get_xunit_func (self .obj , "tearDownModule" )
585
+ if teardown_module is None :
586
+ teardown_module = _get_xunit_func (self .obj , "teardown_module" )
587
+ if teardown_module is not None :
588
+ func = partial (_call_with_optional_argument , teardown_module , self .obj )
589
+ self .addfinalizer (func )
590
+
516
591
def _recurse (self , dirpath ):
517
592
if dirpath .basename == "__pycache__" :
518
593
return False
@@ -599,6 +674,7 @@ def _get_xunit_setup_teardown(holder, attr_name, param_obj=None):
599
674
when the callable is called without arguments, defaults to the ``holder`` object.
600
675
Return ``None`` if a suitable callable is not found.
601
676
"""
677
+ # TODO: only needed because of Package!
602
678
param_obj = param_obj if param_obj is not None else holder
603
679
result = _get_xunit_func (holder , attr_name )
604
680
if result is not None :
@@ -611,6 +687,16 @@ def _get_xunit_setup_teardown(holder, attr_name, param_obj=None):
611
687
return result
612
688
613
689
690
+ def _call_with_optional_argument (func , arg ):
691
+ arg_count = func .__code__ .co_argcount
692
+ if inspect .ismethod (func ):
693
+ arg_count -= 1
694
+ if arg_count :
695
+ func (arg )
696
+ else :
697
+ func ()
698
+
699
+
614
700
def _get_xunit_func (obj , name ):
615
701
"""Return the attribute from the given object to be used as a setup/teardown
616
702
xunit-style function, but only if not marked as a fixture to
@@ -643,18 +729,67 @@ def collect(self):
643
729
)
644
730
)
645
731
return []
732
+
733
+ self ._inject_setup_class_fixture ()
734
+ self ._inject_setup_method_fixture ()
735
+
646
736
return [Instance (name = "()" , parent = self )]
647
737
648
- def setup (self ):
738
+ def _inject_setup_class_fixture (self ):
739
+
649
740
setup_class = _get_xunit_func (self .obj , "setup_class" )
650
- if setup_class is not None :
651
- setup_class = getimfunc (setup_class )
652
- setup_class (self .obj )
741
+ teardown_class = getattr (self .obj , "teardown_class" , None )
742
+ if setup_class is None and teardown_class is None :
743
+ return
744
+
745
+ @fixtures .fixture (autouse = True , scope = "class" )
746
+ def xunit_setup_class_fixture (cls ):
747
+ if setup_class is not None :
748
+ func = getimfunc (setup_class )
749
+ _call_with_optional_argument (func , self .obj )
750
+ yield
751
+ if teardown_class is not None :
752
+ func = getimfunc (teardown_class )
753
+ _call_with_optional_argument (func , self .obj )
754
+ # self.addfinalizer(lambda: fin_class(self.obj))
755
+
756
+ self .obj .__pytest_setup_class = xunit_setup_class_fixture
757
+
758
+ def _inject_setup_method_fixture (self ):
759
+ # setup_method = _get_xunit_setup_teardown(
760
+ # self.obj, "setup_method", param_obj=self.obj
761
+ # )
762
+ setup_method = _get_xunit_func (self .obj , "setup_method" )
763
+ teardown_method = getattr (self .obj , "teardown_method" , None )
764
+ if setup_method is None and teardown_method is None :
765
+ return
653
766
654
- fin_class = getattr (self .obj , "teardown_class" , None )
655
- if fin_class is not None :
656
- fin_class = getimfunc (fin_class )
657
- self .addfinalizer (lambda : fin_class (self .obj ))
767
+ @fixtures .fixture (autouse = True , scope = "function" )
768
+ def xunit_setup_method_fixture (self , request ):
769
+ method = request .function
770
+ if setup_method is not None :
771
+ func = getattr (self , "setup_method" )
772
+ _call_with_optional_argument (func , method )
773
+ # setup_method(request.instance, request.function)
774
+ yield
775
+ if teardown_method is not None :
776
+ func = getattr (self , "teardown_method" )
777
+ _call_with_optional_argument (func , method )
778
+ # self.addfinalizer(lambda: fin_class(self.obj))
779
+
780
+ self .obj .__pytest_setup_method = xunit_setup_method_fixture
781
+
782
+ # def setup(self):
783
+ # return
784
+ # setup_class = _get_xunit_func(self.obj, "setup_class")
785
+ # if setup_class is not None:
786
+ # setup_class = getimfunc(setup_class)
787
+ # setup_class(self.obj)
788
+ #
789
+ # fin_class = getattr(self.obj, "teardown_class", None)
790
+ # if fin_class is not None:
791
+ # fin_class = getimfunc(fin_class)
792
+ # self.addfinalizer(lambda: fin_class(self.obj))
658
793
659
794
660
795
class Instance (PyCollector ):
@@ -681,29 +816,32 @@ class FunctionMixin(PyobjMixin):
681
816
682
817
def setup (self ):
683
818
""" perform setup for this test function. """
684
- if hasattr (self , "_preservedparent" ):
685
- obj = self ._preservedparent
686
- elif isinstance (self .parent , Instance ):
687
- obj = self .parent .newinstance ()
819
+ # if hasattr(self, "_preservedparent"):
820
+ # obj = self._preservedparent
821
+ # pass
822
+ if isinstance (self .parent , Instance ):
823
+ self .parent .newinstance ()
688
824
self .obj = self ._getobj ()
689
- else :
690
- obj = self .parent .obj
691
- if inspect .ismethod (self .obj ):
692
- setup_name = "setup_method"
693
- teardown_name = "teardown_method"
694
- else :
695
- setup_name = "setup_function"
696
- teardown_name = "teardown_function"
697
- setup_func_or_method = _get_xunit_setup_teardown (
698
- obj , setup_name , param_obj = self .obj
699
- )
700
- if setup_func_or_method is not None :
701
- setup_func_or_method ()
702
- teardown_func_or_method = _get_xunit_setup_teardown (
703
- obj , teardown_name , param_obj = self .obj
704
- )
705
- if teardown_func_or_method is not None :
706
- self .addfinalizer (teardown_func_or_method )
825
+ # else:
826
+ # obj = self.parent.obj
827
+ # if inspect.ismethod(self.obj):
828
+ # # setup_name = "setup_method"
829
+ # # teardown_name = "teardown_method"
830
+ # return
831
+ # else:
832
+ # setup_name = "setup_function"
833
+ # teardown_name = "teardown_function"
834
+ # return
835
+ # setup_func_or_method = _get_xunit_setup_teardown(
836
+ # obj, setup_name, param_obj=self.obj
837
+ # )
838
+ # if setup_func_or_method is not None:
839
+ # setup_func_or_method()
840
+ # teardown_func_or_method = _get_xunit_setup_teardown(
841
+ # obj, teardown_name, param_obj=self.obj
842
+ # )
843
+ # if teardown_func_or_method is not None:
844
+ # self.addfinalizer(teardown_func_or_method)
707
845
708
846
def _prunetraceback (self , excinfo ):
709
847
if hasattr (self , "_obj" ) and not self .config .option .fulltrace :
0 commit comments