mkdocstrings-matlab 0.1.7__py2.py3-none-any.whl → 0.2.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mkdocstrings_handlers/matlab/handler.py +126 -35
- mkdocstrings_handlers/matlab/matlab/+docstring/+case/builtin.m +25 -6
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m +7 -2
- mkdocstrings_handlers/matlab/matlab/+docstring/resolve.m +1 -1
- mkdocstrings_handlers/matlab/models.py +1 -1
- {mkdocstrings_matlab-0.1.7.dist-info → mkdocstrings_matlab-0.2.1.dist-info}/METADATA +1 -1
- {mkdocstrings_matlab-0.1.7.dist-info → mkdocstrings_matlab-0.2.1.dist-info}/RECORD +9 -9
- {mkdocstrings_matlab-0.1.7.dist-info → mkdocstrings_matlab-0.2.1.dist-info}/WHEEL +0 -0
- {mkdocstrings_matlab-0.1.7.dist-info → mkdocstrings_matlab-0.2.1.dist-info}/licenses/LICENSE +0 -0
@@ -10,6 +10,7 @@ from pprint import pprint
|
|
10
10
|
|
11
11
|
import charset_normalizer
|
12
12
|
import json
|
13
|
+
import requests
|
13
14
|
|
14
15
|
|
15
16
|
from mkdocstrings_handlers.matlab.collections import LinesCollection, ModelsCollection
|
@@ -60,7 +61,8 @@ class MatlabHandler(BaseHandler):
|
|
60
61
|
# "find_stubs_package": False,
|
61
62
|
# "allow_inspection": True,
|
62
63
|
"show_bases": True,
|
63
|
-
"show_inheritance_diagram":
|
64
|
+
"show_inheritance_diagram": True,
|
65
|
+
"inheritance_diagram_show_builtin": False,
|
64
66
|
"show_source": True,
|
65
67
|
# "preload_modules": None,
|
66
68
|
# Heading options
|
@@ -143,6 +145,50 @@ class MatlabHandler(BaseHandler):
|
|
143
145
|
# (it assumes the python handler is installed)
|
144
146
|
return super().get_templates_dir("python")
|
145
147
|
|
148
|
+
def get_ast(self, identifier:str, config: Mapping[str, Any]) -> dict:
|
149
|
+
"""Retrieve the Abstract Syntax Tree (AST) for a given MATLAB identifier.
|
150
|
+
|
151
|
+
This method resolves the docstring for the specified identifier and parses it into an AST.
|
152
|
+
If the identifier corresponds to a class, it processes its superclasses and optionally
|
153
|
+
includes an inheritance diagram based on the provided configuration.
|
154
|
+
Args:
|
155
|
+
identifier (str): The MATLAB identifier to resolve.
|
156
|
+
config (Mapping[str, Any]): Configuration options for processing the AST.
|
157
|
+
Returns:
|
158
|
+
dict: The parsed AST for the given identifier.
|
159
|
+
Raises:
|
160
|
+
MatlabExecutionError: If there is an error resolving the superclass AST.
|
161
|
+
"""
|
162
|
+
|
163
|
+
ast_json = self.engine.docstring.resolve(identifier)
|
164
|
+
ast = json.loads(ast_json)
|
165
|
+
|
166
|
+
if ast['type'] == 'class':
|
167
|
+
|
168
|
+
if isinstance(ast["superclasses"], str):
|
169
|
+
ast["superclasses"] = [ast["superclasses"]]
|
170
|
+
if isinstance(ast["properties"], dict):
|
171
|
+
ast["properties"] = [ast["properties"]]
|
172
|
+
if isinstance(ast["methods"], dict):
|
173
|
+
ast["methods"] = [ast["methods"]]
|
174
|
+
|
175
|
+
if config["show_inheritance_diagram"]:
|
176
|
+
# Check if class is builtin and skip superclasses if option is not set
|
177
|
+
builtin = ast.get('builtin', False) or ast["name"].startswith("matlab.")
|
178
|
+
resursive = not builtin or config["inheritance_diagram_show_builtin"]
|
179
|
+
if not resursive:
|
180
|
+
ast["superclasses"] = []
|
181
|
+
|
182
|
+
# Get superclasses AST
|
183
|
+
for index, base in enumerate(ast["superclasses"]):
|
184
|
+
try:
|
185
|
+
ast["superclasses"][index] = self.get_ast(base, config)
|
186
|
+
ast["superclasses"][index]["name"] = base
|
187
|
+
except MatlabExecutionError:
|
188
|
+
ast["superclasses"][index] = {"name": base}
|
189
|
+
return ast
|
190
|
+
|
191
|
+
|
146
192
|
def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem:
|
147
193
|
"""Collect data given an identifier and user configuration.
|
148
194
|
|
@@ -156,26 +202,28 @@ class MatlabHandler(BaseHandler):
|
|
156
202
|
Returns:
|
157
203
|
CollectorItem
|
158
204
|
"""
|
205
|
+
if identifier == "":
|
206
|
+
raise CollectionError("Empty identifier")
|
207
|
+
|
159
208
|
final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
|
160
209
|
if identifier in self.models:
|
161
210
|
return self.models[identifier]
|
162
211
|
|
163
212
|
try:
|
164
|
-
|
213
|
+
ast = self.get_ast(identifier, final_config)
|
165
214
|
except MatlabExecutionError as error:
|
166
215
|
raise CollectionError(error.args[0].strip()) from error
|
167
|
-
ast_dict = json.loads(ast_json)
|
168
216
|
|
169
|
-
filepath = Path(
|
217
|
+
filepath = Path(ast["path"])
|
170
218
|
if filepath not in self.lines:
|
171
219
|
lines = str(charset_normalizer.from_path(filepath).best()).splitlines()
|
172
220
|
self.lines[filepath] = lines
|
173
221
|
|
174
|
-
match
|
222
|
+
match ast["type"]:
|
175
223
|
case "function" | "method":
|
176
|
-
return self.collect_function(
|
224
|
+
return self.collect_function(ast, final_config)
|
177
225
|
case "class":
|
178
|
-
return self.collect_class(
|
226
|
+
return self.collect_class(ast, final_config)
|
179
227
|
case _:
|
180
228
|
return None
|
181
229
|
|
@@ -247,15 +295,11 @@ class MatlabHandler(BaseHandler):
|
|
247
295
|
lambda template_name: template_name in self.env.list_templates()
|
248
296
|
)
|
249
297
|
|
250
|
-
def collect_class(self,
|
251
|
-
docstring = (
|
252
|
-
Docstring(ast_dict["docstring"], parser=config["docstring_style"])
|
253
|
-
if ast_dict["docstring"]
|
254
|
-
else None
|
255
|
-
)
|
298
|
+
def collect_class(self, ast: dict, config: Mapping) -> Class:
|
256
299
|
|
257
|
-
filepath = Path(
|
300
|
+
filepath = Path(ast["path"])
|
258
301
|
|
302
|
+
# Parse textmate object
|
259
303
|
if config["show_source"]:
|
260
304
|
tmObject = self.parser.parse_file(filepath)
|
261
305
|
tmClass = next(
|
@@ -266,18 +310,24 @@ class MatlabHandler(BaseHandler):
|
|
266
310
|
else:
|
267
311
|
tmClass = None
|
268
312
|
|
269
|
-
|
270
|
-
|
271
|
-
|
313
|
+
# Get bases
|
314
|
+
if config["show_bases"]:
|
315
|
+
if config["show_inheritance_diagram"]:
|
316
|
+
bases = [base["name"] for base in ast["superclasses"]]
|
317
|
+
else:
|
318
|
+
bases = ast["superclasses"] if isinstance(ast["superclasses"], list) else [ast["superclasses"]]
|
319
|
+
else:
|
320
|
+
bases = []
|
321
|
+
|
322
|
+
# Load model
|
272
323
|
model = Class(
|
273
|
-
|
274
|
-
docstring=docstring,
|
324
|
+
ast["name"],
|
275
325
|
parent=self.get_parent(filepath.parent),
|
276
|
-
hidden=
|
277
|
-
sealed=
|
278
|
-
abstract=
|
279
|
-
enumeration=
|
280
|
-
handle=
|
326
|
+
hidden=ast["hidden"],
|
327
|
+
sealed=ast["sealed"],
|
328
|
+
abstract=ast["abstract"],
|
329
|
+
enumeration=ast["enumeration"],
|
330
|
+
handle=ast["handle"],
|
281
331
|
bases=bases,
|
282
332
|
filepath=filepath,
|
283
333
|
modules_collection=self.models,
|
@@ -286,8 +336,21 @@ class MatlabHandler(BaseHandler):
|
|
286
336
|
endlineno=len(self.lines[filepath]),
|
287
337
|
textmate=tmClass,
|
288
338
|
)
|
339
|
+
ast["name"] = model.canonical_path
|
340
|
+
|
341
|
+
# Format mermaid inheritance diagram
|
342
|
+
if config["show_inheritance_diagram"] and ast["superclasses"]:
|
343
|
+
section = get_inheritance_diagram(ast)
|
344
|
+
docstring = Docstring(ast["docstring"] + section, parser=config["docstring_style"])
|
345
|
+
elif ast["docstring"]:
|
346
|
+
docstring = Docstring(ast["docstring"], parser=config["docstring_style"])
|
347
|
+
else:
|
348
|
+
docstring = None
|
289
349
|
|
290
|
-
|
350
|
+
model.docstring = docstring
|
351
|
+
|
352
|
+
# Load properties
|
353
|
+
for property_dict in ast["properties"]:
|
291
354
|
name = property_dict.pop("name")
|
292
355
|
defining_class = property_dict.pop("class")
|
293
356
|
property_doc = property_dict.pop("docstring")
|
@@ -306,7 +369,8 @@ class MatlabHandler(BaseHandler):
|
|
306
369
|
model.members[name] = prop
|
307
370
|
self.models[prop.canonical_path] = prop
|
308
371
|
|
309
|
-
|
372
|
+
# Load methods
|
373
|
+
for method_dict in ast["methods"]:
|
310
374
|
name = method_dict.pop("name")
|
311
375
|
defining_class = method_dict.pop("class")
|
312
376
|
if (
|
@@ -330,20 +394,21 @@ class MatlabHandler(BaseHandler):
|
|
330
394
|
if config["merge_init_into_class"] and model.name in model.members:
|
331
395
|
constructor = model.members.pop(model.name)
|
332
396
|
model.members["__init__"] = constructor
|
333
|
-
|
397
|
+
|
398
|
+
if getattr(constructor.docstring, 'value', '') == getattr(model.docstring, 'value', ''):
|
334
399
|
model.docstring = None
|
335
400
|
|
336
401
|
self.models[model.canonical_path] = model
|
337
402
|
|
338
403
|
return model
|
339
404
|
|
340
|
-
def collect_function(self,
|
405
|
+
def collect_function(self, ast: dict, config: Mapping) -> Function:
|
341
406
|
parameters = []
|
342
407
|
|
343
408
|
inputs = (
|
344
|
-
|
345
|
-
if isinstance(
|
346
|
-
else [
|
409
|
+
ast["inputs"]
|
410
|
+
if isinstance(ast["inputs"], list)
|
411
|
+
else [ast["inputs"]]
|
347
412
|
)
|
348
413
|
for input_dict in inputs:
|
349
414
|
if input_dict["name"] == "varargin":
|
@@ -362,16 +427,16 @@ class MatlabHandler(BaseHandler):
|
|
362
427
|
)
|
363
428
|
)
|
364
429
|
|
365
|
-
filepath = Path(
|
430
|
+
filepath = Path(ast["path"])
|
366
431
|
model = Function(
|
367
|
-
|
432
|
+
ast["name"],
|
368
433
|
parameters=Parameters(*parameters),
|
369
434
|
docstring=Docstring(
|
370
|
-
|
435
|
+
ast["docstring"],
|
371
436
|
parser=config["docstring_style"],
|
372
437
|
parser_options=config["docstring_options"],
|
373
438
|
)
|
374
|
-
if
|
439
|
+
if ast["docstring"]
|
375
440
|
else None,
|
376
441
|
parent=self.get_parent(filepath.parent),
|
377
442
|
filepath=filepath,
|
@@ -409,6 +474,32 @@ class MatlabHandler(BaseHandler):
|
|
409
474
|
parent = ROOT
|
410
475
|
return parent
|
411
476
|
|
477
|
+
def get_inheritance_diagram(ast: dict) -> str:
|
478
|
+
def get_id(str: str) -> str:
|
479
|
+
return str.replace('.', '_')
|
480
|
+
def get_nodes(ast: dict, nodes: set[str] = set(), clicks: set[str] = set()) -> str:
|
481
|
+
id = get_id(ast['name'])
|
482
|
+
nodes.add(f" {id}[{ast['name']}]")
|
483
|
+
if "help" in ast:
|
484
|
+
clicks.add(f" click {id} \"{ast['help']}\"")
|
485
|
+
if "superclasses" in ast:
|
486
|
+
for superclass in ast["superclasses"]:
|
487
|
+
get_nodes(superclass, nodes)
|
488
|
+
return (nodes, clicks)
|
489
|
+
def get_links(ast: dict, links: set[str] = set()) -> str:
|
490
|
+
if "superclasses" in ast:
|
491
|
+
for superclass in ast["superclasses"]:
|
492
|
+
links.add(f" {get_id(ast['name'])} --> {get_id(superclass['name'])}")
|
493
|
+
get_links(superclass, links)
|
494
|
+
return links
|
495
|
+
|
496
|
+
(nodes, clicks) = get_nodes(ast)
|
497
|
+
nodes_str = '\n'.join(list(nodes))
|
498
|
+
clicks_str = '\n'.join(list(clicks))
|
499
|
+
links_str = '\n'.join(list(get_links(ast)))
|
500
|
+
section = f"\n\n## Inheritance diagram\n\n```mermaid\nflowchart BT\n{nodes_str}\n{clicks_str}\n{links_str}\n```"
|
501
|
+
return section
|
502
|
+
|
412
503
|
|
413
504
|
def get_handler(
|
414
505
|
*,
|
@@ -1,8 +1,27 @@
|
|
1
1
|
function data = builtin(identifier)
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
if isMATLABReleaseOlderThan('R2024a')
|
3
|
+
metaclass = @meta.class.fromName;
|
4
|
+
else
|
5
|
+
metaclass = @matlab.metadata.Class.fromName;
|
6
|
+
end
|
7
|
+
|
8
|
+
object = metaclass(identifier);
|
9
|
+
|
10
|
+
if isempty(object)
|
11
|
+
data.name = identifier;
|
12
|
+
data.type = 'function';
|
13
|
+
data.doc = help(identifier);
|
14
|
+
data.location = string(which(identifier));
|
15
|
+
data.inputs = struct.empty();
|
16
|
+
data.outputs = struct.empty();
|
17
|
+
if ~contains(identifier, '.internal.')
|
18
|
+
data.help = sprintf('https://mathworks.com/help/matlab/ref/%s.html', lower(identifier));
|
19
|
+
end
|
20
|
+
else
|
21
|
+
data = docstring.metadata.class(object, 'builtin', true);
|
22
|
+
if ~contains(identifier, '.internal.')
|
23
|
+
data.help = sprintf('https://mathworks.com/help/matlab/ref/%s-class.html', lower(identifier));
|
24
|
+
end
|
25
|
+
end
|
26
|
+
data.builtin = true;
|
8
27
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
function data = class(object)
|
1
|
+
function data = class(object, opts)
|
2
2
|
arguments
|
3
3
|
object (1,1) % meta.class matlab.metadata.Class
|
4
|
+
opts.builtin (1,1) logical = false
|
4
5
|
end
|
5
6
|
data.type = 'class';
|
6
7
|
|
@@ -8,7 +9,6 @@ function data = class(object)
|
|
8
9
|
data.name = namespaces{end};
|
9
10
|
|
10
11
|
data.docstring = docstring.utils.parse_doc(object);
|
11
|
-
data.path = matlab.internal.metafunction(object.Name).Location;
|
12
12
|
data.hidden = object.Hidden;
|
13
13
|
data.sealed = object.Sealed;
|
14
14
|
data.abstract = object.Abstract;
|
@@ -16,6 +16,11 @@ function data = class(object)
|
|
16
16
|
data.superclasses = arrayfun(@(o) string(o.Name), object.SuperclassList);
|
17
17
|
data.handle = object.HandleCompatible;
|
18
18
|
data.aliases = object.Aliases;
|
19
|
+
if opts.builtin
|
20
|
+
data.path = '';
|
21
|
+
else
|
22
|
+
data.path = matlab.internal.metafunction(object.Name).Location;
|
23
|
+
end
|
19
24
|
|
20
25
|
data.methods = [];
|
21
26
|
for methodObject = object.MethodList'
|
@@ -46,7 +46,7 @@ if contains(identifier, '.')
|
|
46
46
|
end
|
47
47
|
|
48
48
|
% Try built-in aliases with which
|
49
|
-
if contains(which(identifier), ' built-in ')
|
49
|
+
if contains(which(identifier), {' built-in ', matlabroot})
|
50
50
|
data = docstring.case.builtin(identifier);
|
51
51
|
jsonString = jsonencode(data);
|
52
52
|
return
|
@@ -62,7 +62,7 @@ class Class(CanonicalPathMixin, PathMixin, GriffeClass):
|
|
62
62
|
for block in self._textmate.children
|
63
63
|
if block.token == "meta.methods.matlab"
|
64
64
|
]:
|
65
|
-
for method in block.children:
|
65
|
+
for method in [c for c in block.children if c.token == "meta.function.matlab"]:
|
66
66
|
declaration = next(
|
67
67
|
item
|
68
68
|
for item in method.children
|
@@ -1,19 +1,19 @@
|
|
1
1
|
mkdocstrings_handlers/matlab/__init__.py,sha256=laA2bEP5rxdIWBLmfLiKKu7ChZ_HzCe-VeRvxmUTqww,128
|
2
2
|
mkdocstrings_handlers/matlab/collections.py,sha256=oiDK4nwIUXroIPxw6Cu13WcBxmCyAHjPn7naaW_Yhjs,445
|
3
|
-
mkdocstrings_handlers/matlab/handler.py,sha256=
|
4
|
-
mkdocstrings_handlers/matlab/models.py,sha256=
|
3
|
+
mkdocstrings_handlers/matlab/handler.py,sha256=k0tfPCQlAdK2Km48dOJWM8h857Ys5nQivJ28en994nw,20757
|
4
|
+
mkdocstrings_handlers/matlab/models.py,sha256=F8_kvZxEQbD0jwF-_6bO_ICK8T_DHsQv5e2LXY1rGOw,5694
|
5
5
|
mkdocstrings_handlers/matlab/parser.py,sha256=bA3KRNnYjSewqyJI8OmLKATk3AZOq9-28UQg0L6f9os,843
|
6
6
|
mkdocstrings_handlers/matlab/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
mkdocstrings_handlers/matlab/matlab/matlab_startup.m,sha256=rGXiR8fI2GW7yWmHxgzE5Un66n5ws3ogYnMvS2oWO8U,464
|
8
8
|
mkdocstrings_handlers/matlab/matlab/+docstring/exception.m,sha256=sj2ycqMpknn_OG5A5X_b5e4WcAoR2oPoqNnDEHJsi7c,222
|
9
|
-
mkdocstrings_handlers/matlab/matlab/+docstring/resolve.m,sha256=
|
10
|
-
mkdocstrings_handlers/matlab/matlab/+docstring/+case/builtin.m,sha256=
|
9
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/resolve.m,sha256=TOL_XmSflwkd3EiDK2PC8wlFCmhxbMW9N8SVgxiwDfk,3055
|
10
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+case/builtin.m,sha256=aU_SlPuyF2G0fiO4Gh2PrkeoE1umNPWuJI9iR26Ln-M,918
|
11
11
|
mkdocstrings_handlers/matlab/matlab/+docstring/+case/class.m,sha256=kVQxUEk8iOfHK2_NnN0HjHVhFnPgUqsf9PzyKC93y0g,276
|
12
12
|
mkdocstrings_handlers/matlab/matlab/+docstring/+case/func.m,sha256=QneDYSICtXqdPNq8sYNieirXUisuDKRM9rxPx-0osDU,137
|
13
13
|
mkdocstrings_handlers/matlab/matlab/+docstring/+case/method.m,sha256=Bw8Mb96OP7-AnbGnvRMySOIbYSTtEC1BGBnqHMEIhsM,165
|
14
14
|
mkdocstrings_handlers/matlab/matlab/+docstring/+case/namespace.m,sha256=ZpYrgZHLIdGvgg3F6210gDTska9YyASn63ZVYkBq41A,667
|
15
15
|
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/argument.m,sha256=yE1sywrr6Q0YjEkPkdBTjjkLeUrPv0jV-degM_EE_iE,1905
|
16
|
-
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m,sha256=
|
16
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m,sha256=zvOq3INtGZF65yaiTg0-YZ0jU55XrXcaDSFXQbosBuM,1787
|
17
17
|
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/func.m,sha256=k1gz4kjEQX5DCIfzCs1lee5jjAL4fg6A7LnwcUF8kRE,424
|
18
18
|
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/namespace.m,sha256=kMzfAoWIpMXH76rrkyUqauJSRIaylsfnu0Cds4pYnJc,481
|
19
19
|
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/property.m,sha256=rH3cHz66ZG9sUvDU2fhlyASSB_yp0SiHlbpB44fcFiY,1560
|
@@ -22,7 +22,7 @@ mkdocstrings_handlers/matlab/matlab/+docstring/+utils/dedent.m,sha256=IsqIZKyaBU
|
|
22
22
|
mkdocstrings_handlers/matlab/matlab/+docstring/+utils/get_namespace_path.m,sha256=4NlQ7-RjqIFZAn6P-9JzCrm2FvfGRKiM2M_leINj9i4,835
|
23
23
|
mkdocstrings_handlers/matlab/matlab/+docstring/+utils/parse_doc.m,sha256=iFNpbnOr9FAv-3Zn8ksJHIthXAB7XKYVfH2NGFinzHs,499
|
24
24
|
mkdocstrings_handlers/matlab/resources/grammar.yml,sha256=GLI4xdATiB70bzRscXOVwMlw0YFlA-3GJzuzqWeBKJU,19511
|
25
|
-
mkdocstrings_matlab-0.1.
|
26
|
-
mkdocstrings_matlab-0.1.
|
27
|
-
mkdocstrings_matlab-0.1.
|
28
|
-
mkdocstrings_matlab-0.1.
|
25
|
+
mkdocstrings_matlab-0.2.1.dist-info/METADATA,sha256=hQxu7qSPf15QcDG7yMsjZdht6QWSjfpT7FmBZ-O23Hk,549
|
26
|
+
mkdocstrings_matlab-0.2.1.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
|
27
|
+
mkdocstrings_matlab-0.2.1.dist-info/licenses/LICENSE,sha256=14xA0OIYNpfmdeuq8-Yyqg7-3IJ4qhu3BJhknent-cY,1069
|
28
|
+
mkdocstrings_matlab-0.2.1.dist-info/RECORD,,
|
File without changes
|
{mkdocstrings_matlab-0.1.7.dist-info → mkdocstrings_matlab-0.2.1.dist-info}/licenses/LICENSE
RENAMED
File without changes
|