Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make use of -I in all Python invocations #11682

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Expand Up @@ -79,7 +79,7 @@ jobs:

- name: Install tox
run: |
python -m pip install --upgrade pip
python -Im pip install --upgrade pip
pip install --upgrade tox

- name: Publish GitHub release notes
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prepare-release-pr.yml
Expand Up @@ -38,7 +38,7 @@ jobs:

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -Im pip install --upgrade pip
pip install --upgrade setuptools tox

- name: Prepare release PR (minor/patch release)
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Expand Up @@ -186,7 +186,7 @@ jobs:

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -Im pip install --upgrade pip
pip install tox coverage

- name: Test without coverage
Expand All @@ -201,7 +201,7 @@ jobs:

- name: Generate coverage report
if: "matrix.use_coverage"
run: python -m coverage xml
run: python -Im coverage xml

- name: Upload coverage to Codecov
if: "matrix.use_coverage"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-plugin-list.yml
Expand Up @@ -38,7 +38,7 @@ jobs:

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -Im pip install --upgrade pip
pip install packaging requests tabulate[widechars] tqdm requests-cache platformdirs


Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Expand Up @@ -299,7 +299,7 @@ Here is a simple overview, with pytest-specific bits:
#. If instead of using ``tox`` you prefer to run the tests directly, then we suggest to create a virtual environment and use
an editable install with the ``testing`` extra::

$ python3 -m venv .venv
$ python3 -Im venv .venv
$ source .venv/bin/activate # Linux
$ .venv/Scripts/activate.bat # Windows
$ pip install -e ".[testing]"
Expand Down
2 changes: 1 addition & 1 deletion doc/en/explanation/goodpractices.rst
Expand Up @@ -137,7 +137,7 @@ which are better explained in this excellent `blog post`_ by Ionel Cristian Măr
directory) you can rely on the fact that Python by default puts the current directory in ``sys.path`` to
import your package and run ``python -m pytest`` to execute the tests against the local copy directly.

See :ref:`pytest vs python -m pytest` for more information about the difference between calling ``pytest`` and
See :ref:`pytest vs python -Im pytest` for more information about the difference between calling ``pytest`` and
``python -m pytest``.

Tests as part of application code
Expand Down
12 changes: 6 additions & 6 deletions doc/en/explanation/pythonpath.rst
Expand Up @@ -130,13 +130,13 @@ imported in the global import namespace.

This is also discussed in details in :ref:`test discovery`.

.. _`pytest vs python -m pytest`:
.. _`pytest vs python -Im pytest`:

Invoking ``pytest`` versus ``python -m pytest``
-----------------------------------------------
Invoking ``pytest`` versus ``python -Im pytest``
------------------------------------------------

Running pytest with ``pytest [...]`` instead of ``python -m pytest [...]`` yields nearly
equivalent behaviour, except that the latter will add the current directory to ``sys.path``, which
is standard ``python`` behavior.
Running pytest with ``pytest [...]`` instead of ``python -Im pytest [...]`` yields nearly
equivalent behaviour, except that the latter will add the current directory to ``sys.path``
in case when ``-I`` is omitted, which is standard ``python`` behavior.

See also :ref:`invoke-python`.
11 changes: 7 additions & 4 deletions doc/en/how-to/usage.rst
Expand Up @@ -158,17 +158,20 @@ Other ways of calling pytest

.. _invoke-python:

Calling pytest through ``python -m pytest``
Calling pytest through ``python -Im pytest``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can invoke testing through the Python interpreter from the command line:

.. code-block:: text

python -m pytest [...]
python -Im pytest [...]

This is almost equivalent to invoking the command line script ``pytest [...]``
directly, except that calling via ``python`` will also add the current directory to ``sys.path``.
This is equivalent to invoking the command line script ``pytest [...]``
directly, for as long as ``-I`` is used. Dropping it will also add the current
directory to ``sys.path``, which may have a side effect of not `testing your
project as installed
<https://blog.ganssle.io/articles/2019/08/test-as-installed.html>`__.


.. _`pytest.main-usage`:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/pytester.py
Expand Up @@ -97,7 +97,7 @@ def pytest_addoption(parser: Parser) -> None:
choices=("inprocess", "subprocess"),
help=(
"Run pytest sub runs in tests using an 'inprocess' "
"or 'subprocess' (python -m main) method"
"or 'subprocess' (python -Im main) method"
),
)

Expand Down
6 changes: 3 additions & 3 deletions testing/acceptance_test.py
Expand Up @@ -589,17 +589,17 @@ def test_hello():

def test_python_minus_m_invocation_ok(self, pytester: Pytester) -> None:
p1 = pytester.makepyfile("def test_hello(): pass")
res = pytester.run(sys.executable, "-m", "pytest", str(p1))
res = pytester.run(sys.executable, "-Im", "pytest", str(p1))
assert res.ret == 0

def test_python_minus_m_invocation_fail(self, pytester: Pytester) -> None:
p1 = pytester.makepyfile("def test_fail(): 0/0")
res = pytester.run(sys.executable, "-m", "pytest", str(p1))
res = pytester.run(sys.executable, "-Im", "pytest", str(p1))
assert res.ret == 1

def test_python_pytest_package(self, pytester: Pytester) -> None:
p1 = pytester.makepyfile("def test_pass(): pass")
res = pytester.run(sys.executable, "-m", "pytest", str(p1))
res = pytester.run(sys.executable, "-Im", "pytest", str(p1))
assert res.ret == 0
res.stdout.fnmatch_lines(["*1 passed*"])

Expand Down
6 changes: 3 additions & 3 deletions testing/test_assertion.py
Expand Up @@ -1702,18 +1702,18 @@ def test_multitask_job():
"cmdline_args, warning_output",
[
(
["-OO", "-m", "pytest", "-h"],
["-OO", "-Im", "pytest", "-h"],
["warning :*PytestConfigWarning:*assert statements are not executed*"],
),
(
["-OO", "-m", "pytest"],
["-OO", "-Im", "pytest"],
[
"=*= warnings summary =*=",
"*PytestConfigWarning:*assert statements are not executed*",
],
),
(
["-OO", "-m", "pytest", "--assert=plain"],
["-OO", "-Im", "pytest", "--assert=plain"],
[
"=*= warnings summary =*=",
"*PytestConfigWarning: ASSERTIONS ARE NOT EXECUTED and FAILING TESTS WILL PASS. "
Expand Down
2 changes: 1 addition & 1 deletion testing/test_parseopt.py
Expand Up @@ -317,7 +317,7 @@ def test_argcomplete(pytester: Pytester, monkeypatch: MonkeyPatch) -> None:
# http://stackoverflow.com/q/12589419/1307905
# so we use bash
fp.write(
'COMP_WORDBREAKS="$COMP_WORDBREAKS" {} -m pytest 8>&1 9>&2'.format(
'COMP_WORDBREAKS="$COMP_WORDBREAKS" {} -Im pytest 8>&1 9>&2'.format(
shlex.quote(sys.executable)
)
)
Expand Down
2 changes: 1 addition & 1 deletion testing/test_setuponly.py
Expand Up @@ -313,6 +313,6 @@ def test_data(data):
"""
)
result = pytester.run(
sys.executable, "-bb", "-m", "pytest", "--setup-show", str(test_file)
sys.executable, "-bb", "-Im", "pytest", "--setup-show", str(test_file)
)
assert result.ret == 0
14 changes: 5 additions & 9 deletions testing/test_warnings.py
Expand Up @@ -792,7 +792,7 @@ def test_warning_on_testpaths_not_found(pytester: Pytester) -> None:
)


def test_resource_warning(pytester: Pytester, monkeypatch: pytest.MonkeyPatch) -> None:
def test_resource_warning(pytester: Pytester) -> None:
# Some platforms (notably PyPy) don't have tracemalloc.
# We choose to explicitly not skip this in case tracemalloc is not
# available, using `importorskip("tracemalloc")` for example,
Expand All @@ -804,10 +804,6 @@ def test_resource_warning(pytester: Pytester, monkeypatch: pytest.MonkeyPatch) -
except ImportError:
has_tracemalloc = False

# Explicitly disable PYTHONTRACEMALLOC in case pytest's test suite is running
# with it enabled.
monkeypatch.delenv("PYTHONTRACEMALLOC", raising=False)

pytester.makepyfile(
"""
def open_file(p):
Expand All @@ -820,7 +816,9 @@ def test_resource_warning(tmp_path):
open_file(p)
"""
)
result = pytester.run(sys.executable, "-Xdev", "-m", "pytest")
# Explicitly disable PYTHONTRACEMALLOC in case pytest's test suite is running
# with it enabled.
result = pytester.run(sys.executable, "-Xdev", "-Xtracemalloc=0", "-Im", "pytest")
expected_extra = (
[
"*ResourceWarning* unclosed file*",
Expand All @@ -832,9 +830,7 @@ def test_resource_warning(tmp_path):
)
result.stdout.fnmatch_lines([*expected_extra, "*1 passed*"])

monkeypatch.setenv("PYTHONTRACEMALLOC", "20")

result = pytester.run(sys.executable, "-Xdev", "-m", "pytest")
result = pytester.run(sys.executable, "-Xdev", "-Xtracemalloc=20", "-Im", "pytest")
expected_extra = (
[
"*ResourceWarning* unclosed file*",
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Expand Up @@ -129,7 +129,7 @@ setenv =
pip_pre=true
# use latest pip to get new dependency resolver (#7783)
download=true
install_command=python -m pip install {opts} {packages}
install_command=python -Im pip install {opts} {packages}
changedir = testing/plugins_integration
deps = -rtesting/plugins_integration/requirements.txt
setenv =
Expand Down