mkdocstrings-matlab 0.3.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,560 @@
1
+ from typing import Any, TYPE_CHECKING, Callable
2
+ from functools import cached_property
3
+ from pathlib import Path
4
+ from griffe import (
5
+ Attribute,
6
+ Function as GriffeFunction,
7
+ Class as GriffeClass,
8
+ Docstring as GriffeDocstring,
9
+ DocstringSection,
10
+ DocstringSectionText,
11
+ Module,
12
+ Object,
13
+ Parameters as GriffeParameters,
14
+ Parameter as GriffeParameter,
15
+ )
16
+
17
+ from mkdocstrings_handlers.matlab.enums import AccessEnum, ParameterKind
18
+
19
+ if TYPE_CHECKING:
20
+ from mkdocstrings_handlers.matlab.collect import PathCollection
21
+
22
+ __all__ = [
23
+ "Attribute",
24
+ "Class",
25
+ "Classfolder",
26
+ "Function",
27
+ "MatlabObject",
28
+ "MatlabMixin",
29
+ "Module",
30
+ "Docstring",
31
+ "DocstringSectionText",
32
+ "Namespace",
33
+ "Parameters",
34
+ "Parameter",
35
+ "Property",
36
+ "Script",
37
+ ]
38
+
39
+
40
+ class Docstring(GriffeDocstring):
41
+ """
42
+ A class to represent a docstring with additional sections.
43
+
44
+ This class extends the GriffeDocstring class to include extra sections
45
+ that can be added to the parsed docstring.
46
+
47
+ Attributes:
48
+ _extra_sections (list[DocstringSection]): A list to store additional docstring sections.
49
+
50
+ Methods:
51
+ parsed: Returns the parsed docstring sections combined with extra sections.
52
+ _parsed: Parses the docstring into structured data.
53
+ """
54
+
55
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
56
+ """
57
+ Initializes the Docstring object.
58
+
59
+ Args:
60
+ *args (Any): Variable length argument list.
61
+ **kwargs (Any): Arbitrary keyword arguments.
62
+ """
63
+ super().__init__(*args, **kwargs)
64
+ self._extra_sections: list[DocstringSection] = []
65
+
66
+ @property
67
+ def parsed(self) -> list[DocstringSection]:
68
+ """
69
+ The docstring sections, parsed into structured data.
70
+
71
+ Returns:
72
+ list[DocstringSection]: The combined list of parsed and extra docstring sections.
73
+ """
74
+ return self._parsed + self._extra_sections
75
+
76
+ @cached_property
77
+ def _parsed(self) -> list[DocstringSection]:
78
+ """
79
+ Parses the docstring into structured data.
80
+
81
+ Returns:
82
+ list[DocstringSection]: The parsed docstring sections.
83
+ """
84
+ return self.parse()
85
+
86
+
87
+ class _ParentGrabber:
88
+ """
89
+ A callable class that wraps a function to grab a parent MatlabObject.
90
+
91
+ Attributes:
92
+ _grabber (Callable[[], MatlabObject]): A callable that returns a MatlabObject.
93
+
94
+ Methods:
95
+ __call__(): Calls the grabber function and returns a MatlabObject.
96
+ """
97
+
98
+ def __init__(self, grabber: "Callable[[], Object]") -> None:
99
+ """
100
+ Initializes the _ParentGrabber with a grabber function.
101
+
102
+ Args:
103
+ grabber (Callable[[], MatlabObject]): A function that returns a MatlabObject.
104
+ """
105
+ self._grabber = grabber
106
+
107
+ @property
108
+ def parent(self) -> "Object":
109
+ """
110
+ Calls the grabber function and returns a MatlabObject.
111
+
112
+ Returns:
113
+ MatlabObject: The MatlabObject returned by the grabber function.
114
+ """
115
+ return self._grabber()
116
+
117
+
118
+ class MatlabObject(Object):
119
+ """
120
+ Represents a Matlab object with associated docstring, path collection, and parent object.
121
+
122
+ Attributes:
123
+ path_collection (PathCollection | None): The collection of paths related to the Matlab object.
124
+ """
125
+
126
+ def __init__(
127
+ self,
128
+ *args,
129
+ path_collection: "PathCollection | None" = None,
130
+ **kwargs,
131
+ ) -> None:
132
+ """
133
+ Initialize the object with the given parameters.
134
+
135
+ Args:
136
+ *args: Variable length argument list.
137
+ path_collection (PathCollection | None): The collection of paths related to the object.
138
+ **kwargs: Arbitrary keyword arguments.
139
+ """
140
+
141
+ self.path_collection: "PathCollection | None" = path_collection
142
+ lines_collection = (
143
+ path_collection.lines_collection if path_collection is not None else None
144
+ )
145
+ super().__init__(*args, lines_collection=lines_collection, **kwargs)
146
+
147
+ @property
148
+ def canonical_path(self) -> str:
149
+ """
150
+ The full dotted path of this object.
151
+
152
+ Returns:
153
+ str: The canonical path of the object.
154
+ """
155
+ if isinstance(self.parent, _Root):
156
+ return self.name
157
+
158
+ if isinstance(self.parent, MatlabObject):
159
+ parent = self.parent
160
+ else:
161
+ parent = getattr(self.parent, "model", self.parent)
162
+
163
+ if isinstance(parent, Classfolder) and self.name == parent.name:
164
+ if isinstance(parent.parent, _Root) or parent.parent is None:
165
+ return self.name
166
+ else:
167
+ return f"{parent.parent.canonical_path}.{self.name}"
168
+ else:
169
+ return f"{parent.canonical_path}.{self.name}" if parent else self.name
170
+
171
+
172
+ class _Root(MatlabObject):
173
+ """
174
+ A class representing the root object in a MATLAB structure.
175
+ All the objects that have the root object as parent are at the top level,
176
+ and can be called directly.
177
+ """
178
+
179
+ def __init__(self) -> None:
180
+ super().__init__("ROOT", parent=None)
181
+
182
+ def __repr__(self) -> str:
183
+ return "MATLABROOT"
184
+
185
+
186
+ ROOT = _Root()
187
+
188
+
189
+ class PathMixin(Object):
190
+ """
191
+ A mixin class that provides a filepath attribute and related functionality.
192
+
193
+ Attributes:
194
+ filepath (Path | None): The file path associated with the object. It can be None if no file path is provided.
195
+ """
196
+
197
+ def __init__(self, *args: Any, filepath: Path | None = None, **kwargs: Any) -> None:
198
+ self._filepath: Path | None = filepath
199
+
200
+ super().__init__(*args, **kwargs)
201
+
202
+ @property
203
+ def filepath(self) -> Path | None:
204
+ return self._filepath
205
+
206
+ def __repr__(self) -> str:
207
+ return f"{self.__class__.__name__}({self.name})"
208
+
209
+
210
+ class MatlabMixin(Object):
211
+ def __init__(
212
+ self,
213
+ *args: Any,
214
+ parent: "Class | Classfolder | Namespace | _Root | None" = None,
215
+ docstring: Docstring | None = None,
216
+ **kwargs: Any,
217
+ ):
218
+ self._parent: "Class | Classfolder | Namespace | _Root | _ParentGrabber | None" = parent
219
+ self._docstring: Docstring | None = docstring
220
+ super().__init__(*args, **kwargs)
221
+
222
+ @property
223
+ def parent(self) -> Object:
224
+ if isinstance(self._parent, MatlabMixin):
225
+ return self._parent
226
+ elif isinstance(self._parent, _ParentGrabber):
227
+ return self._parent.parent
228
+ else:
229
+ return ROOT
230
+
231
+ @parent.setter
232
+ def parent(self, value):
233
+ if value is not None:
234
+ self._parent = value
235
+
236
+ @property
237
+ def docstring(self) -> Docstring | None:
238
+ return self._docstring
239
+
240
+ @docstring.setter
241
+ def docstring(self, value: Docstring | None):
242
+ if value is not None:
243
+ self._docstring = value
244
+
245
+
246
+ class Parameter(MatlabMixin, GriffeParameter, MatlabObject):
247
+ """
248
+ Represents a parameter in a MATLAB object.
249
+
250
+ Inherits from:
251
+ MatlabObject: Base class for MATLAB objects.
252
+ GriffeParameter: Base class for parameters.
253
+
254
+ Attributes:
255
+ kind (ParameterKind | None): The kind of the parameter, which can be of type ParameterKind or None.
256
+ """
257
+
258
+ def __init__(
259
+ self, *args: Any, kind: ParameterKind | None = None, **kwargs: Any
260
+ ) -> None:
261
+ super().__init__(*args, **kwargs)
262
+ self.kind: ParameterKind | None = kind
263
+
264
+
265
+ class Parameters(MatlabMixin, GriffeParameters, MatlabObject):
266
+ """
267
+ A class to represent a collection of parameters.
268
+
269
+ Inherits from:
270
+ MatlabObject: Base class for MATLAB objects.
271
+ GriffeParameters: Base class for handling parameters.
272
+ """
273
+
274
+ def __init__(self, *parameters: Parameter, **kwargs: Any) -> None:
275
+ super().__init__(**kwargs)
276
+ self._params: list[Parameter] = list(parameters)
277
+
278
+
279
+ class Script(MatlabMixin, PathMixin, MatlabObject):
280
+ """
281
+ A class representing a MATLAB script.
282
+
283
+ This class inherits from `PathMixin` and `MatlabObject` to provide
284
+ functionality specific to MATLAB scripts.
285
+ """
286
+
287
+ pass
288
+
289
+
290
+ class Class(MatlabMixin, PathMixin, GriffeClass, MatlabObject):
291
+ """
292
+ Represents a MATLAB class with additional properties and methods for handling
293
+ MATLAB-specific features.
294
+
295
+ This class extends `PathMixin`, `MatlabObject`, and `GriffeClass` to provide
296
+ additional functionality for handling MATLAB class properties such as
297
+ abstract, hidden, and sealed attributes. It also provides methods to retrieve
298
+ parameters, inherited members, and labels.
299
+
300
+ Attributes:
301
+ abstract (bool): Indicates if the class is abstract.
302
+ hidden (bool): Indicates if the class is hidden.
303
+ sealed (bool): Indicates if the class is sealed.
304
+
305
+ Args:
306
+ *args (Any): Variable length argument list.
307
+ Abstract (bool, optional): Indicates if the class is abstract
308
+ Hidden (bool, optional): Indicates if the class is hidden
309
+ Sealed (bool, optional): Indicates if the class is sealed
310
+ """
311
+
312
+ def __init__(
313
+ self,
314
+ *args: Any,
315
+ Abstract: bool = False,
316
+ Hidden: bool = False,
317
+ Sealed: bool = False,
318
+ **kwargs: Any,
319
+ ) -> None:
320
+ super().__init__(*args, **kwargs)
321
+ self.abstract: bool = Abstract
322
+ self.hidden: bool = Hidden
323
+ self.sealed: bool = Sealed
324
+
325
+ @property
326
+ def parameters(self) -> Parameters:
327
+ """
328
+ Retrieve the parameters of the class by grabbing its constructor.
329
+
330
+ Returns:
331
+ Parameters: The parameters of the function if the current member is a function,
332
+ otherwise an empty Parameters object.
333
+ """
334
+ try:
335
+ member = self.all_members.get(self.name)
336
+ if isinstance(member, Function):
337
+ return member.parameters
338
+ return Parameters()
339
+ except KeyError:
340
+ return Parameters()
341
+
342
+ @property
343
+ def inherited_members(self) -> dict[str, MatlabObject]:
344
+ """
345
+ Retrieve a dictionary of inherited members from base classes.
346
+
347
+ This method iterates over the base classes in reverse order, resolves their models,
348
+ and collects members that are not already present in the current object's members.
349
+
350
+ Returns:
351
+ dict[str, MatlabObject]: A dictionary where the keys are member names and the values are the corresponding MatlabObject instances.
352
+ """
353
+
354
+ inherited_members = {}
355
+ for base in reversed(self.bases):
356
+ model = (
357
+ self.path_collection.resolve(str(base))
358
+ if self.path_collection
359
+ else None
360
+ )
361
+ if model is None:
362
+ # TODO Perhaps issue a warning here?
363
+ continue
364
+
365
+ for name, member in model.members.items():
366
+ if name not in self.members:
367
+ inherited_members[name] = member
368
+ return inherited_members
369
+
370
+ @property
371
+ def labels(self) -> set[str]:
372
+ labels = set()
373
+ if self.abstract:
374
+ labels.add("abstract")
375
+ if self.hidden:
376
+ labels.add("hidden")
377
+ if self.sealed:
378
+ labels.add("sealed")
379
+ return labels
380
+
381
+ @labels.setter
382
+ def labels(self, *args):
383
+ pass
384
+
385
+ @property
386
+ def is_private(self) -> bool:
387
+ return self.hidden
388
+
389
+ @property
390
+ def canonical_path(self) -> str:
391
+ if isinstance(self.parent, Classfolder):
392
+ return self.parent.canonical_path
393
+ else:
394
+ return super().canonical_path
395
+
396
+
397
+ class Classfolder(Class):
398
+ """
399
+ A class representing a MATLAB classfolder
400
+ """
401
+
402
+ pass
403
+
404
+
405
+ class Property(MatlabMixin, Attribute, MatlabObject):
406
+ def __init__(
407
+ self,
408
+ *args: Any,
409
+ AbortSet: bool = False,
410
+ Abstract: bool = False,
411
+ Constant: bool = False,
412
+ Dependent: bool = False,
413
+ GetObservable: bool = False,
414
+ Hidden: bool = False,
415
+ NonCopyable: bool = False,
416
+ SetObservable: bool = False,
417
+ Transient: bool = False,
418
+ WeakHandle: bool = False,
419
+ GetAccess: AccessEnum = AccessEnum.public,
420
+ SetAccess: AccessEnum = AccessEnum.public,
421
+ **kwargs: Any,
422
+ ) -> None:
423
+ super().__init__(*args, **kwargs)
424
+ self.abort_set: bool = AbortSet
425
+ self.abstract: bool = Abstract
426
+ self.constant: bool = Constant
427
+ self.dependent: bool = Dependent
428
+ self.get_observable: bool = GetObservable
429
+ self.hidden: bool = Hidden
430
+ self.non_copyable: bool = NonCopyable
431
+ self.set_observable: bool = SetObservable
432
+ self.transient: bool = Transient
433
+ self.weak_handle: bool = WeakHandle
434
+ self.get_access: AccessEnum = GetAccess
435
+ self.set_access: AccessEnum = SetAccess
436
+ self.getter: Function | None = None
437
+
438
+ @property
439
+ def is_private(self) -> bool:
440
+ set_public = (
441
+ self.set_access == AccessEnum.public
442
+ or self.set_access == AccessEnum.immutable
443
+ )
444
+ get_public = self.get_access == AccessEnum.public
445
+ return (set_public or get_public) and not self.hidden
446
+
447
+ @property
448
+ def labels(self) -> set[str]:
449
+ labels = set()
450
+ for attr in [
451
+ "abort_set",
452
+ "abstract",
453
+ "constant",
454
+ "dependent",
455
+ "get_observable",
456
+ "hidden",
457
+ "non_copyable",
458
+ "set_observable",
459
+ "transient",
460
+ "weak_handle",
461
+ ]:
462
+ if getattr(self, attr):
463
+ labels.add(attr)
464
+ for attr in ["get_access", "set_access"]:
465
+ if getattr(self, attr) != AccessEnum.public:
466
+ labels.add(f"{attr}={str(getattr(self, attr))}")
467
+ return labels
468
+
469
+ @labels.setter
470
+ def labels(self, *args):
471
+ pass
472
+
473
+
474
+ class Function(MatlabMixin, PathMixin, GriffeFunction, MatlabObject):
475
+ """
476
+ Represents a MATLAB function with various attributes and properties.
477
+
478
+ Attributes:
479
+ parameters (Parameters): The parameters of the function.
480
+ returns (Parameters | None): The return parameters of the function.
481
+ access (AccessEnum): The access level of the function.
482
+ static (bool): Indicates if the function is static.
483
+ abstract (bool): Indicates if the function is abstract.
484
+ sealed (bool): Indicates if the function is sealed.
485
+ hidden (bool): Indicates if the function is hidden.
486
+ _is_setter (bool): Indicates if the function is a setter.
487
+ _is_getter (bool): Indicates if the function is a getter.
488
+
489
+ Args:
490
+ *args (Any): Variable length argument list.
491
+ returns (Parameters | None, optional): The return parameters of the function. Defaults to None.
492
+ Abstract (bool, optional): Indicates if the function is abstract. Defaults to False.
493
+ Access (AccessEnum, optional): The access level of the function. Defaults to AccessEnum.public.
494
+ Hidden (bool, optional): Indicates if the function is hidden. Defaults to False.
495
+ Sealed (bool, optional): Indicates if the function is sealed. Defaults to False.
496
+ Static (bool, optional): Indicates if the function is static. Defaults to False.
497
+ setter (bool, optional): Indicates if the function is a setter. Defaults to False.
498
+ getter (bool, optional): Indicates if the function is a getter. Defaults to False.
499
+ """
500
+
501
+ def __init__(
502
+ self,
503
+ *args: Any,
504
+ returns: Parameters | None = None,
505
+ Abstract: bool = False,
506
+ Access: AccessEnum = AccessEnum.public,
507
+ Hidden: bool = False,
508
+ Sealed: bool = False,
509
+ Static: bool = False,
510
+ setter: bool = False,
511
+ getter: bool = False,
512
+ **kwargs: Any,
513
+ ) -> None:
514
+ super().__init__(*args, **kwargs)
515
+ self.parameters: Parameters = Parameters()
516
+ self.returns: Parameters | None = returns
517
+ self.access: AccessEnum = Access
518
+ self.static: bool = Static
519
+ self.abstract: bool = Abstract
520
+ self.sealed: bool = Sealed
521
+ self.hidden: bool = Hidden
522
+ self._is_setter: bool = setter
523
+ self._is_getter: bool = getter
524
+
525
+ @property
526
+ def is_private(self) -> bool:
527
+ public = self.access == AccessEnum.public or self.access == AccessEnum.immutable
528
+ return public and not self.hidden
529
+
530
+ @property
531
+ def labels(self) -> set[str]:
532
+ labels = set()
533
+ for attr in ["abstract", "hidden", "sealed", "static"]:
534
+ if getattr(self, attr):
535
+ labels.add(attr)
536
+ if self.access != AccessEnum.public:
537
+ labels.add(f"access={str(self.access)}")
538
+ return labels
539
+
540
+ @labels.setter
541
+ def labels(self, *args):
542
+ pass
543
+
544
+
545
+ class Namespace(MatlabMixin, PathMixin, Module, MatlabObject):
546
+ """
547
+ A class representing a namespace in a MATLAB project.
548
+
549
+ Inherits from:
550
+ - PathMixin: A mixin class providing path-related functionality.
551
+ - MatlabObject: A base class for MATLAB objects.
552
+ - Module: A class representing a module.
553
+ """
554
+
555
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
556
+ super().__init__(*args, **kwargs)
557
+ self._access: AccessEnum = AccessEnum.public
558
+
559
+ def __repr__(self) -> str:
560
+ return f"Namespace({self.path!r})"
File without changes