use __dict__ directly in Node.__init__ instead of setattr

Write to self.__dict__ instead of calling setattr for each field
and attribute during node construction (~123K calls per compile).
Also branch on whether keyword attributes were passed to avoid
the dict.pop overhead in the common no-attributes case.
This commit is contained in:
tobymao 2026-03-21 23:24:47 -07:00
parent 6e1496ef8b
commit 32763b89ee
No known key found for this signature in database
GPG Key ID: 5B3B30F3BACB48DC

View File

@ -204,6 +204,7 @@ class Node(metaclass=NodeType):
def __init__(self, *fields: t.Any, **attributes: t.Any) -> None:
if self.abstract:
raise TypeError("abstract nodes are not instantiable")
d = self.__dict__
if fields:
if len(fields) != len(self.fields):
if not self.fields:
@ -213,11 +214,15 @@ class Node(metaclass=NodeType):
f" argument{'s' if len(self.fields) != 1 else ''}"
)
for name, arg in zip(self.fields, fields, strict=False):
setattr(self, name, arg)
for attr in self.attributes:
setattr(self, attr, attributes.pop(attr, None))
d[name] = arg
if attributes:
raise TypeError(f"unknown attribute {next(iter(attributes))!r}")
for attr in self.attributes:
d[attr] = attributes.pop(attr, None)
if attributes:
raise TypeError(f"unknown attribute {next(iter(attributes))!r}")
else:
for attr in self.attributes:
d[attr] = None
def iter_fields(
self,