Coverage for /opt/homebrew/lib/python3.11/site-packages/_pytest/scope.py: 77%

39 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-05-04 13:14 +0700

1""" 

2Scope definition and related utilities. 

3 

4Those are defined here, instead of in the 'fixtures' module because 

5their use is spread across many other pytest modules, and centralizing it in 'fixtures' 

6would cause circular references. 

7 

8Also this makes the module light to import, as it should. 

9""" 

10from enum import Enum 

11from functools import total_ordering 

12from typing import Optional 

13from typing import TYPE_CHECKING 

14 

15if TYPE_CHECKING: 

16 from typing_extensions import Literal 

17 

18 _ScopeName = Literal["session", "package", "module", "class", "function"] 

19 

20 

21@total_ordering 

22class Scope(Enum): 

23 """ 

24 Represents one of the possible fixture scopes in pytest. 

25 

26 Scopes are ordered from lower to higher, that is: 

27 

28 ->>> higher ->>> 

29 

30 Function < Class < Module < Package < Session 

31 

32 <<<- lower <<<- 

33 """ 

34 

35 # Scopes need to be listed from lower to higher. 

36 Function: "_ScopeName" = "function" 

37 Class: "_ScopeName" = "class" 

38 Module: "_ScopeName" = "module" 

39 Package: "_ScopeName" = "package" 

40 Session: "_ScopeName" = "session" 

41 

42 def next_lower(self) -> "Scope": 

43 """Return the next lower scope.""" 

44 index = _SCOPE_INDICES[self] 

45 if index == 0: 

46 raise ValueError(f"{self} is the lower-most scope") 

47 return _ALL_SCOPES[index - 1] 

48 

49 def next_higher(self) -> "Scope": 

50 """Return the next higher scope.""" 

51 index = _SCOPE_INDICES[self] 

52 if index == len(_SCOPE_INDICES) - 1: 

53 raise ValueError(f"{self} is the upper-most scope") 

54 return _ALL_SCOPES[index + 1] 

55 

56 def __lt__(self, other: "Scope") -> bool: 

57 self_index = _SCOPE_INDICES[self] 

58 other_index = _SCOPE_INDICES[other] 

59 return self_index < other_index 

60 

61 @classmethod 

62 def from_user( 

63 cls, scope_name: "_ScopeName", descr: str, where: Optional[str] = None 

64 ) -> "Scope": 

65 """ 

66 Given a scope name from the user, return the equivalent Scope enum. Should be used 

67 whenever we want to convert a user provided scope name to its enum object. 

68 

69 If the scope name is invalid, construct a user friendly message and call pytest.fail. 

70 """ 

71 from _pytest.outcomes import fail 

72 

73 try: 

74 # Holding this reference is necessary for mypy at the moment. 

75 scope = Scope(scope_name) 

76 except ValueError: 

77 fail( 

78 "{} {}got an unexpected scope value '{}'".format( 

79 descr, f"from {where} " if where else "", scope_name 

80 ), 

81 pytrace=False, 

82 ) 

83 return scope 

84 

85 

86_ALL_SCOPES = list(Scope) 

87_SCOPE_INDICES = {scope: index for index, scope in enumerate(_ALL_SCOPES)} 

88 

89 

90# Ordered list of scopes which can contain many tests (in practice all except Function). 

91HIGH_SCOPES = [x for x in Scope if x is not Scope.Function]