diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7168992..6c40342 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,12 +46,12 @@ jobs: fail-fast: false matrix: python: [ - "3.8", - "3.9", "3.10", "3.11", "3.12", "3.13", + "3.14", + "3.15", ] steps: diff --git a/mypy_extensions.py b/mypy_extensions.py index 1910000..891766b 100644 --- a/mypy_extensions.py +++ b/mypy_extensions.py @@ -45,6 +45,13 @@ def _typeddict_new(cls, _typename, _fields=None, **kwargs): return _TypedDictMeta(_typename, (), ns, _from_functional_call=True) +def _get_own_annotations(tp): + if sys.version_info >= (3, 14): + import annotationlib + return annotationlib.get_annotations(tp) + return tp.__dict__.get('__annotations__', {}) + + class _TypedDictMeta(type): def __new__(cls, name, bases, ns, total=True, _from_functional_call=False): # Create new typed dict class object. @@ -71,11 +78,15 @@ def __new__(cls, name, bases, ns, total=True, _from_functional_call=False): ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns) - anns = ns.get('__annotations__', {}) + if '__annotations__' in ns: + anns = ns['__annotations__'] + else: + # Python 3.14+ evaluates class annotations lazily (PEP 649) + anns = _get_own_annotations(tp_dict) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" anns = {n: _type_check(tp, msg) for n, tp in anns.items()} for base in bases: - anns.update(base.__dict__.get('__annotations__', {})) + anns.update(_get_own_annotations(base)) tp_dict.__annotations__ = anns if not hasattr(tp_dict, '__total__'): tp_dict.__total__ = total diff --git a/pyproject.toml b/pyproject.toml index 9cce176..4f3d56d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,15 +16,15 @@ classifiers = [ "Environment :: Console", "Intended Audience :: Developers", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Topic :: Software Development", ] -requires-python = ">=3.8" +requires-python = ">=3.10" [project.urls] Homepage = "https://github.com/python/mypy_extensions" diff --git a/tox.ini b/tox.ini index 3412839..8a56f3b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] minversion = 4.4.4 skip_missing_interpreters = true -envlist = py38, py39, py310, py311, py312, py313 +envlist = py310, py311, py312, py313, py314, py315 [testenv] description = run the test driver with {basepython}