scope.py


Overview

The `scope.py` file defines and manages the concept of *fixture scopes* used in the pytest testing framework. Fixture scopes specify the lifetime and sharing boundaries of fixtures, controlling when and how often fixtures are set up and torn down during test execution.

This module centralizes the `Scope` enumeration and related utilities, enabling consistent handling of fixture scopes across many pytest modules without causing circular imports. It purposely remains lightweight and independent of the broader `fixtures` module to facilitate easy imports and reuse.

The defined scopes are ordered from the narrowest/lower scope (`function`) to the broadest/higher scope (`session`), reflecting the typical lifecycle and visibility of test fixtures.


Classes and Functions

Scope (Enum)

Represents one of the possible fixture scopes in pytest and provides utilities for scope comparison and navigation.

Scopes Defined (from narrowest to broadest):

Scope

Description

function

Fixture is created for each test function.

class

Fixture is shared among tests within a class.

module

Fixture is shared among tests within a module.

package

Fixture is shared among tests within a package.

session

Fixture is shared across the entire test session.


Properties & Methods

Properties (Enum members)

Each corresponds to a string literal of the same name.


next_lower(self) -> Scope

Returns the next lower (narrower) scope relative to the current scope.

scope = Scope.Module
lower_scope = scope.next_lower()
print(lower_scope)  # Output: Scope.Class

next_higher(self) -> Scope

Returns the next higher (broader) scope relative to the current scope.

scope = Scope.Class
higher_scope = scope.next_higher()
print(higher_scope)  # Output: Scope.Module

__lt__(self, other: Scope) -> bool

Implements comparison logic to allow ordering of scopes, enabling the use of `<` to compare scopes by their hierarchy.

print(Scope.Function < Scope.Module)  # Output: True
print(Scope.Session < Scope.Package)  # Output: False

from_user(cls, scope_name: _ScopeName, descr: str, where: str | None = None) -> Scope

Class method to convert a user-provided scope name (string) into the corresponding `Scope` enum instance. It performs validation and raises a user-friendly failure via `pytest.fail` if the input is invalid.

scope = Scope.from_user("module", "fixture scope", "in test_config.py")
print(scope)  # Output: Scope.Module

If an invalid scope is passed:

Scope.from_user("invalidscope", "fixture scope")  
# Will call pytest.fail with message like:
# "fixture scope got an unexpected scope value 'invalidscope'"

Module-level Variables


Implementation Details and Algorithms


Interaction with Other System Components


Visual Diagram

classDiagram
    class Scope {
        <<Enum>>
        +Function: Scope
        +Class: Scope
        +Module: Scope
        +Package: Scope
        +Session: Scope
        +next_lower() Scope
        +next_higher() Scope
        +from_user(scope_name: _ScopeName, descr: str, where: Optional[str]) Scope
        +__lt__(other: Scope) bool
    }

    Scope o-- "_ALL_SCOPES: List[Scope]" : uses
    Scope o-- "_SCOPE_INDICES: Dict[Scope, int]" : uses
    Scope ..> "pytest.outcomes.fail" : calls

Summary

The `scope.py` file encapsulates the concept of fixture scopes in pytest as a strongly ordered `Enum` with convenient navigation and validation methods. It plays a critical role in the fixture management system by providing a simple, lightweight, and consistent interface for scope handling across pytest's codebase. Its design carefully avoids heavy dependencies, making it a reusable utility module.


Example Usage Snippet

from scope import Scope

# Get a scope from user input and handle errors gracefully
try:
    user_scope = Scope.from_user("module", "fixture scope")
except Exception:
    # This will not usually raise but fail inside pytest
    pass

# Compare scopes
if Scope.Function < user_scope:
    print(f"{Scope.Function} is narrower than {user_scope}")

# Navigate between scopes
higher = user_scope.next_higher() if user_scope != Scope.Session else user_scope
print(f"Next higher scope after {user_scope} is {higher}")

End of Documentation for scope.py