mark/structures: micro-optimize item.keywords/NodeKeywords
This commit is contained in:
parent
54811b24e2
commit
c4b9b14a44
|
@ -539,6 +539,8 @@ MARK_GEN = MarkGenerator(_ispytest=True)
|
||||||
|
|
||||||
@final
|
@final
|
||||||
class NodeKeywords(MutableMapping[str, Any]):
|
class NodeKeywords(MutableMapping[str, Any]):
|
||||||
|
__slots__ = ("node", "parent", "_markers")
|
||||||
|
|
||||||
def __init__(self, node: "Node") -> None:
|
def __init__(self, node: "Node") -> None:
|
||||||
self.node = node
|
self.node = node
|
||||||
self.parent = node.parent
|
self.parent = node.parent
|
||||||
|
@ -555,21 +557,36 @@ class NodeKeywords(MutableMapping[str, Any]):
|
||||||
def __setitem__(self, key: str, value: Any) -> None:
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
self._markers[key] = value
|
self._markers[key] = value
|
||||||
|
|
||||||
|
# Note: we could've avoided explicitly implementing some of the methods
|
||||||
|
# below and use the collections.abc fallback, but that would be slow.
|
||||||
|
|
||||||
|
def __contains__(self, key: object) -> bool:
|
||||||
|
return (
|
||||||
|
key in self._markers
|
||||||
|
or self.parent is not None
|
||||||
|
and key in self.parent.keywords
|
||||||
|
)
|
||||||
|
|
||||||
|
def update( # type: ignore[override]
|
||||||
|
self,
|
||||||
|
other: Union[Mapping[str, Any], Iterable[Tuple[str, Any]]] = (),
|
||||||
|
**kwds: Any,
|
||||||
|
) -> None:
|
||||||
|
self._markers.update(other)
|
||||||
|
self._markers.update(kwds)
|
||||||
|
|
||||||
def __delitem__(self, key: str) -> None:
|
def __delitem__(self, key: str) -> None:
|
||||||
raise ValueError("cannot delete key in keywords dict")
|
raise ValueError("cannot delete key in keywords dict")
|
||||||
|
|
||||||
def __iter__(self) -> Iterator[str]:
|
def __iter__(self) -> Iterator[str]:
|
||||||
seen = self._seen()
|
yield from self._markers
|
||||||
return iter(seen)
|
|
||||||
|
|
||||||
def _seen(self) -> Set[str]:
|
|
||||||
seen = set(self._markers)
|
|
||||||
if self.parent is not None:
|
if self.parent is not None:
|
||||||
seen.update(self.parent.keywords)
|
yield from self.parent.keywords
|
||||||
return seen
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int:
|
||||||
return len(self._seen())
|
return len(self._markers) + (
|
||||||
|
len(self.parent.keywords) if self.parent is not None else 0
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<NodeKeywords for node {self.node}>"
|
return f"<NodeKeywords for node {self.node}>"
|
||||||
|
|
Loading…
Reference in New Issue