13
13
import types
14
14
import warnings
15
15
16
+ import attr
16
17
import py
17
18
import six
18
19
from packaging .version import Version
35
36
from _pytest .compat import safe_str
36
37
from _pytest .outcomes import fail
37
38
from _pytest .outcomes import Skipped
39
+ from _pytest .pathlib import Path
38
40
from _pytest .warning_types import PytestConfigWarning
39
41
40
42
hookimpl = HookimplMarker ("pytest" )
@@ -154,10 +156,15 @@ def directory_arg(path, optname):
154
156
builtin_plugins .add ("pytester" )
155
157
156
158
157
- def get_config (args = None ):
159
+ def get_config (args = None , plugins = None ):
158
160
# subsequent calls to main will create a fresh instance
159
161
pluginmanager = PytestPluginManager ()
160
- config = Config (pluginmanager )
162
+ config = Config (
163
+ pluginmanager ,
164
+ invocation_params = Config .InvocationParams (
165
+ args = args , plugins = plugins , dir = Path ().resolve ()
166
+ ),
167
+ )
161
168
162
169
if args is not None :
163
170
# Handle any "-p no:plugin" args.
@@ -190,7 +197,7 @@ def _prepareconfig(args=None, plugins=None):
190
197
msg = "`args` parameter expected to be a list or tuple of strings, got: {!r} (type: {})"
191
198
raise TypeError (msg .format (args , type (args )))
192
199
193
- config = get_config (args )
200
+ config = get_config (args , plugins )
194
201
pluginmanager = config .pluginmanager
195
202
try :
196
203
if plugins :
@@ -686,13 +693,52 @@ def _iter_rewritable_modules(package_files):
686
693
687
694
688
695
class Config (object ):
689
- """ access to configuration values, pluginmanager and plugin hooks. """
696
+ """
697
+ Access to configuration values, pluginmanager and plugin hooks.
698
+
699
+ :ivar PytestPluginManager pluginmanager: the plugin manager handles plugin registration and hook invocation.
700
+
701
+ :ivar argparse.Namespace option: access to command line option as attributes.
702
+
703
+ :ivar InvocationParams invocation_params:
704
+
705
+ Object containing the parameters regarding the ``pytest.main``
706
+ invocation.
707
+ Contains the followinig read-only attributes:
708
+ * ``args``: list of command-line arguments as passed to ``pytest.main()``.
709
+ * ``plugins``: list of extra plugins, might be None
710
+ * ``dir``: directory where ``pytest.main()`` was invoked from.
711
+ """
712
+
713
+ @attr .s (frozen = True )
714
+ class InvocationParams (object ):
715
+ """Holds parameters passed during ``pytest.main()``
716
+
717
+ .. note::
718
+
719
+ Currently the environment variable PYTEST_ADDOPTS is also handled by
720
+ pytest implicitly, not being part of the invocation.
721
+
722
+ Plugins accessing ``InvocationParams`` must be aware of that.
723
+ """
724
+
725
+ args = attr .ib ()
726
+ plugins = attr .ib ()
727
+ dir = attr .ib ()
728
+
729
+ def __init__ (self , pluginmanager , invocation_params = None , * args ):
730
+ from .argparsing import Parser , FILE_OR_DIR
731
+
732
+ if invocation_params is None :
733
+ invocation_params = self .InvocationParams (
734
+ args = (), plugins = None , dir = Path ().resolve ()
735
+ )
690
736
691
- def __init__ (self , pluginmanager ):
692
737
#: access to command line option as attributes.
693
738
#: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
694
739
self .option = argparse .Namespace ()
695
- from .argparsing import Parser , FILE_OR_DIR
740
+
741
+ self .invocation_params = invocation_params
696
742
697
743
_a = FILE_OR_DIR
698
744
self ._parser = Parser (
@@ -709,9 +755,13 @@ def __init__(self, pluginmanager):
709
755
self ._cleanup = []
710
756
self .pluginmanager .register (self , "pytestconfig" )
711
757
self ._configured = False
712
- self .invocation_dir = py .path .local ()
713
758
self .hook .pytest_addoption .call_historic (kwargs = dict (parser = self ._parser ))
714
759
760
+ @property
761
+ def invocation_dir (self ):
762
+ """Backward compatibility"""
763
+ return py .path .local (str (self .invocation_params .dir ))
764
+
715
765
def add_cleanup (self , func ):
716
766
""" Add a function to be called when the config object gets out of
717
767
use (usually coninciding with pytest_unconfigure)."""
0 commit comments