Repository: pytest-dev/pytest
File: src/_pytest/fixtures.py (Python)

Code before:
        return node.getparent(_pytest.python.Module)
    elif scope is Scope.Package:
        return node.getparent(_pytest.python.Package)
    elif scope is Scope.Session:
        return node.getparent(_pytest.main.Session)
    else:
        assert_never(scope)


# TODO: Try to use FixtureFunctionDefinition instead of the marker
def getfixturemarker(obj: object) -> FixtureFunctionMarker | None:
    """Return fixturemarker or None if it doesn't exist"""
    if isinstance(obj, FixtureFunctionDefinition):
        return obj._fixture_function_marker
    return None


# Algorithm for sorting on a per-parametrized resource setup basis.
# It is called for Session scope first and performs sorting
# down to the lower scopes such as to minimize number of "high scope"
# setups and teardowns.


@dataclasses.dataclass(frozen=True)
class ParamArgKey:
    # The param name.
    argname: str
    param_index: int
    # For scopes Package, Module, Class, the path to the file (directory in
    # Package's case) of the package/module/class where the item is defined.
    scoped_item_path: Path | None
    # For Class scope, the class where the item is defined.
    item_cls: type | None


_V = TypeVar("_V")
OrderedSet = dict[_V, None]


def get_param_argkeys(item: nodes.Item, scope: Scope) -> Iterator[ParamArgKey]:
    """Return hashable keys for all parametrized arguments which match the
    specified high scope."""
    assert scope is not Scope.Function

    try:
        callspec: CallSpec2 = item.callspec  # type: ignore[attr-defined]
    except AttributeError:
        return

    item_cls = None
    if scope is Scope.Session:

Review comment (suggestion):
It's not entirely clear if this is meant as a docstring or a comment for the following line. I'd suggest adding an explicit docstring and putting the comment on the same line as what it refers to.

Code after:
        return node.getparent(_pytest.python.Module)
    elif scope is Scope.Package:
        return node.getparent(_pytest.python.Package)
    elif scope is Scope.Session:
        return node.getparent(_pytest.main.Session)
    else:
        assert_never(scope)


# TODO: Try to use FixtureFunctionDefinition instead of the marker
def getfixturemarker(obj: object) -> FixtureFunctionMarker | None:
    """Return fixturemarker or None if it doesn't exist"""
    if isinstance(obj, FixtureFunctionDefinition):
        return obj._fixture_function_marker
    return None


# Algorithm for sorting on a per-parametrized resource setup basis.
# It is called for Session scope first and performs sorting
# down to the lower scopes such as to minimize number of "high scope"
# setups and teardowns.


@dataclasses.dataclass(frozen=True)
class ParamArgKey:
    """A key for a high-scoped parameter used by an item.

    For use as a hashable key in `reorder_items`. The combination of fields
    is meant to uniquely identify a particular "instance" of a param,
    potentially shared by multiple items in a scope.
    """

    #: The param name.
    argname: str
    param_index: int
    #: For scopes Package, Module, Class, the path to the file (directory in
    #: Package's case) of the package/module/class where the item is defined.
    scoped_item_path: Path | None
    #: For Class scope, the class where the item is defined.
    item_cls: type | None


_V = TypeVar("_V")
OrderedSet = dict[_V, None]


def get_param_argkeys(item: nodes.Item, scope: Scope) -> Iterator[ParamArgKey]:
    """Return all ParamArgKeys for item matching the specified high scope."""
    assert scope is not Scope.Function

    try: