Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/attr/_compat.py: 76%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

42 statements  

1# SPDX-License-Identifier: MIT 

2 

3import inspect 

4import platform 

5import sys 

6import threading 

7 

8from collections.abc import Mapping, Sequence # noqa: F401 

9from typing import _GenericAlias 

10 

11 

12PYPY = platform.python_implementation() == "PyPy" 

13PY_3_10_PLUS = sys.version_info[:2] >= (3, 10) 

14PY_3_11_PLUS = sys.version_info[:2] >= (3, 11) 

15PY_3_12_PLUS = sys.version_info[:2] >= (3, 12) 

16PY_3_13_PLUS = sys.version_info[:2] >= (3, 13) 

17PY_3_14_PLUS = sys.version_info[:2] >= (3, 14) 

18 

19 

20if PY_3_14_PLUS: 

21 import annotationlib 

22 

23 # We request forward-ref annotations to not break in the presence of 

24 # forward references. 

25 

26 def _get_annotations(cls): 

27 return annotationlib.get_annotations( 

28 cls, format=annotationlib.Format.FORWARDREF 

29 ) 

30 

31else: 

32 

33 def _get_annotations(cls): 

34 """ 

35 Get annotations for *cls*. 

36 """ 

37 return cls.__dict__.get("__annotations__", {}) 

38 

39 

40class _AnnotationExtractor: 

41 """ 

42 Extract type annotations from a callable, returning None whenever there 

43 is none. 

44 """ 

45 

46 __slots__ = ["sig"] 

47 

48 def __init__(self, callable): 

49 try: 

50 self.sig = inspect.signature(callable) 

51 except (ValueError, TypeError): # inspect failed 

52 self.sig = None 

53 

54 def get_first_param_type(self): 

55 """ 

56 Return the type annotation of the first argument if it's not empty. 

57 """ 

58 if not self.sig: 

59 return None 

60 

61 params = list(self.sig.parameters.values()) 

62 if params and params[0].annotation is not inspect.Parameter.empty: 

63 return params[0].annotation 

64 

65 return None 

66 

67 def get_return_type(self): 

68 """ 

69 Return the return type if it's not empty. 

70 """ 

71 if ( 

72 self.sig 

73 and self.sig.return_annotation is not inspect.Signature.empty 

74 ): 

75 return self.sig.return_annotation 

76 

77 return None 

78 

79 

80# Thread-local global to track attrs instances which are already being repr'd. 

81# This is needed because there is no other (thread-safe) way to pass info 

82# about the instances that are already being repr'd through the call stack 

83# in order to ensure we don't perform infinite recursion. 

84# 

85# For instance, if an instance contains a dict which contains that instance, 

86# we need to know that we're already repr'ing the outside instance from within 

87# the dict's repr() call. 

88# 

89# This lives here rather than in _make.py so that the functions in _make.py 

90# don't have a direct reference to the thread-local in their globals dict. 

91# If they have such a reference, it breaks cloudpickle. 

92repr_context = threading.local() 

93 

94 

95def get_generic_base(cl): 

96 """If this is a generic class (A[str]), return the generic base for it.""" 

97 if cl.__class__ is _GenericAlias: 

98 return cl.__origin__ 

99 return None