Skip to content

Commit

Permalink
add _contextvars for proper naming
Browse files Browse the repository at this point in the history
On 3.9 and lower, the contextvars types call themselves builtins.*
which we can't and won't match. This improves naming fidelity for
3.10 and newer.
  • Loading branch information
tungol committed Nov 7, 2024
1 parent 951c0b8 commit 2525094
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 66 deletions.
2 changes: 1 addition & 1 deletion stdlib/@tests/stubtest_allowlists/common.txt
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ codecs.CodecInfo.streamreader
codecs.CodecInfo.streamwriter

collections.UserList.sort # Runtime has *args but will error if any are supplied
contextvars.Context.__init__ # C signature is broader than what is actually accepted
_?contextvars.Context.__init__ # C signature is broader than what is actually accepted

# The Dialect properties are initialized as None in Dialect but their values are enforced in _Dialect
csv.Dialect.delimiter
Expand Down
1 change: 0 additions & 1 deletion stdlib/@tests/stubtest_allowlists/py311.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ weakref.ProxyType.__reversed__ # Doesn't really exist
# C signature is broader than what is actually accepted
ast.ExtSlice.__new__
ast.Index.__new__
contextvars.Context.__init__

# Undocumented implementation details
cgi.FieldStorage.bufsize
Expand Down
1 change: 0 additions & 1 deletion stdlib/@tests/stubtest_allowlists/py312.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ sys.last_exc
# C signature is broader than what is actually accepted
ast.ExtSlice.__new__
ast.Index.__new__
contextvars.Context.__init__

# Treated an alias of a typing class in the stubs,
# they are generic to type checkers anyway.
Expand Down
1 change: 0 additions & 1 deletion stdlib/@tests/stubtest_allowlists/py313.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ sys.last_exc
# C signature is broader than what is actually accepted
ast.ExtSlice.__new__
ast.Index.__new__
contextvars.Context.__init__

# Treated an alias of a typing class in the stubs,
# they are generic to type checkers anyway.
Expand Down
2 changes: 1 addition & 1 deletion stdlib/@tests/stubtest_allowlists/py38.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ tkinter.Tcl
tkinter.Tk.__init__

# Exists at runtime, but missing from stubs
contextvars.ContextVar.__class_getitem__
_?contextvars.ContextVar.__class_getitem__
datetime.datetime_CAPI
dummy_threading.ExceptHookArgs
dummy_threading.Lock
Expand Down
1 change: 1 addition & 0 deletions stdlib/VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ _codecs: 3.0-
_collections_abc: 3.3-
_compat_pickle: 3.1-
_compression: 3.5-
_contextvars: 3.7-
_csv: 3.0-
_ctypes: 3.0-
_curses: 3.0-
Expand Down
61 changes: 61 additions & 0 deletions stdlib/_contextvars.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import sys
from collections.abc import Callable, Iterator, Mapping
from typing import Any, ClassVar, Generic, TypeVar, final, overload
from typing_extensions import ParamSpec

if sys.version_info >= (3, 9):
from types import GenericAlias

_T = TypeVar("_T")
_D = TypeVar("_D")
_P = ParamSpec("_P")

@final
class ContextVar(Generic[_T]):
@overload
def __init__(self, name: str) -> None: ...
@overload
def __init__(self, name: str, *, default: _T) -> None: ...
def __hash__(self) -> int: ...
@property
def name(self) -> str: ...
@overload
def get(self) -> _T: ...
@overload
def get(self, default: _T, /) -> _T: ...
@overload
def get(self, default: _D, /) -> _D | _T: ...
def set(self, value: _T, /) -> Token[_T]: ...
def reset(self, token: Token[_T], /) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

@final
class Token(Generic[_T]):
@property
def var(self) -> ContextVar[_T]: ...
@property
def old_value(self) -> Any: ... # returns either _T or MISSING, but that's hard to express
MISSING: ClassVar[object]
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

def copy_context() -> Context: ...

# It doesn't make sense to make this generic, because for most Contexts each ContextVar will have
# a different value.
@final
class Context(Mapping[ContextVar[Any], Any]):
def __init__(self) -> None: ...
@overload
def get(self, key: ContextVar[_T], default: None = None, /) -> _T | None: ...
@overload
def get(self, key: ContextVar[_T], default: _T, /) -> _T: ...
@overload
def get(self, key: ContextVar[_T], default: _D, /) -> _T | _D: ...
def run(self, callable: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> _T: ...
def copy(self) -> Context: ...
def __getitem__(self, key: ContextVar[_T], /) -> _T: ...
def __iter__(self) -> Iterator[ContextVar[Any]]: ...
def __len__(self) -> int: ...
def __eq__(self, value: object, /) -> bool: ...
62 changes: 1 addition & 61 deletions stdlib/contextvars.pyi
Original file line number Diff line number Diff line change
@@ -1,63 +1,3 @@
import sys
from collections.abc import Callable, Iterator, Mapping
from typing import Any, ClassVar, Generic, TypeVar, final, overload
from typing_extensions import ParamSpec

if sys.version_info >= (3, 9):
from types import GenericAlias
from _contextvars import Context as Context, ContextVar as ContextVar, Token as Token, copy_context as copy_context

__all__ = ("Context", "ContextVar", "Token", "copy_context")

_T = TypeVar("_T")
_D = TypeVar("_D")
_P = ParamSpec("_P")

@final
class ContextVar(Generic[_T]):
@overload
def __init__(self, name: str) -> None: ...
@overload
def __init__(self, name: str, *, default: _T) -> None: ...
def __hash__(self) -> int: ...
@property
def name(self) -> str: ...
@overload
def get(self) -> _T: ...
@overload
def get(self, default: _T, /) -> _T: ...
@overload
def get(self, default: _D, /) -> _D | _T: ...
def set(self, value: _T, /) -> Token[_T]: ...
def reset(self, token: Token[_T], /) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

@final
class Token(Generic[_T]):
@property
def var(self) -> ContextVar[_T]: ...
@property
def old_value(self) -> Any: ... # returns either _T or MISSING, but that's hard to express
MISSING: ClassVar[object]
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

def copy_context() -> Context: ...

# It doesn't make sense to make this generic, because for most Contexts each ContextVar will have
# a different value.
@final
class Context(Mapping[ContextVar[Any], Any]):
def __init__(self) -> None: ...
@overload
def get(self, key: ContextVar[_T], default: None = None, /) -> _T | None: ...
@overload
def get(self, key: ContextVar[_T], default: _T, /) -> _T: ...
@overload
def get(self, key: ContextVar[_T], default: _D, /) -> _T | _D: ...
def run(self, callable: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> _T: ...
def copy(self) -> Context: ...
def __getitem__(self, key: ContextVar[_T], /) -> _T: ...
def __iter__(self) -> Iterator[ContextVar[Any]]: ...
def __len__(self) -> int: ...
def __eq__(self, value: object, /) -> bool: ...

0 comments on commit 2525094

Please sign in to comment.