diff --git a/AUTHORS b/AUTHORS index cc054bfd9..7c35a6152 100644 --- a/AUTHORS +++ b/AUTHORS @@ -118,6 +118,7 @@ Daw-Ran Liou Debi Mishra Denis Kirisov Denivy Braiam Rück +Dheeraj C K Dhiren Serai Diego Russo Dmitry Dygalo diff --git a/changelog/9502.improvement.rst b/changelog/9502.improvement.rst new file mode 100644 index 000000000..2eaf6a727 --- /dev/null +++ b/changelog/9502.improvement.rst @@ -0,0 +1 @@ +Added :envvar:`PYTEST_VERSION` environment variable which is defined at the start of the pytest session and undefined afterwards. It contains the value of ``pytest.__version__``, and among other things can be used to easily check if code is running from within a pytest run. diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index c9d7aeb55..39317497e 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -1117,6 +1117,11 @@ When set (regardless of value), pytest acknowledges that is running in a CI proc This contains a command-line (parsed by the py:mod:`shlex` module) that will be **prepended** to the command line given by the user, see :ref:`adding default options` for more information. +.. envvar:: PYTEST_VERSION + +This environment variable is defined at the start of the pytest session and is undefined afterwards. +It contains the value of ``pytest.__version__``, and among other things can be used to easily check if a code is running from within a pytest run. + .. envvar:: PYTEST_CURRENT_TEST This is not meant to be set by users, but is set by pytest internally with the name of the current test so other diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 7ff27643f..306b14cce 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -50,6 +50,7 @@ from .compat import PathAwareHookProxy from .exceptions import PrintHelp as PrintHelp from .exceptions import UsageError as UsageError from .findpaths import determine_setup +from _pytest import __version__ import _pytest._code from _pytest._code import ExceptionInfo from _pytest._code import filter_traceback @@ -151,7 +152,9 @@ def main( :returns: An exit code. """ + old_pytest_version = os.environ.get("PYTEST_VERSION") try: + os.environ["PYTEST_VERSION"] = __version__ try: config = _prepareconfig(args, plugins) except ConftestImportFailure as e: @@ -186,6 +189,11 @@ def main( for msg in e.args: tw.line(f"ERROR: {msg}\n", red=True) return ExitCode.USAGE_ERROR + finally: + if old_pytest_version is None: + os.environ.pop("PYTEST_VERSION", None) + else: + os.environ["PYTEST_VERSION"] = old_pytest_version def console_main() -> int: diff --git a/testing/test_runner.py b/testing/test_runner.py index 8cc496f70..d3ddc5d9a 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1094,3 +1094,20 @@ def test_outcome_exception_bad_msg() -> None: with pytest.raises(TypeError) as excinfo: OutcomeException(func) # type: ignore assert str(excinfo.value) == expected + + +def test_pytest_version_env_var(pytester: Pytester, monkeypatch: MonkeyPatch) -> None: + os.environ["PYTEST_VERSION"] = "old version" + pytester.makepyfile( + """ + import pytest + import os + + + def test(): + assert os.environ.get("PYTEST_VERSION") == pytest.__version__ + """ + ) + result = pytester.runpytest_inprocess() + assert result.ret == ExitCode.OK + assert os.environ["PYTEST_VERSION"] == "old version"