1 """!This module provides two different ways to generate Fortran
2 namelist files from HWRFConfig sections:
4 NamelistInserter - given a file, or a multi-line string, finds
5 angle bracket (<vartype:stuff>) strings with values from an
6 HWRFConfig section. This is the suggested method for namelists
7 with very few configurable items.
9 Conf2Namelist - given one or more Config sections, find values of
10 the form nlsec.nlkey=value. The nlsec specifies the namelist
11 &nlsec, the nlkey specifies the namelist variable name, and the
12 value is converted to a Python value and then a Fortran namelist
13 value. The Conf2Namelist provides ways to append multiple
14 Conf2Namelist objects' data to form Fortran one-dimensional
15 arrays. This is to support WRF namelists, where one specifies
16 each domain's data in a 1D array.
18 In addition, this module provides two functions to_fortnml and
19 from_fortnml to convert between in-memory Python objects and strings
20 suitable for pasting in a Fortran namelist to achieve the same value
23 import collections,re,fractions,datetime,ConfigParser, StringIO,logging
26 from ConfigParser
import NoOptionError,NoSectionError
28 from hwrf.numerics import to_datetime, to_datetime_rel, to_fraction
32 __all__=[
'to_fortnml',
'from_fortnml',
'Conf2Namelist',
'NamelistInserter']
39 """!used to indicate namelist recursion
41 This exception is used only for internal purposes and will never
42 be raised beyond this module."""
45 """!converts a Python object to fortran namelist format
47 Converts the given python data structure to a string suitable for
48 representing in a Fortran namelist. It can handle bool, int,
49 float, string, datetime, fraction and a list (or tuple) of those.
50 A datetime is converted via strftime('"%Y-%m-%d_%H:%M:%S"'). The
51 optional exc_hint is used when raising exceptions to give an idea
52 of what file and line number, or config option name, generated the
60 * fractions.Fraction ==> str(float(py))
61 * basestring ==> double-quoted string
62 * datetime.datetime ==> WPS/WRF format date stamp: %Y-%m-%D_%H:%M:%S
63 * list or tuple ==> comma-separated list of converted values
65 Anything else will raise an exception.
67 @return the converted value as a string
68 @param py the object to convert
69 @param exc_hint prepended to exception messages when exceptions are
70 raised. Should contain file and line information."""
72 return __to_fortnml_impl(py,exc_hint=exc_hint)
73 except NamelistRecursion:
75 s=s[0:37]+
'...' if len(s)>40
else s
76 raise NamelistValueError(
'%s: cannot convert nested python containers to Fortran namelist values.'%(exc_hint+s,))
78 def __to_fortnml_impl(py,recursed=False,exc_hint=''):
79 """!internal function used to convert python objects to namelist syntax
81 This function does the actual work of converting a Python object to
82 Fortran namelist syntax. Do not call it directly.
83 @param py the object to convert
84 @param recursed have we already recursed? Used to detect nested lists
85 @param exc_hint the exc_hint argument to to_fortnml()"""
86 if isinstance(py,bool):
return 'T' if py
else 'F'
87 if isinstance(py,int):
return str(py)
88 if isinstance(py,float):
return str(py)
89 if isinstance(py,fractions.Fraction):
return str(float(py))
90 if isinstance(py,basestring):
return '"'+re.sub(
'"',
'""',str(py))+
'"'
91 if isinstance(py,datetime.datetime):
return py.strftime(
'"%Y-%m-%d_%H:%M:%S"')
92 if isinstance(py,list)
or isinstance(py,tuple):
94 raise NamelistRecursion()
96 return ', '.join([__to_fortnml_impl(x,recursed=
True,
97 exc_hint=exc_hint)
for x
in py])
98 raise NamelistValueError(
'%s%s Unable to convert to a fortran namelist '
99 'value'%(exc_hint,repr(py)))
103 fortnml_parse=re.compile(
"""(?ix)\s*(?:
104 (?P<fraction>[0-9]+[+][0-9]+[/][0-9]+) |
105 \"(?P<dqchar>(?:[^\"]+|\"\")+)\" |
106 \'(?P<sqchar>(?:[^\']+|\'\')+)\' |
108 (?:(?:[+-]?[0-9]+\.[0-9]*|[+-]?\.[0-9]+)(?:[eE][+-]?[0-9]+)?) |
109 (?:[+-]?[0-9]+[eE][+-]?[0-9]+)
111 (?P<int>[+-]?[0-9]+) |
112 (?P<identifier>[a-zA-Z_][a-zA-Z0-9_]+|[a-eg-su-zA-EG-SU-Z_]) |
113 (?P<true>t|\.true\.) |
114 (?P<false>f|\.false\.) |
115 (?P<comment>[!#].*$) |
119 """A regular expression for tokenizing a fortran namelist scalar value."""
122 """!Converts a fortran namelist value to a Python object
124 This is the inverse function for to_fortnml. Given a string from
125 a Fortran namelist value, returns an equivalent python object.
126 Will throw NamelistValueError if an unrecognized object is
127 present, or NamelistRecursion if you send a nested container (such
129 @param py the string to convert
130 @return the Python object"""
133 for match
in fortnml_parse.finditer(py):
135 if tok
is None or tok==
'bad':
137 elif tok==
'comment':
break
138 elif tok==
'int': out.append(int(match.group(tok)))
139 elif tok==
'real': out.append(float(match.group(tok)))
140 elif tok==
'true': out.append(
True)
141 elif tok==
'false': out.append(
False)
142 elif tok==
'fraction': out.append(to_fraction(match.group(tok)))
143 elif tok==
'dqchar': out.append(re.sub(
'""',
'"',match.group(tok)))
144 elif tok==
'sqchar': out.append(re.sub(
"''",
"'",match.group(tok)))
145 elif tok==
'comma': islist=
True
146 elif tok==
'identifier': out.append(match.group(tok))
155 """!Insert config file data into a Fortran namelist file.
157 This class parses an input file that contains a partial namelist,
158 inserting missing values of the format <s:cycle> with values from
159 a ConfigParser-like object. The <s:cycle> sorts of text follow a
162 * @<s:varname@> -- insert a string surrounded by double quotes taken
163 from the specified conf variable
164 * @<f:varname@> -- insert a float, taken from conf variable varname
165 * @<r:varname@> -- same as <f:varname>
166 * @<i:varname@> -- insert an integer, taken from conf variable varname
167 * @<l:varname@> -- insert a logical, taken from conf variable varname
168 * @<b:varname@> -- same as <l:varname>
170 @<d:varname@> -- the conf variable is converted to a
171 datetime.datetime using hwrf.numerics.to_datetime, and then to a
172 string of the format "YYYY-MM-DD_HH:MM:SS". If atime is
173 specified to the parse subroutine, then the value is allowed to
174 be a difference relative to the atime (as accepted by
175 hwrf.numerics.to_datetime_rel).
177 @<u:varname@> -- convert the conf variable to a string, and dump its
178 value unquoted. This is used, for example, to have the name of a
179 namelist variable be generated from a conf file.
181 You can also specify angle braces without a type:
185 to ask for the variable to be converted by guessing the type that
186 was intended in the conf file. For example:
205 myvar=.true., .false., .true. /
208 As for variables, one can request a subitem of a variable:
210 * varname -- get variable varname
211 * vit[stormname] -- get variable "vit" and then get
212 vit.__getitem__["stormname"]
214 for subscriptable types. This is mainly intended for vitals."""
218 find_ltgt=re.compile(
'''(?P<pre>(?:[^<]|"(?:[^"]|""")*"|'(?:[^']|'{3})*')*)<(?:(?P<typ>[^:]*):)?(?P<var>[^>\[]*)(?:\[(?P<sub>[^\]]*)\])?>(?P<rest>.*)''')
222 nlfalse=re.compile(
'\A(?i)(?:f.*|.false.|n|no|0*[1-9][0-9]*)\Z')
226 nltrue=re.compile(
'\A(?i)(?:t.*|.true.|y|yes|0)\Z')
230 comment=re.compile(
'(?P<code>(?:[^!]|\"(?:[^\"]|\"\"\")*\"|\'(?:[^\']|\'\'\')*\')*)(?P<comment>!.*)?')
232 def __init__(self,conf,section):
233 """!NamelistInserter constructor
235 Creates a new NamelistInserter that will get its data from the
236 specified section of the HWRFConfig conf.
237 @param conf the hwrf.config.HWRFConfig object to use
238 @param section the section to read"""
240 self._section=section
248 def parse(self,line_iterable,logger=None,source='<internal>',
249 raise_all=
True,atime=
None,ftime=
None,**kwargs):
250 """!Generates the namelist, returning it as a string.
252 Reads the config section and file, generating the namelist and
253 returning it as a string.
255 @param line_iterable an iterator that iterates over each line of
257 @param logger optional: a logging.Logger to log messages, or None
258 to disable. Default: None
259 @param source for warning or error messages: the filename.
260 Default: "@<internal@>"
261 @param raise_all set to False to log messages instead of
262 raising exceptions. Raise only one exception at the end.
263 Default: True; raise an exception as soon as the first
265 @param atime Optional: the analysis time for conf.timestrinterp
266 @param ftime Optional: the forecast time for conf.timestrinterp
267 @param kwargs additional variables and their values for config
269 assert(
not isinstance(line_iterable,basestring))
270 if atime
is not None:
271 atime=to_datetime(atime)
272 if ftime
is not None:
273 ftime=to_datetime_rel(ftime,atime)
274 elif atime
is not None:
276 out=StringIO.StringIO()
278 section=self._section
281 if logger
is not None:
282 logger.warning(
'%s:%d: syntax error: %s'%(source,iline,what))
283 for line
in line_iterable:
287 m=NamelistInserter.comment.match(linepart)
291 comment=m.group(
'comment')
296 while len(linepart)>0:
297 m=NamelistInserter.find_ltgt.match(linepart)
305 assert(linepart!=rest)
309 if pre: out.write(pre)
310 if typ
is None: typ=
'*'
311 if not typ: synerr(
'no output type specified')
312 elif not var: synerr(
'no variable specified')
314 synerr(
'output type must be one of: bdfilsu, not %s'
316 elif typ
not in 'bdfilrsuBDFILRSU*':
317 synerr(
'invalid type %s specified: only bdfilsu are '
323 elif atime
is not None:
324 val=conf.timestrinterp(
325 section,
'{'+var+
'}',ftime=ftime,
326 atime=atime,**kwargs)
329 section,
'{'+var+
'}',**kwargs)
330 except(KeyError,TypeError,ValueError,NoOptionError,
331 NoSectionError)
as e:
332 if logger
is not None:
334 '%s:%d: cannot find variable %s'
342 except (TypeError,KeyError,ValueError,HWRFError) \
344 if logger
is not None:
345 logger.warning(
'%s:%d: %s[%s]: %s'%(
346 source,iline,var,sub,str(e)),
351 if typ
in 'rRfF': typval=float(val)
352 elif typ
in 'iI': typval=int(val)
354 if isinstance(val,bool):
356 elif isinstance(val,basestring):
357 if NamelistInserter.nlfalse.match(val):
359 elif NamelistInserter.nltrue.match(val):
363 '%s is not a valid logical'
369 if atime
is not None:
370 typval=to_datetime_rel(dval,atime)
372 typval=to_datetime(dval)
377 except (TypeError,KeyError,ValueError)
as e:
378 if logger
is not None:
380 '%s:%d: cannot convert %s to type=%s: %s'
381 %(source,iline,repr(val),typ,str(e)),
385 if sub: fromthis=
'%s[%s]'%(var,sub)
388 if typ
in 'bdfilrsBDFILRS*':
390 typval,exc_hint=fromthis+
':')
393 except (TypeError,KeyError,ValueError)
as e:
394 if logger
is not None:
396 '%s:%d: <%s:%s>=%s: error converting to '
398 %(source,iline,typ,fromthis,repr(typval),
399 str(e)),exc_info=
True)
409 return out.getvalue()
412 """!Generates a Fortran namelist entirely from config files
414 This class generates namelist information from any
415 ConfigParser-like object, starting at a specified conf section.
416 This differs from NamelistInserter in that no external file is
417 read - only the ConfigParser is used. Also, an
418 hwrf.config.HWRFConfig is not required; any ConfigParser-like
419 object is sufficient.
421 When parsing the section, variables of the form nlsection.nlkey
422 will be put in namelist section nlsection, with variable name
423 nlkey. Variables that contain no "." but are valid Fortran
424 variable names (except for the variable "namelist") are called
425 "traits" and are accessible via trait_get, trait_set, and the
426 other trait_* subroutines. The special variable "namelist"
427 specifies a list of conf sections to recurse into. Variables in
428 the local conf section will always override variables in included
429 conf sections, and variables in later included conf sections will
430 override variables in earlier included conf sections.
434 conf=RawConfigParser()
435 conf.readfp(StringIO('''
437 happiness_quotient=0.7
438 physics.mp_physics=85
439 physics.cu_physics=84
443 physics.bl_pbl_physics=93
445 physics.bl_pbl_physics=3
447 str(Conf2Namelist(conf,'sec1'))
457 and a trait accessible via self.trait_get('happiness_quotient')
463 happiness_quotient=0.7
464 physics.mp_physics=85
465 physics.cu_physics=84
469 physics.bl_pbl_physics=93
472 physics.bl_pbl_physics=3'''
473 """A test namelist for debugging"""
479 nlentry=re.compile(
'\A(?:(?P<section>[a-zA-Z_][a-zA-Z0-9_]*)\.)?(?P<var>[a-zA-Z_][a-zA-Z0-9_%]*)\Z')
483 nlfalse=re.compile(
'\A(?i)(?:f.*|.false.)\Z')
484 """A regular expression from re.compile, to detect false Fortran logical values."""
488 nltrue=re.compile(
'\A(?i)(?:t.*|.true.)\Z')
489 """A regular expression from re.compile, to detect true Fortran logical values."""
494 """A special, fake, invalid namelist name for traits."""
497 """!Returns a copy of self.
499 Creates a shallow copy of self
500 @param other unused; may be removed in the future"""
516 def __init__(self,conf=None,section=None,section_sorter=None,
517 var_sorters=
None,logger=
None,nl=
None,morevars=
None):
518 """!Conf2Namelist constructor
520 Creates a Conf2Namelist.
522 @param conf the HWRFConfig object
523 @param section the section to start searching from.
524 @param section_sorter the cmp-like function to use to sort the
525 sections when generating the output namelist
526 @param var_sorters a dict-like mapping from section name to a
527 cmp-like function to use to sort variable names within
529 @param logger a logging.Logger object to use to log messages
530 @param nl a dict of dicts (or object that acts like that)
531 to use to initialize the Conf2Namelist. Warning: this
532 functionality is untested
533 @param morevars a dict with additional variables to use when
534 expanding strings This is simply passed to conf.items.
535 See the HWRFConfig documentation for details."""
536 if morevars
is None: morevars=emptydict
541 self.
nl=collections.defaultdict(
lambda: collections.defaultdict())
543 for (sec,con)
in nl.iteritems():
544 for key,val
in con.iteritems():
546 if conf
is None or section
is None:
551 nlentry=Conf2Namelist.nlentry
552 while len(parseme)>0:
557 if logger
is not None:
558 logger.debug(
'Conf2Namelist now parsing section %s'%(sec,))
559 for key,value
in conf.items(sec,morevars=morevars):
561 if m
and m.group(
'section')
is not None:
564 elif key==
'namelist':
567 for sec2
in value.split(
','):
569 if len(trim)>0
and not trim
in touched:
571 elif re.match(
'\A[a-zA-Z_][a-zA-Z_0-9%]*\Z',key):
574 elif logger
is not None:
576 'Conf2Namelist ignoring %s = %s in section %s'
579 """!create namelists if they do not exist
581 Ensures that the specified namelist exists. Returns self.
582 @param args list of namelist names"""
584 self.
nl[str(section).lower()]
587 """!Sets a variable in a namelist
589 Sets the value of a namelist's variable.
590 @param section the namelist name
591 @param var the name of the variable in the namelist
592 @param data the value. This can be a string,
593 datetime.datetime, int, float, fractions.Fraction or a list or
595 if not ( isinstance(data,basestring)
or
596 isinstance(data,datetime.datetime)
or
597 isinstance(data,int)
or isinstance(data,float)
or
598 isinstance(data,list)
or
599 isinstance(data,fractions.Fraction) ):
600 raise TypeError(
'%s: invalid type for namelist (value=%s)'
601 %(data.__class__.__name__,repr(data)))
602 self.
nl[str(section).lower()][str(var).lower()]=data
604 """!Removes a variable from a namelist.
606 Removes a variable from a namelist
607 @param section the namelist
608 @param var the variable to delete"""
610 del self.
nl[str(section).lower()][var]
611 except KeyError:
pass
614 """Removes a namelist section from the namelist"""
616 del self.
nl[str(section).lower()]
617 except KeyError:
pass
619 """!does this namelist have this variable?
621 Determines if the namelist exists and has the variable.
623 @return True if the namelist exists and it has the variable, or
625 @param section the string name of the namelist
626 @param var the string name of the variable"""
627 if section
not in self.
nl:
return False
628 return var
in self.
nl[section]
631 """Returns True if the namelist section exists in the namelist
632 and False otherwise"""
633 if section
in self.
nl:
return True
635 def nl_get(self,section,var,default=None):
636 """!get the value of a variable from a namelist
638 Gets the value of a variable in a namelist. If the
639 default is supplied and non-None, it will be returned if the
640 variable does not exist. Raises NamelistKeyError if the
641 variable does not exist a the default is not provided.
642 @param section the namelist name
643 @param var the name of the variable in the namelist
644 @param default the value to return if the namelist or variable
646 s=str(section).lower()
651 if default
is not None:
655 """!Sets the value of a namelist variable if it has no value.
657 If the namelist variable has a value, this function does
658 nothing. Otherwise, it is the same as calling nl_set.
659 @param section the namelist name
660 @param var the variable name
661 @param data the value to set, passed to nl_set()"""
665 self.
nl_set(section,var,data)
667 """!Iterates over variable,value tuples in the given
669 @param section the namelist over which to iterate"""
670 if not isinstance(section,basestring): section=str(section)
671 if not section
in self.
nl:
return
672 for var,value
in self.
nl[section].iteritems():
675 """!Iterates over variable,value tuples in the traits."""
676 assert(Conf2Namelist.TRAIT
in self.
nl)
677 assert(self.
nl[Conf2Namelist.TRAIT])
678 for var,value
in self.
nl[Conf2Namelist.TRAIT].iteritems():
681 """!Sets a trait's value.
682 This is the same as nl_set() but sets a trait. It simply
683 passes the special constant Conf2Namelist.TRAIT as the
685 @param var the name of the trait to set
686 @param value the value to set"""
687 return self.
nl_set(Conf2Namelist.TRAIT,var,value)
691 Deletes a trait. This is the same as calling nl_del passing
692 the Conf2Namelist.TRAIT constant as the section.
693 @param var the variable to delete."""
694 return self.
nl_del(Conf2Namelist.TRAIT,var)
696 """!Returns a trait's value.
698 Returns the value of a trait. If a default is given and
699 non-None, returns the default if the trait does not exist.
700 This is the same as calling nl_get() passing the
701 Conf2Namelist.TRAIT as the section.
702 @param var the trait to get
703 @param default the default value if the trait is unset"""
704 return self.
nl_get(Conf2Namelist.TRAIT,var,default)
706 """!Returns True if the trait exists, and False otherwise.
708 Determines if a trait is set. This is the same as passing
709 Conf2Namelist.TRAIT as the section argument to nl_have()
710 @param var the trait to query"""
711 return self.
nl_have(Conf2Namelist.TRAIT,var)
713 """!Sets the traits value if it does not have one.
715 Sets the value of a trait if the trait does not already have a
716 value. This is the same as calling nl_set_if_unset() passing
717 the special value Conf2Namelist.TRAIT as the section."""
720 """!create array values by joining multiple Conf2Namelist objects
722 Generates a new Conf2Namelist by looping over all arguments in
723 this namelist, and appending the other namelists' values in a
724 list. If the other namelist does not have a given value, then
725 this namelist's value, or the last namelist that had a value
726 for that argument, will be appended. Variables or namelist
727 sections that exist in the other namelists, but not this one,
730 @param others an iterable object (list, tuple) of Conf2Namelist"""
734 for secname,mydict
in self.nl.iteritems():
735 outsec=out.nl[secname]
736 for var,value
in mydict.iteritems():
740 nextval=other.nl_get(secname,var,default)
742 if isinstance(nextval,tuple)
or isinstance(nextval,list):
743 thelist.extend(nextval)
745 thelist.append(nextval)
748 def copy(self,section_subset=None,var_subset=None,other=None):
749 """!duplicates this object
751 Returns a copy of this object, or if other is specified,
752 copies this object's contents into the target Conf2Namelist.
753 When copying into a target Conf2Namelist, only values that are
754 not already in that namelist will be copied. The copy has its
755 own data structures, so modifying the copy will not modify the
756 original. Optionally, you can copy only a subset of this
759 @param section_subset = a callable object that returns True
760 for each section to be kept
761 @param var_subset = a callable object that returns
762 True for each variable to be kept.
764 @param other if specified, this must be a Conf2Namelist.
765 Instead of creating a new Conf2Namelist, data will be inserted
769 for s,sd
in self.nl.iteritems():
770 if section_subset
is None or section_subset(s):
772 for var,value
in sd.iteritems():
773 if var_subset
is None or var_subset(s,var):
780 """!Removes all traits.
781 Deletes the special Conf2Namelist.TRAIT namelist
783 if Conf2Namelist.TRAIT
in self.
nl:
784 del(self.
nl[Conf2Namelist.TRAIT])
787 """!synonym for make_namelist()
789 Generates a Fortran namelist as a string. Equivalent to
794 """!generates the namelist as a string
796 Returns the stringified namelist for this object, suitable for
797 writing to a file for Fortran to read. Optionally, you can
798 provide a sorting for the namelist entries:
800 @param section_sorter = a cmp-like function for sorting sections by
801 name If absent, cmp is used.
802 @param var_sorters = a dict-like mapping of section names to cmp-like
803 objects for sorting variables within each section. If
804 absent, self.namelist_sorter(sectionname) is used
805 @param morevars a dict of additional variables which override
806 values set in self.nl"""
808 if section_sorter
is None:
813 if morevars
is not None and var
in morevars:
818 for sec
in sorted(self.nl.iterkeys(),section_sorter):
820 if sec==Conf2Namelist.TRAIT:
826 if var_sorters
is not None and sec
in var_sorters:
827 sorter=var_sorters[sec]
830 if sec==Conf2Namelist.TRAIT:
832 exc_hint=
'%s%%%s='%(str(sec),str(var)))) \
833 for var
in sorted(sd.keys(),sorter))
836 exc_hint=
'%s%%%s='%(str(sec),str(var)))) \
837 for var
in sorted(sd.keys(),sorter))
838 if sec==Conf2Namelist.TRAIT:
844 """!return a sorting function for the variables in a namelist
846 Returns a cmp function that orders namelist entries for the
847 specified namelist section. See the argument "cmp" of the
848 python built-in function sorted() for details.
850 @param section the namelist or Conf2Namelist.TRAIT
851 @return a cmp-like function sorter(a,b) """
855 return lambda x,y: cmp(x,y)
857 """!sets the sorting algorithms for namelists and variables
859 Sets the cmp-like functions for sorting sections and
860 variables in each section. The section_sorter sorts sections.
861 The var_sorters is a dict-like mapping from section name to a
862 cmp-like function for sorting that section. If any sorter is
863 unspecified, cmp will be used. See the "cmp" argument of the
864 python built-in function sorted() for details.
866 @param section_sorter a cmp-like function for sorting
867 namelist by namelist name. If section_sorters is None,
869 @param var_sorters a dict-like mapping from namelist name to a
870 variable sorter function. Each variable sorter function must
871 be a cmp-like function that compares variable names. If
872 var_sorters is None, then cmp() will be used for all namelists.
874 self.
section_sorter=cmp
if section_sorter
is None else section_sorter
def trait_set_if_unset(self, var, value)
Sets the traits value if it does not have one.
Generates a Fortran namelist entirely from config files.
def trait_del(self, var)
Deletes a trait.
def trait_get
Returns a trait's value.
def to_fortnml
converts a Python object to fortran namelist format
Raised when hwrf.namelist cannot convert a value to or from Fortran namelist format.
def nl_del(self, section, var)
Removes a variable from a namelist.
def nl_set_if_unset(self, section, var, data)
Sets the value of a namelist variable if it has no value.
def copy(self, other)
Returns a copy of self.
def nl_get
get the value of a variable from a namelist
def __str__(self)
synonym for make_namelist()
def nl_del_sect(self, section)
def join(self, others)
create array values by joining multiple Conf2Namelist objects
def __init__
Conf2Namelist constructor.
def from_fortnml(py)
Converts a fortran namelist value to a Python object.
def trait_each(self)
Iterates over variable,value tuples in the traits.
used to indicate namelist recursion
Time manipulation and other numerical routines.
def namelist_sorter(self, section)
return a sorting function for the variables in a namelist
def nl_set(self, section, var, data)
Sets a variable in a namelist.
def nl_section(self, args)
create namelists if they do not exist
Insert config file data into a Fortran namelist file.
def trait_set(self, var, value)
Sets a trait's value.
def make_namelist
generates the namelist as a string
section_sorter
The cmp function used to sort sections.
def nl_have_sect(self, section)
def nl_each(self, section)
Iterates over variable,value tuples in the given namelist.
Raised when an hwrf.namelist is asked for a key that does not exist.
Exceptions raised by the hwrf package.
nl
A dict of dicts used to store namelist information.
var_sorters
A dict mapping from section name to a cmp function used to sort namelist variables in that section...
def set_sorters(self, section_sorter, var_sorters)
sets the sorting algorithms for namelists and variables
def nl_have(self, section, var)
does this namelist have this variable?
def remove_traits(self)
Removes all traits.
def trait_have(self, var)
Returns True if the trait exists, and False otherwise.