Skip to content

Commit acca73d

Browse files
committed
Preserve class-local member definition order
`handle_class()` now uses a new _iter_class_members() helper that: - preserves class_.__dict__ definition order for class-local members - then appends additional visible members from dir()/getattr() so inherited or lazily exposed names are still seen That makes nested class discovery consistent with the earlier module-level fix, so the printer's topological sort now gets real definition order as its stable tie-break for nested classes too.
1 parent 49e181e commit acca73d

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

pybind11_stubgen/parser/mixins/parse.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ParserDispatchMixin(IParser):
4848
def handle_class(self, path: QualifiedName, class_: type) -> Class | None:
4949
base_classes = class_.__bases__
5050
result = Class(name=path[-1], bases=self.handle_bases(path, base_classes))
51-
for name, member in inspect.getmembers(class_):
51+
for name, member in self._iter_class_members(class_):
5252
obj = self.handle_class_member(
5353
QualifiedName([*path, Identifier(name)]), class_, member
5454
)
@@ -70,6 +70,30 @@ def handle_class(self, path: QualifiedName, class_: type) -> Class | None:
7070
raise AssertionError()
7171
return result
7272

73+
def _iter_class_members(self, class_: type):
74+
seen: set[str] = set()
75+
76+
# Iterate __dict__ keys for definition order, but resolve values
77+
# through getattr() so descriptors (staticmethod, properties, etc.)
78+
# are properly unwrapped — matching inspect.getmembers() semantics.
79+
for name in class_.__dict__:
80+
seen.add(name)
81+
try:
82+
value = getattr(class_, name)
83+
except AttributeError:
84+
continue
85+
yield name, value
86+
87+
# Append inherited or lazily exposed members from dir().
88+
for name in dir(class_):
89+
if name in seen:
90+
continue
91+
try:
92+
value = getattr(class_, name)
93+
except AttributeError:
94+
continue
95+
yield name, value
96+
7397
def handle_class_member(
7498
self, path: QualifiedName, class_: type, member: Any
7599
) -> Docstring | Alias | Class | list[Method] | Field | Property | None:

0 commit comments

Comments
 (0)