Skip to content

Commit 4fa546d

Browse files
committed
Cope with Namespace annotations in Python 3.14
The __annotations__ member can be incomplete, use the get_annotations() helper from annotationlib (Python >= 3.14) or inspect (Python >= 3.10) if available. Related: #3083 Signed-off-by: Nils Philippsen <nils@tiptoe.de>
1 parent cfd4222 commit 4fa546d

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

rdflib/namespace/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@
7474

7575
import logging
7676
import warnings
77+
78+
try:
79+
# Python >= 3.14
80+
from annotationlib import get_annotations
81+
except ImportError: # pragma: no cover
82+
try:
83+
# Python >= 3.10
84+
from inspect import get_annotations
85+
except ImportError:
86+
def get_annotations(thing: Any) -> dict:
87+
return thing.__annotations__
88+
7789
from functools import lru_cache
7890
from pathlib import Path
7991
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Set, Tuple, Union
@@ -310,15 +322,15 @@ def __contains__(cls, item: str) -> bool:
310322
if item_str.startswith(str(this_ns)):
311323
item_str = item_str[len(str(this_ns)) :]
312324
return any(
313-
item_str in c.__annotations__
325+
item_str in get_annotations(c)
314326
or item_str in c._extras
315327
or (cls._underscore_num and item_str[0] == "_" and item_str[1:].isdigit())
316328
for c in cls.mro()
317329
if issubclass(c, DefinedNamespace)
318330
)
319331

320332
def __dir__(cls) -> Iterable[str]:
321-
attrs = {str(x) for x in cls.__annotations__}
333+
attrs = {str(x) for x in get_annotations(cls)}
322334
# Removing these as they should not be considered part of the namespace.
323335
attrs.difference_update(_DFNS_RESERVED_ATTRS)
324336
values = {cls[str(x)] for x in attrs}
@@ -327,7 +339,7 @@ def __dir__(cls) -> Iterable[str]:
327339
def as_jsonld_context(self, pfx: str) -> dict: # noqa: N804
328340
"""Returns this DefinedNamespace as a JSON-LD 'context' object"""
329341
terms = {pfx: str(self._NS)}
330-
for key, term in self.__annotations__.items():
342+
for key, term in get_annotations(self).items():
331343
if issubclass(term, URIRef):
332344
terms[key] = f"{pfx}:{key}"
333345

0 commit comments

Comments
 (0)