88import types
99import warnings
1010from functools import lru_cache
11+ from pathlib import Path
1112
13+ import attr
1214import py
1315from packaging .version import Version
1416from pluggy import HookimplMarker
@@ -148,10 +150,15 @@ def directory_arg(path, optname):
148150builtin_plugins .add ("pytester" )
149151
150152
151- def get_config (args = None ):
153+ def get_config (args = None , plugins = None ):
152154 # subsequent calls to main will create a fresh instance
153155 pluginmanager = PytestPluginManager ()
154- config = Config (pluginmanager )
156+ config = Config (
157+ pluginmanager ,
158+ invocation_params = Config .InvocationParams (
159+ args = args , plugins = plugins , dir = Path ().resolve ()
160+ ),
161+ )
155162
156163 if args is not None :
157164 # Handle any "-p no:plugin" args.
@@ -184,7 +191,7 @@ def _prepareconfig(args=None, plugins=None):
184191 msg = "`args` parameter expected to be a list or tuple of strings, got: {!r} (type: {})"
185192 raise TypeError (msg .format (args , type (args )))
186193
187- config = get_config (args )
194+ config = get_config (args , plugins )
188195 pluginmanager = config .pluginmanager
189196 try :
190197 if plugins :
@@ -613,20 +620,57 @@ def _iter_rewritable_modules(package_files):
613620
614621
615622class Config :
616- """ access to configuration values, pluginmanager and plugin hooks. """
623+ """
624+ Access to configuration values, pluginmanager and plugin hooks.
617625
618- def __init__ (self , pluginmanager ):
619- #: access to command line option as attributes.
620- #: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
621- self .option = argparse .Namespace ()
626+ :ivar PytestPluginManager pluginmanager: the plugin manager handles plugin registration and hook invocation.
627+
628+ :ivar argparse.Namespace option: access to command line option as attributes.
629+
630+ :ivar InvocationParams invocation_params:
631+
632+ Object containing the parameters regarding the ``pytest.main``
633+ invocation.
634+
635+ Contains the followinig read-only attributes:
636+
637+ * ``args``: list of command-line arguments as passed to ``pytest.main()``.
638+ * ``plugins``: list of extra plugins, might be None
639+ * ``dir``: directory where ``pytest.main()`` was invoked from.
640+ """
641+
642+ @attr .s (frozen = True )
643+ class InvocationParams :
644+ """Holds parameters passed during ``pytest.main()``
645+
646+ .. note::
647+
648+ Currently the environment variable PYTEST_ADDOPTS is also handled by
649+ pytest implicitly, not being part of the invocation.
650+
651+ Plugins accessing ``InvocationParams`` must be aware of that.
652+ """
653+
654+ args = attr .ib ()
655+ plugins = attr .ib ()
656+ dir = attr .ib ()
657+
658+ def __init__ (self , pluginmanager , * , invocation_params = None ):
622659 from .argparsing import Parser , FILE_OR_DIR
623660
661+ if invocation_params is None :
662+ invocation_params = self .InvocationParams (
663+ args = (), plugins = None , dir = Path ().resolve ()
664+ )
665+
666+ self .option = argparse .Namespace ()
667+ self .invocation_params = invocation_params
668+
624669 _a = FILE_OR_DIR
625670 self ._parser = Parser (
626671 usage = "%(prog)s [options] [{}] [{}] [...]" .format (_a , _a ),
627672 processopt = self ._processopt ,
628673 )
629- #: a pluginmanager instance
630674 self .pluginmanager = pluginmanager
631675 self .trace = self .pluginmanager .trace .root .get ("config" )
632676 self .hook = self .pluginmanager .hook
@@ -636,9 +680,13 @@ def __init__(self, pluginmanager):
636680 self ._cleanup = []
637681 self .pluginmanager .register (self , "pytestconfig" )
638682 self ._configured = False
639- self .invocation_dir = py .path .local ()
640683 self .hook .pytest_addoption .call_historic (kwargs = dict (parser = self ._parser ))
641684
685+ @property
686+ def invocation_dir (self ):
687+ """Backward compatibility"""
688+ return py .path .local (str (self .invocation_params .dir ))
689+
642690 def add_cleanup (self , func ):
643691 """ Add a function to be called when the config object gets out of
644692 use (usually coninciding with pytest_unconfigure)."""
0 commit comments