|
40 | 40 | from _pytest._code.code import ExceptionInfo |
41 | 41 | from _pytest._code.code import TerminalRepr |
42 | 42 | from _pytest._code.code import Traceback |
43 | | -from _pytest._io import TerminalWriter |
44 | 43 | from _pytest._io.saferepr import saferepr |
45 | 44 | from _pytest.compat import ascii_escaped |
46 | 45 | from _pytest.compat import get_default_arg_names |
47 | 46 | from _pytest.compat import get_real_func |
48 | 47 | from _pytest.compat import getimfunc |
49 | | -from _pytest.compat import getlocation |
50 | 48 | from _pytest.compat import is_async_function |
51 | 49 | from _pytest.compat import is_generator |
52 | 50 | from _pytest.compat import LEGACY_PATH |
53 | 51 | from _pytest.compat import NOTSET |
54 | 52 | from _pytest.compat import safe_getattr |
55 | 53 | from _pytest.compat import safe_isclass |
56 | 54 | from _pytest.config import Config |
57 | | -from _pytest.config import ExitCode |
58 | 55 | from _pytest.config import hookimpl |
59 | 56 | from _pytest.config.argparsing import Parser |
60 | 57 | from _pytest.deprecated import check_ispytest |
|
71 | 68 | from _pytest.mark.structures import normalize_mark_list |
72 | 69 | from _pytest.outcomes import fail |
73 | 70 | from _pytest.outcomes import skip |
74 | | -from _pytest.pathlib import bestrelpath |
75 | 71 | from _pytest.pathlib import fnmatch_ex |
76 | 72 | from _pytest.pathlib import import_path |
77 | 73 | from _pytest.pathlib import ImportPathMismatchError |
|
88 | 84 | from typing import Self |
89 | 85 |
|
90 | 86 |
|
91 | | -_PYTEST_DIR = Path(_pytest.__file__).parent |
92 | | - |
93 | | - |
94 | 87 | def pytest_addoption(parser: Parser) -> None: |
95 | | - group = parser.getgroup("general") |
96 | | - group.addoption( |
97 | | - "--fixtures", |
98 | | - "--funcargs", |
99 | | - action="store_true", |
100 | | - dest="showfixtures", |
101 | | - default=False, |
102 | | - help="Show available fixtures, sorted by plugin appearance " |
103 | | - "(fixtures with leading '_' are only shown with '-v')", |
104 | | - ) |
105 | | - group.addoption( |
106 | | - "--fixtures-per-test", |
107 | | - action="store_true", |
108 | | - dest="show_fixtures_per_test", |
109 | | - default=False, |
110 | | - help="Show fixtures per test", |
111 | | - ) |
112 | 88 | parser.addini( |
113 | 89 | "python_files", |
114 | 90 | type="args", |
@@ -137,16 +113,6 @@ def pytest_addoption(parser: Parser) -> None: |
137 | 113 | ) |
138 | 114 |
|
139 | 115 |
|
140 | | -def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]: |
141 | | - if config.option.showfixtures: |
142 | | - showfixtures(config) |
143 | | - return 0 |
144 | | - if config.option.show_fixtures_per_test: |
145 | | - show_fixtures_per_test(config) |
146 | | - return 0 |
147 | | - return None |
148 | | - |
149 | | - |
150 | 116 | def pytest_generate_tests(metafunc: "Metafunc") -> None: |
151 | 117 | for marker in metafunc.definition.iter_markers(name="parametrize"): |
152 | 118 | metafunc.parametrize(*marker.args, **marker.kwargs, _param_mark=marker) |
@@ -1525,137 +1491,6 @@ def _ascii_escaped_by_config(val: Union[str, bytes], config: Optional[Config]) - |
1525 | 1491 | return val if escape_option else ascii_escaped(val) # type: ignore |
1526 | 1492 |
|
1527 | 1493 |
|
1528 | | -def _pretty_fixture_path(invocation_dir: Path, func) -> str: |
1529 | | - loc = Path(getlocation(func, invocation_dir)) |
1530 | | - prefix = Path("...", "_pytest") |
1531 | | - try: |
1532 | | - return str(prefix / loc.relative_to(_PYTEST_DIR)) |
1533 | | - except ValueError: |
1534 | | - return bestrelpath(invocation_dir, loc) |
1535 | | - |
1536 | | - |
1537 | | -def show_fixtures_per_test(config): |
1538 | | - from _pytest.main import wrap_session |
1539 | | - |
1540 | | - return wrap_session(config, _show_fixtures_per_test) |
1541 | | - |
1542 | | - |
1543 | | -def _show_fixtures_per_test(config: Config, session: Session) -> None: |
1544 | | - import _pytest.config |
1545 | | - |
1546 | | - session.perform_collect() |
1547 | | - invocation_dir = config.invocation_params.dir |
1548 | | - tw = _pytest.config.create_terminal_writer(config) |
1549 | | - verbose = config.getvalue("verbose") |
1550 | | - |
1551 | | - def get_best_relpath(func) -> str: |
1552 | | - loc = getlocation(func, invocation_dir) |
1553 | | - return bestrelpath(invocation_dir, Path(loc)) |
1554 | | - |
1555 | | - def write_fixture(fixture_def: fixtures.FixtureDef[object]) -> None: |
1556 | | - argname = fixture_def.argname |
1557 | | - if verbose <= 0 and argname.startswith("_"): |
1558 | | - return |
1559 | | - prettypath = _pretty_fixture_path(invocation_dir, fixture_def.func) |
1560 | | - tw.write(f"{argname}", green=True) |
1561 | | - tw.write(f" -- {prettypath}", yellow=True) |
1562 | | - tw.write("\n") |
1563 | | - fixture_doc = inspect.getdoc(fixture_def.func) |
1564 | | - if fixture_doc: |
1565 | | - write_docstring( |
1566 | | - tw, fixture_doc.split("\n\n")[0] if verbose <= 0 else fixture_doc |
1567 | | - ) |
1568 | | - else: |
1569 | | - tw.line(" no docstring available", red=True) |
1570 | | - |
1571 | | - def write_item(item: nodes.Item) -> None: |
1572 | | - # Not all items have _fixtureinfo attribute. |
1573 | | - info: Optional[FuncFixtureInfo] = getattr(item, "_fixtureinfo", None) |
1574 | | - if info is None or not info.name2fixturedefs: |
1575 | | - # This test item does not use any fixtures. |
1576 | | - return |
1577 | | - tw.line() |
1578 | | - tw.sep("-", f"fixtures used by {item.name}") |
1579 | | - # TODO: Fix this type ignore. |
1580 | | - tw.sep("-", f"({get_best_relpath(item.function)})") # type: ignore[attr-defined] |
1581 | | - # dict key not used in loop but needed for sorting. |
1582 | | - for _, fixturedefs in sorted(info.name2fixturedefs.items()): |
1583 | | - assert fixturedefs is not None |
1584 | | - if not fixturedefs: |
1585 | | - continue |
1586 | | - # Last item is expected to be the one used by the test item. |
1587 | | - write_fixture(fixturedefs[-1]) |
1588 | | - |
1589 | | - for session_item in session.items: |
1590 | | - write_item(session_item) |
1591 | | - |
1592 | | - |
1593 | | -def showfixtures(config: Config) -> Union[int, ExitCode]: |
1594 | | - from _pytest.main import wrap_session |
1595 | | - |
1596 | | - return wrap_session(config, _showfixtures_main) |
1597 | | - |
1598 | | - |
1599 | | -def _showfixtures_main(config: Config, session: Session) -> None: |
1600 | | - import _pytest.config |
1601 | | - |
1602 | | - session.perform_collect() |
1603 | | - invocation_dir = config.invocation_params.dir |
1604 | | - tw = _pytest.config.create_terminal_writer(config) |
1605 | | - verbose = config.getvalue("verbose") |
1606 | | - |
1607 | | - fm = session._fixturemanager |
1608 | | - |
1609 | | - available = [] |
1610 | | - seen: Set[Tuple[str, str]] = set() |
1611 | | - |
1612 | | - for argname, fixturedefs in fm._arg2fixturedefs.items(): |
1613 | | - assert fixturedefs is not None |
1614 | | - if not fixturedefs: |
1615 | | - continue |
1616 | | - for fixturedef in fixturedefs: |
1617 | | - loc = getlocation(fixturedef.func, invocation_dir) |
1618 | | - if (fixturedef.argname, loc) in seen: |
1619 | | - continue |
1620 | | - seen.add((fixturedef.argname, loc)) |
1621 | | - available.append( |
1622 | | - ( |
1623 | | - len(fixturedef.baseid), |
1624 | | - fixturedef.func.__module__, |
1625 | | - _pretty_fixture_path(invocation_dir, fixturedef.func), |
1626 | | - fixturedef.argname, |
1627 | | - fixturedef, |
1628 | | - ) |
1629 | | - ) |
1630 | | - |
1631 | | - available.sort() |
1632 | | - currentmodule = None |
1633 | | - for baseid, module, prettypath, argname, fixturedef in available: |
1634 | | - if currentmodule != module: |
1635 | | - if not module.startswith("_pytest."): |
1636 | | - tw.line() |
1637 | | - tw.sep("-", f"fixtures defined from {module}") |
1638 | | - currentmodule = module |
1639 | | - if verbose <= 0 and argname.startswith("_"): |
1640 | | - continue |
1641 | | - tw.write(f"{argname}", green=True) |
1642 | | - if fixturedef.scope != "function": |
1643 | | - tw.write(" [%s scope]" % fixturedef.scope, cyan=True) |
1644 | | - tw.write(f" -- {prettypath}", yellow=True) |
1645 | | - tw.write("\n") |
1646 | | - doc = inspect.getdoc(fixturedef.func) |
1647 | | - if doc: |
1648 | | - write_docstring(tw, doc.split("\n\n")[0] if verbose <= 0 else doc) |
1649 | | - else: |
1650 | | - tw.line(" no docstring available", red=True) |
1651 | | - tw.line() |
1652 | | - |
1653 | | - |
1654 | | -def write_docstring(tw: TerminalWriter, doc: str, indent: str = " ") -> None: |
1655 | | - for line in doc.split("\n"): |
1656 | | - tw.line(indent + line) |
1657 | | - |
1658 | | - |
1659 | 1494 | class Function(PyobjMixin, nodes.Item): |
1660 | 1495 | """Item responsible for setting up and executing a Python test function. |
1661 | 1496 |
|
|
0 commit comments