Skip to content

Commit 9731afc

Browse files
committed
feat: Add data to dict/json output
We now add the following attributes to the base output (non-full) of `as_dict()` and therefore `as_json()` methods (serialization): - `public` - `imports` - `exports` - `runtime` - `deprecated` In full mode, we also add the following attributes: - `is_public` - `is_deprecated` - `is_private` - `is_class_private` - `is_special` - `is_imported` - `is_exported` - `is_wildcard_exposed` - `is_inherited`
1 parent 52c3dc8 commit 9731afc

4 files changed

Lines changed: 146 additions & 5 deletions

File tree

docs/schema.json

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,44 @@
8787
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.relative_package_filepath",
8888
"type": "string"
8989
},
90+
"public": {
91+
"title": "Whether the object was explicitly marked as public.",
92+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.public",
93+
"type": [
94+
"null",
95+
"boolean"
96+
]
97+
},
98+
"exports": {
99+
"title": "The exports of the object.",
100+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.exports",
101+
"type": [
102+
"null",
103+
"array"
104+
],
105+
"items": {
106+
"type": "string"
107+
}
108+
},
109+
"imports": {
110+
"title": "The imports of the object.",
111+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.imports",
112+
"type": "object"
113+
},
114+
"runtime": {
115+
"title": "Whether this object exists at runtime.",
116+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.runtime",
117+
"type": "boolean"
118+
},
119+
"deprecated": {
120+
"title": "Whether the object was explicitly marked as deprecated.",
121+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.deprecated",
122+
"type": [
123+
"null",
124+
"string",
125+
"boolean"
126+
]
127+
},
90128
"labels": {
91129
"title": "The labels of the object.",
92130
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.labels",
@@ -179,6 +217,51 @@
179217
"null"
180218
]
181219
},
220+
"is_public": {
221+
"title": "Whether the object is public.",
222+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_public",
223+
"type": "boolean"
224+
},
225+
"is_deprecated": {
226+
"title": "Whether the object is deprecated.",
227+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_deprecated",
228+
"type": "boolean"
229+
},
230+
"is_private": {
231+
"title": "Whether the object is private.",
232+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_private",
233+
"type": "boolean"
234+
},
235+
"is_class_private": {
236+
"title": "Whether the object is class-private.",
237+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_class_private",
238+
"type": "boolean"
239+
},
240+
"is_special": {
241+
"title": "Whether the object is special.",
242+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_special",
243+
"type": "boolean"
244+
},
245+
"is_imported": {
246+
"title": "Whether the object is imported.",
247+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_imported",
248+
"type": "boolean"
249+
},
250+
"is_exported": {
251+
"title": "Whether the object is exported.",
252+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_exported",
253+
"type": "boolean"
254+
},
255+
"is_wildcard_exposed": {
256+
"title": "Whether the object is wildcard-exposed.",
257+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_wildcard_exposed",
258+
"type": "boolean"
259+
},
260+
"is_inherited": {
261+
"title": "Whether the object is inherited.",
262+
"markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_inherited",
263+
"type": "boolean"
264+
},
182265
"bases": true,
183266
"decorators": true,
184267
"parameters": true,
@@ -195,6 +278,9 @@
195278
"filepath",
196279
"relative_filepath",
197280
"relative_package_filepath",
281+
"public",
282+
"runtime",
283+
"deprecated",
198284
"labels",
199285
"members"
200286
],

src/_griffe/encoders.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,12 @@ def _attach_parent_to_exprs(obj: Class | Function | Attribute | TypeAlias, paren
182182

183183

184184
def _load_module(obj_dict: dict[str, Any]) -> Module:
185-
module = Module(name=obj_dict["name"], filepath=Path(obj_dict["filepath"]), docstring=_load_docstring(obj_dict))
185+
module = Module(
186+
name=obj_dict["name"],
187+
filepath=Path(obj_dict["filepath"]),
188+
docstring=_load_docstring(obj_dict),
189+
runtime=obj_dict.get("runtime", True),
190+
)
186191
# YORE: Bump 2: Replace line with `members = obj_dict.get("members", {}).values()`.
187192
members = obj_dict.get("members", [])
188193
# YORE: Bump 2: Remove block.
@@ -193,6 +198,10 @@ def _load_module(obj_dict: dict[str, Any]) -> Module:
193198
module.set_member(module_member.name, module_member)
194199
_attach_parent_to_exprs(module_member, module)
195200
module.labels |= set(obj_dict.get("labels", ()))
201+
module.exports = obj_dict.get("exports")
202+
module.imports = obj_dict.get("imports", {})
203+
module.deprecated = obj_dict.get("deprecated")
204+
module.public = obj_dict.get("public")
196205
return module
197206

198207

@@ -205,6 +214,7 @@ def _load_class(obj_dict: dict[str, Any]) -> Class:
205214
decorators=_load_decorators(obj_dict),
206215
type_parameters=TypeParameters(*obj_dict["type_parameters"]),
207216
bases=obj_dict["bases"],
217+
runtime=obj_dict.get("runtime", True),
208218
)
209219
# YORE: Bump 2: Replace line with `members = obj_dict.get("members", {}).values()`.
210220
members = obj_dict.get("members", [])
@@ -216,6 +226,9 @@ def _load_class(obj_dict: dict[str, Any]) -> Class:
216226
class_.set_member(class_member.name, class_member)
217227
_attach_parent_to_exprs(class_member, class_)
218228
class_.labels |= set(obj_dict.get("labels", ()))
229+
class_.imports = obj_dict.get("imports", {})
230+
class_.deprecated = obj_dict.get("deprecated")
231+
class_.public = obj_dict.get("public")
219232
_attach_parent_to_exprs(class_, class_)
220233
return class_
221234

@@ -230,8 +243,11 @@ def _load_function(obj_dict: dict[str, Any]) -> Function:
230243
lineno=obj_dict["lineno"],
231244
endlineno=obj_dict.get("endlineno"),
232245
docstring=_load_docstring(obj_dict),
246+
runtime=obj_dict.get("runtime", True),
233247
)
234248
function.labels |= set(obj_dict.get("labels", ()))
249+
function.deprecated = obj_dict.get("deprecated")
250+
function.public = obj_dict.get("public")
235251
return function
236252

237253

@@ -245,6 +261,9 @@ def _load_attribute(obj_dict: dict[str, Any]) -> Attribute:
245261
annotation=obj_dict.get("annotation"),
246262
)
247263
attribute.labels |= set(obj_dict.get("labels", ()))
264+
attribute.runtime = obj_dict.get("runtime", True)
265+
attribute.deprecated = obj_dict.get("deprecated")
266+
attribute.public = obj_dict.get("public")
248267
return attribute
249268

250269

src/_griffe/mixins.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,17 +359,23 @@ def is_special(self) -> bool:
359359
@property
360360
def is_class_private(self) -> bool:
361361
"""Whether this object/alias is class-private (starts with `__` and is a class member)."""
362-
return self.parent and self.parent.is_class and self.name.startswith("__") and not self.name.endswith("__") # type: ignore[attr-defined]
362+
return (
363+
bool(self.parent) and self.parent.is_class and self.name.startswith("__") and not self.name.endswith("__") # type: ignore[attr-defined]
364+
)
363365

364366
@property
365367
def is_imported(self) -> bool:
366368
"""Whether this object/alias was imported from another module."""
367-
return self.parent and self.name in self.parent.imports # type: ignore[attr-defined]
369+
return bool(self.parent) and self.name in self.parent.imports # type: ignore[attr-defined]
368370

369371
@property
370372
def is_exported(self) -> bool:
371373
"""Whether this object/alias is exported (listed in `__all__`)."""
372-
return self.parent.is_module and bool(self.parent.exports and self.name in self.parent.exports) # type: ignore[attr-defined]
374+
return (
375+
bool(self.parent) # type: ignore[attr-defined]
376+
and self.parent.is_module # type: ignore[attr-defined]
377+
and bool(self.parent.exports and self.name in self.parent.exports) # type: ignore[attr-defined]
378+
)
373379

374380
@property
375381
def is_wildcard_exposed(self) -> bool:
@@ -388,7 +394,7 @@ def is_wildcard_exposed(self) -> bool:
388394
True or False.
389395
"""
390396
# If the object is not available at runtime or is not defined at the module level, it is not exposed.
391-
if not self.runtime or not self.parent.is_module: # type: ignore[attr-defined]
397+
if not self.runtime or not (bool(self.parent) and self.parent.is_module): # type: ignore[attr-defined]
392398
return False
393399

394400
# If the parent module defines `__all__`, the object is exposed if it is listed in it.

src/_griffe/models.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,12 @@ def as_dict(self, *, full: bool = False, **kwargs: Any) -> dict[str, Any]:
11901190
base: dict[str, Any] = {
11911191
"kind": self.kind,
11921192
"name": self.name,
1193+
"public": self.public,
1194+
"exports": self.exports and [str(export) for export in self.exports],
1195+
"imports": self.imports,
1196+
"runtime": self.runtime,
1197+
"deprecated": self.deprecated,
1198+
# TODO: Include `self.extra`?
11931199
}
11941200

11951201
if full:
@@ -1199,6 +1205,30 @@ def as_dict(self, *, full: bool = False, **kwargs: Any) -> dict[str, Any]:
11991205
"filepath": self.filepath,
12001206
"relative_filepath": self.relative_filepath,
12011207
"relative_package_filepath": self.relative_package_filepath,
1208+
"is_public": self.is_public,
1209+
"is_deprecated": self.is_deprecated,
1210+
"is_private": self.is_private,
1211+
"is_class_private": self.is_class_private,
1212+
"is_special": self.is_special,
1213+
"is_imported": self.is_imported,
1214+
"is_exported": self.is_exported,
1215+
"is_wildcard_exposed": self.is_wildcard_exposed,
1216+
"is_inherited": self.inherited,
1217+
# TODO: Add these properties?
1218+
# "is_alias": self.is_alias,
1219+
# "is_collection": self.is_collection,
1220+
# "is_module": self.is_module,
1221+
# "is_class": self.is_class,
1222+
# "is_function": self.is_function,
1223+
# "is_attribute": self.is_attribute,
1224+
# "is_type_alias": self.is_type_alias,
1225+
# "is_init_module": self.is_init_module,
1226+
# "is_package": self.is_package,
1227+
# "is_subpackage": self.is_subpackage,
1228+
# "is_namespace_package": self.is_namespace_package,
1229+
# "is_namespace_subpackage": self.is_namespace_subpackage,
1230+
# "has_docstring": self.has_docstring,
1231+
# "has_docstrings": self.has_docstrings,
12021232
},
12031233
)
12041234

0 commit comments

Comments
 (0)