1- """ Base Metadata Classes """
1+ """
2+ Base Metadata Classes
3+ """
24
35import copy
46import os
@@ -67,7 +69,9 @@ def __call__(
6769
6870
6971class Tree :
70- """ Metadata Tree """
72+ """
73+ Metadata Tree
74+ """
7175
7276 def __init__ (self , data , name = None , parent = None ):
7377 """
@@ -160,11 +164,16 @@ def commit(self):
160164 return self ._commit
161165
162166 def __str__ (self ):
163- """ Use tree name as identifier """
167+ """
168+ Use tree name as identifier
169+ """
170+
164171 return self .name
165172
166173 def _initialize (self , path ):
167- """ Find metadata tree root, detect format version, check for config """
174+ """
175+ Find metadata tree root, detect format version, check for config
176+ """
168177
169178 # Find the tree root
170179 root = os .path .abspath (path )
@@ -202,7 +211,9 @@ def _initialize(self, path):
202211 raise utils .FileError (f"Failed to parse '{ config_file_path } '.\n { error } " )
203212
204213 def _merge_plus (self , data , key , value , prepend = False ):
205- """ Handle extending attributes using the '+' suffix """
214+ """
215+ Handle extending attributes using the '+' suffix
216+ """
206217
207218 # Set the value if key is not present
208219 if key not in data :
@@ -252,7 +263,10 @@ def _merge_plus(self, data, key, value, prepend=False):
252263 key , self .name , str (error )))
253264
254265 def _merge_regexp (self , data , key , value ):
255- """ Handle substitution of current values """
266+ """
267+ Handle substitution of current values
268+ """
269+
256270 # Nothing to substitute if the key is not present in parent
257271 if key not in data :
258272 return
@@ -274,7 +288,10 @@ def _merge_regexp(self, data, key, value):
274288 key , self .name ))
275289
276290 def _merge_minus_regexp (self , data , key , value ):
277- """ Handle removing current values if they match regexp """
291+ """
292+ Handle removing current values if they match regexp
293+ """
294+
278295 # A bit faster but essentially `any`
279296 def lazy_any_search (item , patterns ):
280297 for p in patterns :
@@ -301,7 +318,10 @@ def lazy_any_search(item, patterns):
301318 key , self .name ))
302319
303320 def _merge_minus (self , data , key , value ):
304- """ Handle reducing attributes using the '-' suffix """
321+ """
322+ Handle reducing attributes using the '-' suffix
323+ """
324+
305325 # Cannot reduce attribute if key is not present in parent
306326 if key not in data :
307327 return
@@ -324,7 +344,10 @@ def _merge_minus(self, data, key, value):
324344 key , self .name ))
325345
326346 def _merge_special (self , data , source ):
327- """ Merge source dict into data, handle special suffixes """
347+ """
348+ Merge source dict into data, handle special suffixes
349+ """
350+
328351 for key , value in source .items ():
329352 # Handle special attribute merging
330353 if key .endswith ('+' ):
@@ -342,10 +365,15 @@ def _merge_special(self, data, source):
342365 data [key ] = value
343366
344367 def _process_directives (self , directives ):
345- """ Check and process special fmf directives """
368+ """
369+ Check and process special fmf directives
370+ """
346371
347372 def check (value , type_ , name = None ):
348- """ Check for correct type """
373+ """
374+ Check for correct type
375+ """
376+
349377 if not isinstance (value , type_ ):
350378 name = f" '{ name } '" if name else ""
351379 raise fmf .utils .FormatError (
@@ -372,7 +400,10 @@ def check(value, type_, name=None):
372400
373401 @staticmethod
374402 def init (path ):
375- """ Create metadata tree root under given path """
403+ """
404+ Create metadata tree root under given path
405+ """
406+
376407 root = os .path .abspath (os .path .join (path , ".fmf" ))
377408 if os .path .exists (root ):
378409 raise utils .FileError ("{0} '{1}' already exists." .format (
@@ -387,7 +418,10 @@ def init(path):
387418 return root
388419
389420 def merge (self , parent = None ):
390- """ Merge parent data """
421+ """
422+ Merge parent data
423+ """
424+
391425 # Check parent
392426 if parent is None :
393427 parent = self .parent
@@ -401,7 +435,10 @@ def merge(self, parent=None):
401435 self .data = data
402436
403437 def inherit (self ):
404- """ Apply inheritance """
438+ """
439+ Apply inheritance
440+ """
441+
405442 # Preserve original data and merge parent
406443 # (original data needed for custom inheritance extensions)
407444 self .original_data = self .data
@@ -413,7 +450,10 @@ def inherit(self):
413450 child .inherit ()
414451
415452 def update (self , data ):
416- """ Update metadata, handle virtual hierarchy """
453+ """
454+ Update metadata, handle virtual hierarchy
455+ """
456+
417457 # Make a note that the data dictionary has been updated
418458 # None is handled in the same way as an empty dictionary
419459 self ._updated = True
@@ -605,6 +645,7 @@ def get(self, name=None, default=None):
605645 default value when any of the dictionary keys does not exist.
606646
607647 """
648+
608649 # Return the whole dictionary if no attribute specified
609650 if name is None :
610651 return self .data
@@ -619,7 +660,10 @@ def get(self, name=None, default=None):
619660 return data
620661
621662 def child (self , name , data , source = None ):
622- """ Create or update child with given data """
663+ """
664+ Create or update child with given data
665+ """
666+
623667 try :
624668 # Update data from a dictionary (handle empty nodes)
625669 if isinstance (data , dict ) or data is None :
@@ -636,7 +680,10 @@ def child(self, name, data, source=None):
636680
637681 @property
638682 def explore_include (self ):
639- """ Additional filenames to be explored """
683+ """
684+ Additional filenames to be explored
685+ """
686+
640687 try :
641688 explore_include = self .config ["explore" ]["include" ]
642689 if not isinstance (explore_include , list ):
@@ -657,6 +704,7 @@ def grow(self, path):
657704 from the same path multiple times with attribute adding using the "+"
658705 sign leads to adding the value more than once!
659706 """
707+
660708 if path != '/' :
661709 path = path .rstrip ("/" )
662710 if path in IGNORED_DIRECTORIES : # pragma: no cover
@@ -764,14 +812,20 @@ def climb(self, whole: bool = False, sort: bool = True):
764812
765813 @property
766814 def select (self ):
767- """ Respect directive, otherwise by being leaf/branch node"""
815+ """
816+ Respect directive, otherwise by being leaf/branch node
817+ """
818+
768819 try :
769820 return self ._directives ["select" ]
770821 except KeyError :
771822 return not self .children
772823
773824 def find (self , name ):
774- """ Find node with given name """
825+ """
826+ Find node with given name
827+ """
828+
775829 for node in self .climb (whole = True ):
776830 if node .name == name :
777831 return node
@@ -807,6 +861,7 @@ def prune(
807861 default. Set to ``False`` if you prefer to keep the order in
808862 which the child nodes were inserted into the tree.
809863 """
864+
810865 keys = keys or []
811866 names = names or []
812867 filters = filters or []
@@ -842,7 +897,10 @@ def prune(
842897 yield node
843898
844899 def show (self , brief = False , formatting = None , values = None ):
845- """ Show metadata """
900+ """
901+ Show metadata
902+ """
903+
846904 values = values or []
847905
848906 # Custom formatting
@@ -919,6 +977,7 @@ def copy(self):
919977 node and the rest of the tree attached to it is not copied
920978 in order to save memory.
921979 """
980+
922981 original_parent = self .parent
923982 self .parent = None
924983 duplicate = copy .deepcopy (self )
@@ -939,6 +998,7 @@ def validate(self, schema, schema_store=None):
939998
940999 Raises utils.JsonSchemaError if the supplied schema was invalid.
9411000 """
1001+
9421002 return utils .validate_data (self .data , schema , schema_store = schema_store )
9431003
9441004 def _locate_raw_data (self ):
@@ -954,8 +1014,8 @@ def _locate_raw_data(self):
9541014 node_data ... dictionary containing raw data for the current node
9551015 full_data ... full raw data from the closest parent node
9561016 source ... file system path where the full raw data are stored
957-
9581017 """
1018+
9591019 # List of node names in the virtual hierarchy
9601020 hierarchy = list ()
9611021
@@ -1011,10 +1071,14 @@ def __enter__(self):
10111071 export to yaml does not preserve this information. The feature
10121072 is experimental and can be later modified, use at your own risk.
10131073 """
1074+
10141075 return self ._locate_raw_data ()[0 ]
10151076
10161077 def __exit__ (self , exc_type , exc_val , exc_tb ):
1017- """ Experimental: Store modified metadata to disk """
1078+ """
1079+ Experimental: Store modified metadata to disk
1080+ """
1081+
10181082 _ , full_data , source = self ._locate_raw_data ()
10191083 with open (source , "w" , encoding = 'utf-8' ) as file :
10201084 file .write (dict_to_yaml (full_data ))
@@ -1026,6 +1090,7 @@ def __getitem__(self, key):
10261090 To get a child the key has to start with a '/'.
10271091 as identification of child item string
10281092 """
1093+
10291094 if key .startswith ("/" ):
10301095 return self .children [key [1 :]]
10311096 else :
0 commit comments