def collect(cls: _Value, *, w: Walker) -> _Value: props = {} for name, typeinfo, metadata in w.walk_fields(cls): fieldname = w.resolver.metadata.resolve_name(metadata, default=name) value = getattr(cls, name, None) if value is None: value = typeinfo.raw props[fieldname] = collect(value, w=w) return props
def _mark_recursive( w: Walker, members: t.List[Member], *, seen: t.Set[t.Type[t.Any]], guess_member: GuessMemberFunc, ) -> t.Iterable[t.Type[t.Any]]: from collections import deque q: t.Deque[t.Type[t.Any]] = deque() for m in members: q.append(m) while True: try: m = q.popleft() except IndexError: break if m in seen: continue seen.add(m) yield m kind = guess_member(m) if kind != "object": logger.debug("skip recursive walk, kind=%r, type=%r", kind, m) assert kind is not None mark(m, kind=kind) continue for _, info, _ in w.walk_fields(m): if info.type_ in seen: continue for x in info.args or [info]: if x.type_ in seen: continue kind = guess_member(x.type_) if kind is None: continue mark(x.type_, kind=kind) yield x.type_ q.append(x.type_)
def scan(walker: Walker) -> Context: ctx = Context(walker) resolver = ctx.walker.resolver result = ctx.result scanned = _scan(walker) for enum in scanned.enums: result.enums[enum.__name__] = enum for cls in scanned.objects: schema = make_dict() typename = resolver.resolve_typename(cls) for field_name, info, metadata in walker.walk_fields(cls): field_name = resolver.metadata.resolve_name(metadata, default=field_name) prop = {"type": (scanned.get_name(info.type_) or detect.schema_type(info))} resolver.metadata.fill_extra_metadata(prop, metadata, name="graphql") schema[field_name] = prop result.types[typename] = schema return ctx