Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/blinker/_utilities.py: 65%

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

31 statements  

1from __future__ import annotations 

2 

3import collections.abc as c 

4import inspect 

5import typing as t 

6from weakref import ref 

7from weakref import WeakMethod 

8 

9T = t.TypeVar("T") 

10 

11 

12class Symbol: 

13 """A constant symbol, nicer than ``object()``. Repeated calls return the 

14 same instance. 

15 

16 >>> Symbol('foo') is Symbol('foo') 

17 True 

18 >>> Symbol('foo') 

19 foo 

20 """ 

21 

22 symbols: t.ClassVar[dict[str, Symbol]] = {} 

23 

24 def __new__(cls, name: str) -> Symbol: 

25 if name in cls.symbols: 

26 return cls.symbols[name] 

27 

28 obj = super().__new__(cls) 

29 cls.symbols[name] = obj 

30 return obj 

31 

32 def __init__(self, name: str) -> None: 

33 self.name = name 

34 

35 def __repr__(self) -> str: 

36 return self.name 

37 

38 def __getnewargs__(self) -> tuple[t.Any, ...]: 

39 return (self.name,) 

40 

41 

42def make_id(obj: object) -> c.Hashable: 

43 """Get a stable identifier for a receiver or sender, to be used as a dict 

44 key or in a set. 

45 """ 

46 if inspect.ismethod(obj): 

47 # The id of a bound method is not stable, but the id of the unbound 

48 # function and instance are. 

49 return id(obj.__func__), id(obj.__self__) 

50 

51 if isinstance(obj, (str, int)): 

52 # Instances with the same value always compare equal and have the same 

53 # hash, even if the id may change. 

54 return obj 

55 

56 # Assume other types are not hashable but will always be the same instance. 

57 return id(obj) 

58 

59 

60def make_ref(obj: T, callback: c.Callable[[ref[T]], None] | None = None) -> ref[T]: 

61 if inspect.ismethod(obj): 

62 return WeakMethod(obj, callback) # type: ignore[arg-type, return-value] 

63 

64 return ref(obj, callback)