1# SPDX-License-Identifier: MIT OR Apache-2.0
2# This file is dual licensed under the terms of the Apache License, Version
3# 2.0, and the MIT License. See the LICENSE file in the root of this
4# repository for complete details.
5
6"""
7greenlet-specific code that pretends to be a `threading.local`.
8
9Fails to import if not running under greenlet.
10"""
11
12from __future__ import annotations
13
14from typing import Any
15from weakref import WeakKeyDictionary
16
17from greenlet import getcurrent
18
19
20class GreenThreadLocal:
21 """
22 threading.local() replacement for greenlets.
23 """
24
25 def __init__(self) -> None:
26 self.__dict__["_weakdict"] = WeakKeyDictionary()
27
28 def __getattr__(self, name: str) -> Any:
29 key = getcurrent()
30 try:
31 return self._weakdict[key][name]
32 except KeyError:
33 raise AttributeError(name) from None
34
35 def __setattr__(self, name: str, val: Any) -> None:
36 key = getcurrent()
37 self._weakdict.setdefault(key, {})[name] = val
38
39 def __delattr__(self, name: str) -> None:
40 key = getcurrent()
41 try:
42 del self._weakdict[key][name]
43 except KeyError:
44 raise AttributeError(name) from None