A constant symbol. >>> symbol("foo") is symbol("foo") True >>> symbol("foo") <symbol 'foo> A slight refinement of the MAGICCOOKIE=object() pattern. The primary advantage of symbol() is its repr(). They are also singletons. Repeated calls of symbol('name') will all re
| 1667 | |
| 1668 | |
| 1669 | class symbol(int): |
| 1670 | """A constant symbol. |
| 1671 | |
| 1672 | >>> symbol("foo") is symbol("foo") |
| 1673 | True |
| 1674 | >>> symbol("foo") |
| 1675 | <symbol 'foo> |
| 1676 | |
| 1677 | A slight refinement of the MAGICCOOKIE=object() pattern. The primary |
| 1678 | advantage of symbol() is its repr(). They are also singletons. |
| 1679 | |
| 1680 | Repeated calls of symbol('name') will all return the same instance. |
| 1681 | |
| 1682 | """ |
| 1683 | |
| 1684 | name: str |
| 1685 | |
| 1686 | symbols: Dict[str, symbol] = {} |
| 1687 | _lock = threading.Lock() |
| 1688 | |
| 1689 | def __new__( |
| 1690 | cls, |
| 1691 | name: str, |
| 1692 | doc: Optional[str] = None, |
| 1693 | canonical: Optional[int] = None, |
| 1694 | ) -> symbol: |
| 1695 | with cls._lock: |
| 1696 | sym = cls.symbols.get(name) |
| 1697 | if sym is None: |
| 1698 | assert isinstance(name, str) |
| 1699 | if canonical is None: |
| 1700 | canonical = hash(name) |
| 1701 | sym = int.__new__(symbol, canonical) |
| 1702 | sym.name = name |
| 1703 | if doc: |
| 1704 | sym.__doc__ = doc |
| 1705 | |
| 1706 | # NOTE: we should ultimately get rid of this global thing, |
| 1707 | # however, currently it is to support pickling. The best |
| 1708 | # change would be when we are on py3.11 at a minimum, we |
| 1709 | # switch to stdlib enum.IntFlag. |
| 1710 | cls.symbols[name] = sym |
| 1711 | else: |
| 1712 | if canonical and canonical != sym: |
| 1713 | raise TypeError( |
| 1714 | f"Can't replace canonical symbol for {name!r} " |
| 1715 | f"with new int value {canonical}" |
| 1716 | ) |
| 1717 | return sym |
| 1718 | |
| 1719 | def __reduce__(self): |
| 1720 | return symbol, (self.name, "x", int(self)) |
| 1721 | |
| 1722 | def __str__(self): |
| 1723 | return repr(self) |
| 1724 | |
| 1725 | def __repr__(self): |
| 1726 | return f"symbol({self.name!r})" |