1
1
# -*- coding: utf-8
2
2
"""
3
- Collects common base functionality
3
+ This module provides base classes for functionality common to odML objects.
4
4
"""
5
5
import posixpath
6
6
7
- from . import terminology
8
- from .tools .doc_inherit import allow_inherit_docstring
9
-
10
7
try :
11
8
from collections .abc import Iterable
12
9
except ImportError :
13
10
from collections import Iterable
14
11
12
+ from . import terminology
13
+ from .tools .doc_inherit import allow_inherit_docstring
14
+
15
+
15
16
class BaseObject (object ):
17
+ """
18
+ Base class for all odML objects.
19
+ """
16
20
_format = None
17
21
18
22
def __hash__ (self ):
@@ -41,16 +45,21 @@ def __eq__(self, obj):
41
45
42
46
def __ne__ (self , obj ):
43
47
"""
44
- Use the __eq__ function to determine if both objects are equal
48
+ Use the __eq__ function to determine if both objects are equal.
45
49
"""
46
50
return not self == obj
47
51
48
52
def format (self ):
53
+ """
54
+ Returns the format class of the current object.
55
+ """
49
56
return self ._format
50
57
51
58
@property
52
59
def document (self ):
53
- """ Returns the Document object in which this object is contained """
60
+ """
61
+ Returns the Document object in which this object is contained.
62
+ """
54
63
if self .parent is None :
55
64
return None
56
65
return self .parent .document
@@ -64,15 +73,18 @@ def get_terminology_equivalent(self):
64
73
65
74
def clean (self ):
66
75
"""
67
- Stub that doesn't do anything for this class
76
+ Stub that doesn't do anything for this class.
68
77
"""
69
78
pass
70
79
71
80
def clone (self , children = True ):
72
81
"""
73
82
Clone this object recursively (if children is True) allowing to copy it
74
83
independently to another document. If children is False, this acts as
75
- a template cloner, creating a copy of the object without any children
84
+ a template cloner, creating a copy of the object without any children.
85
+
86
+ :param children: True by default. Is used in the classes that inherit
87
+ from this class.
76
88
"""
77
89
# TODO don't we need some recursion / deepcopy here?
78
90
import copy
@@ -81,6 +93,9 @@ def clone(self, children=True):
81
93
82
94
83
95
class SmartList (list ):
96
+ """
97
+ List class that can hold odml.Sections and odml.Properties.
98
+ """
84
99
85
100
def __init__ (self , content_type ):
86
101
"""
@@ -108,7 +123,7 @@ def __getitem__(self, key):
108
123
def __setitem__ (self , key , value ):
109
124
"""
110
125
Replaces item at list[*key*] with *value*.
111
- :param key: index position
126
+ :param key: index position.
112
127
:param value: object that replaces item at *key* position.
113
128
value has to be of the same content type as the list.
114
129
In this context usually a Section or a Property.
@@ -152,17 +167,17 @@ def __eq__(self, obj):
152
167
153
168
def __ne__ (self , obj ):
154
169
"""
155
- Use the __eq__ function to determine if both objects are equal
170
+ Use the __eq__ function to determine if both objects are equal.
156
171
"""
157
172
return not self == obj
158
173
159
174
def index (self , obj ):
160
175
"""
161
- Find obj in list
176
+ Find obj in list.
162
177
"""
163
- for i , e in enumerate (self ):
164
- if e is obj :
165
- return i
178
+ for idx , val in enumerate (self ):
179
+ if val is obj :
180
+ return idx
166
181
raise ValueError ("remove: %s not in list" % repr (obj ))
167
182
168
183
def remove (self , obj ):
@@ -193,6 +208,9 @@ def sort(self, key=lambda x: x.name, reverse=False):
193
208
194
209
@allow_inherit_docstring
195
210
class Sectionable (BaseObject ):
211
+ """
212
+ Base class for all odML objects that can store odml.Sections.
213
+ """
196
214
def __init__ (self ):
197
215
from odml .section import BaseSection
198
216
self ._sections = SmartList (BaseSection )
@@ -210,18 +228,20 @@ def __iter__(self):
210
228
@property
211
229
def document (self ):
212
230
"""
213
- Returns the parent-most node (if its a document instance) or None
231
+ Returns the parent-most node (if its a document instance) or None.
214
232
"""
215
233
from odml .doc import BaseDocument
216
- p = self
217
- while p .parent :
218
- p = p .parent
219
- if isinstance (p , BaseDocument ):
220
- return p
234
+ par = self
235
+ while par .parent :
236
+ par = par .parent
237
+ if isinstance (par , BaseDocument ):
238
+ return par
221
239
222
240
@property
223
241
def sections (self ):
224
- """ The list of sections contained in this section/document """
242
+ """
243
+ The list of sections contained in this section/document.
244
+ """
225
245
return self ._sections
226
246
227
247
def insert (self , position , section ):
@@ -301,6 +321,7 @@ def itersections(self, recursive=True, yield_self=False,
301
321
:param filter_func: accepts a function that will be applied to each
302
322
iterable. Yields iterable if function returns True
303
323
:type filter_func: function
324
+ :param max_depth: number of layers in the document tree to include in the search.
304
325
"""
305
326
stack = []
306
327
# Below: never yield self if self is a Document
@@ -422,6 +443,10 @@ def _match_iterable(self, iterable, key):
422
443
"""
423
444
Searches for a key match within a given iterable.
424
445
Raises ValueError if not found.
446
+
447
+ :param iterable: list of odML objects.
448
+ :param key: string to search an objects name against.
449
+ :returns: odML object that matched the key.
425
450
"""
426
451
for obj in iterable :
427
452
if self ._matches (obj , key ):
@@ -458,17 +483,25 @@ def _get_section_by_path(self, path):
458
483
return self ._match_iterable (self .sections , pathlist [0 ])
459
484
460
485
def find (self , key = None , type = None , findAll = False , include_subtype = False ):
461
- """ Return the first subsection named *key* of type *type* """
486
+ """
487
+ Returns the first subsection named *key* of type *type*.
488
+
489
+ :param key: string to search against an odML objects name.
490
+ :param type: type of an odML object.
491
+ :param findAll: include further matches after the first one in the result.
492
+ :param include_subtype: splits an objects type at '/' and matches the parts
493
+ against the provided type.
494
+ """
462
495
ret = []
463
496
if type :
464
497
type = type .lower ()
465
498
466
- for s in self ._sections :
467
- if self ._matches (s , key , type , include_subtype = include_subtype ):
499
+ for sec in self ._sections :
500
+ if self ._matches (sec , key , type , include_subtype = include_subtype ):
468
501
if findAll :
469
- ret .append (s )
502
+ ret .append (sec )
470
503
else :
471
- return s
504
+ return sec
472
505
if ret :
473
506
return ret
474
507
@@ -533,7 +566,7 @@ def find_related(self, key=None, type=None, children=True, siblings=True,
533
566
534
567
def get_path (self ):
535
568
"""
536
- Returns the absolute path of this section
569
+ Returns the absolute path of this section.
537
570
"""
538
571
node = self
539
572
path = []
@@ -543,36 +576,36 @@ def get_path(self):
543
576
return "/" + "/" .join (path )
544
577
545
578
@staticmethod
546
- def _get_relative_path (a , b ):
579
+ def _get_relative_path (path_a , path_b ):
547
580
"""
548
- Returns a relative path for navigation from dir *a * to dir *b*
581
+ Returns a relative path for navigation from *path_a * to *path_b*.
549
582
550
- If the common parent of both is "/", return an absolute path
583
+ If the common parent of both is "/", return an absolute path.
551
584
"""
552
- a += "/"
553
- b += "/"
554
- parent = posixpath .dirname (posixpath .commonprefix ([a , b ]))
585
+ path_a += "/"
586
+ path_b += "/"
587
+ parent = posixpath .dirname (posixpath .commonprefix ([path_a , path_b ]))
555
588
if parent == "/" :
556
- return b [:- 1 ]
589
+ return path_b [:- 1 ]
557
590
558
- a = posixpath .relpath (a , parent )
559
- b = posixpath .relpath (b , parent )
560
- if a == "." :
561
- return b
591
+ path_a = posixpath .relpath (path_a , parent )
592
+ path_b = posixpath .relpath (path_b , parent )
593
+ if path_a == "." :
594
+ return path_b
562
595
563
- return posixpath .normpath ("../" * (a .count ("/" ) + 1 ) + b )
596
+ return posixpath .normpath ("../" * (path_a .count ("/" ) + 1 ) + path_b )
564
597
565
598
def get_relative_path (self , section ):
566
599
"""
567
600
Returns a relative (file)path to point to section
568
601
like (e.g. ../other_section)
569
602
570
603
If the common parent of both sections is the document (i.e. /),
571
- return an absolute path
604
+ return an absolute path.
572
605
"""
573
- a = self .get_path ()
574
- b = section .get_path ()
575
- return self ._get_relative_path (a , b )
606
+ path_a = self .get_path ()
607
+ path_b = section .get_path ()
608
+ return self ._get_relative_path (path_a , path_b )
576
609
577
610
def clean (self ):
578
611
"""
@@ -586,22 +619,24 @@ def clean(self):
586
619
587
620
def clone (self , children = True , keep_id = False ):
588
621
"""
589
- Clone this object recursively allowing to copy it independently
590
- to another document
622
+ Clones this object recursively allowing to copy it independently
623
+ to another document.
591
624
"""
592
625
from odml .section import BaseSection
593
626
obj = super (Sectionable , self ).clone (children )
594
627
obj ._parent = None
595
628
obj ._sections = SmartList (BaseSection )
596
629
if children :
597
- for s in self ._sections :
598
- obj .append (s .clone (keep_id = keep_id ))
630
+ for sec in self ._sections :
631
+ obj .append (sec .clone (keep_id = keep_id ))
599
632
600
633
return obj
601
634
602
635
@property
603
636
def repository (self ):
604
- """ A URL to a terminology. """
637
+ """
638
+ A URL to a terminology.
639
+ """
605
640
return self ._repository
606
641
607
642
@repository .setter
0 commit comments