bronx.datagrip.namelist¶
This module contains:
The
LiteralParserclass in charge of type conversion between FORTRAN literals, represented as strings, and corresponding python types. A detailed exemple is given in the class’s documentation.The
NamelistBlockclass that contains a single namelist and allows to modify its content.The
NamelistSetclass that holds a collection of namelist blocks (described byNamelistBlockobjects).The
NamelistParserclass that parse a string, a physical file or File-like object and look for namelist blocks. Upon success, it returns aNamelistSetobject
Inital author: Joris Picot (2010-12-08 / CERFACS)
Module Attributes¶
- bronx.datagrip.namelist.NO_SORTING = 0
Do not sort anything
- bronx.datagrip.namelist.FIRST_ORDER_SORTING = 1
Sort all keys
- bronx.datagrip.namelist.SECOND_ORDER_SORTING = 2
Sort only within indexes or attributes of the same key.
Functions¶
- bronx.datagrip.namelist.namparse(obj, **kwargs)[source]¶
Raw parsing with an default anonymous fortran parser.
This function is a shortcut to the
NamelistParser.parse()method.- Example:
To get a
NamelistSetobject from a string:>>> nset = namparse('&NAM1 A=5.69, / &NAM2 B=1 /') >>> print(nset.dumps()) &NAM1 A=5.69, / &NAM2 B=1, /
Classes¶
- class bronx.datagrip.namelist.LiteralParser(re_flags=18, re_integer='^[+-]?[0-9]+(?:_[A-Z0-9]+)?$', re_boz='^(?:B(?:\'|")[0-1]+(?:\'|")|O(?:\'|")[0-7]+(?:\'|")|Z(?:\'|")[ABCDEF0-9]+(?:\'|"))$', re_real='^[+-]?(?:(?:[0-9]+\\.(?:[0-9]+)?|\\.[0-9]+)(?:[DE][+-]?[0-9]+)?(?:_[A-Z0-9]+)?|[0-9]+[DE][+-]?[0-9]+(?:_[A-Z0-9]+)?)$', re_complex='^[(](?:[+-]?[0-9]+(?:_[A-Z0-9]+)?|[+-]?(?:(?:[0-9]+\\.(?:[0-9]+)?|\\.[0-9]+)(?:[DE][+-]?[0-9]+)?(?:_[A-Z0-9]+)?|[0-9]+[DE][+-]?[0-9]+(?:_[A-Z0-9]+)?)),(?:[+-]?[0-9]+(?:_[A-Z0-9]+)?|[+-]?(?:(?:[0-9]+\\.(?:[0-9]+)?|\\.[0-9]+)(?:[DE][+-]?[0-9]+)?(?:_[A-Z0-9]+)?|[0-9]+[DE][+-]?[0-9]+(?:_[A-Z0-9]+)?))[)]$', re_character='^(?:(?:[A-Z0-9]+_)?\'[^\']*\'|(?:[A-Z0-9]+_)?"[^"]*")$', re_logical='^(?:\\.TRUE\\.(?:_[A-Z0-9]+)?|\\.FALSE\\.(?:_[A-Z0-9]+)?|[TF])$', re_true='\\.T(?:RUE)?\\.|T', re_false='\\.F(?:ALSE)?\\.|F')[source]¶
Bases:
objectObject in charge of parsing literal fortran expressions that could be found in a namelist.
For each literal type (integer, boz, real, complex, character and logical), there is a corresponding function parse_* and a global parser, simply called
parse(), choose automatically the appropriate literal type. Here is the type conversion table:integer -> int
boz -> int
real -> float or Decimal
complex -> complex
character -> string
logical -> bool
For python data, functions are provided for conversion into FORTRAN literals through a LiteralParser. Each literal type has its encode_* function and a global encoder, simply called
encode(), chooses automatically the appropriate encoder; python integers will be converted into a FORTRAN integer, hence the only way to produce a FORTRAN boz is to use encode_boz directly.- Example:
A
LiteralParsercan easily be created:>>> lp = LiteralParser() >>> lp <bronx.datagrip.namelist.LiteralParser object at 0x...>
Basic fortran types could be checked agains a string value:
>>> lp.check_integer('2') True >>> lp.check_integer('2.') False >>> lp.check_integer('2x') False >>> lp.check_real('1.2E-6') True >>> lp.check_logical('.T.') False >>> lp.check_logical('.True.') True >>> lp.check_complex('(2.,0.)') True >>> lp.check_boz("B'11'") True
After a successful type check, one can parse a specific fortran type according to the corresponding method of the
LiteralParser:>>> s = '1.2E-6' >>> lp.check_real(s) True >>> x = lp.parse_real(s) >>> print(x) 0.0000012
It could be more convenient to use the generic
parse()method:>>> x = lp.parse('.true.') >>> print(x) True >>> type(x).__name__ 'bool' >>> x = lp.parse('2.') >>> print(x) 2 >>> type(x) <class 'decimal.Decimal'> >>> x = lp.parse('Z"1F"') >>> print(x) 31 >>> type(x).__name__ 'int'
The reverse operation could be achieved through a specific encodingfunction:
>>> x = 2 >>> print(lp.encode_real(x)) 2. >>> print(lp.encode_integer(x)) 2 >>> print(lp.encode_complex(x)) (2.,0.) >>> print(lp.encode_logical(x)) .TRUE.
It is possible to rely on the internal python type to decide which is the appropriate encoding through the generic
encode()method:>>> x = 2 >>> print(lp.encode(x)) 2 >>> z = 1 - 2j >>> print(lp.encode(z)) (1.,-2.) >>> x = 2. >>> print(lp.encode(x)) 2.
- parse(string)[source]¶
Parse a FORTRAN literal and returns the corresponding python type. Resolution order is: integer, boz, real, complex, character and logical.
- parse_boz(string)[source]¶
If the argument looks like a FORTRAN boz, returns the matching python integer.
- parse_character(string)[source]¶
If the argument looks like a FORTRAN character, returns the matching python string.
- parse_complex(string)[source]¶
If the argument looks like a FORTRAN complex, returns the matching python complex.
- parse_integer(string)[source]¶
If the argument looks like a FORTRAN integer, returns the matching python integer.
- class bronx.datagrip.namelist.NamelistBlock(name='UNKNOWN')[source]¶
Bases:
MutableMappingThis class represents a FORTRAN namelist block.
This class defines all the methods of a usual Python’s dictionary. The keys being the namelist’s variable names.
Macros are special values prefixed and suffixed with
__(e.g.__MYMACRO__) that can be substituted at any time using theaddmacro()method. NB: They need to be declared using theaddmacro()method prior to being used.- Example:
To create an empty
NamelistBlockobject, just provide the name:>>> nb1 = NamelistBlock('MYNAM') >>> nb1 <bronx.datagrip.namelist.NamelistBlock object at 0x... | name=MYNAM len=0>
From now and on, it’s possible to play around with the namelist block:
>>> nb1['A'] = 1 >>> nb1.B = 2. >>> nb1.text = 'MyBad' >>> print(nb1) &MYNAM A=1, B=2., TEXT='MyBad', / >>> for k in nb1: ... print('Entry {:s}: Value is {!s}'.format(k, nb1[k])) ... Entry A: Value is 1 Entry B: Value is 2.0 Entry TEXT: Value is MyBad >>> for k, v in nb1.items(): ... print('Entry {:s}: Value is {!s}'.format(k, v)) ... Entry A: Value is [1] Entry B: Value is [2.0] Entry TEXT: Value is [...'MyBad'] >>> del nb1.B
An example of namelist blocks merge:
>>> nb2 = NamelistBlock('MYNAM') >>> nb2.A = 3 >>> nb2.todelete('text') >>> nb1.merge(nb2) >>> print(nb1) &MYNAM A=3, /
Macros can be defined in a namelist block using the __MACRONAME__ syntax. They can be substituted at anytime:
>>> nb3 = NamelistBlock('MYNAM') >>> nb3.addmacro('MACRO_A') >>> nb3.A = '__MACRO_A__' >>> print(nb3) &MYNAM A=__MACRO_A__, / >>> nb3.addmacro('MACRO_A', 3) >>> print(nb3) &MYNAM A=3, /
- add_declaredmacro(macro, value=None)[source]¶
Add a new old-style declared macro to this definition block, and/or set a value.
- dumps(literal=None, sorting=0)[source]¶
Returns a string of the namelist block that will be readable by fortran parsers.
- Parameters:
sorting – Sorting option. One of
NO_SORTING,FIRST_ORDER_SORTING(sort based on variable names) orSECOND_ORDER_SORTING(sort only within indexes or attributes of the same variable: usefull with arrays).
- iterkeys()¶
Iterate through variable names.
- merge(delta)[source]¶
Merge the delta provided to the current block.
- Parameters:
delta (NamelistBlock) – The namelist block to merge in.
- property name¶
The namelist block name.
- class bronx.datagrip.namelist.NamelistParser(literal=<bronx.datagrip.namelist.LiteralParser object>, macros=None, re_flags=None, re_clean='^(\\s+|![^\\n]*\\n)', re_block='&.*/', re_endblock='^/(end)?', re_bname='[A-Z][A-Z0-9_]*', re_entry='[A-Z][ A-Z0-9_, \\%\\(\\):]*(?=\\s*=)', re_macro='(?P<STRB>[\'"])?\\$?(?P<NAME>[A-Z_][A-Z0-9_]*)(?(STRB)[\'"])', re_freemacro='(?P<STRB>[\'"])?[_]{2}(?P<NAME>[A-Z][A-Z0-9_]*)[_]{2}(?(STRB)[\'"])', re_endol='(?=\\s*(, |/|\\n))', re_comma='\\s*, ')[source]¶
Bases:
objectParser that creates a
NamelistSetobject from a namelist file or a string.Macros (i.e. __SOMETHING__ values) are properly dealt with.
- Example:
To get a
NamelistSetobject from a string:
>>> np = NamelistParser() >>> nset = np.parse('&NAM1 A=5.69, / &NAM2 B=__MYMACRO__ /') >>> print(nset.dumps()) &NAM1 A=5.69, / &NAM2 B=__MYMACRO__, / >>> nset.dumps_needs_update False >>> nset.setmacro('MYMACRO', 'toto') >>> nset.dumps_needs_update True >>> print(nset.dumps()) &NAM1 A=5.69, / &NAM2 B='toto', /
- property literal¶
The literal parser used to process variable values.
- parse(obj)[source]¶
Parse a string or a file.
Returns a
NamelistSetobject.
- class bronx.datagrip.namelist.NamelistSet(blocks_set=None)[source]¶
Bases:
MutableMappingA set of namelist blocks (see
NamelistBlock).This class defines all the methods of a usual Python’s dictionary. The keys being the namelist names and the values the corresponding namelist blocks.
- Example:
To create a
NamelistSetobject populated with a pre-existing namelist block:>>> nb = NamelistBlock('MYNAM') >>> nb.A = 3 >>> nset = NamelistSet([nb, ])
It’s possible to add a new block and customise it:
>>> newblock = nset.newblock('TESTNAM') >>> newblock.A = 1 >>> nset['TESTNAM'].B = 5. >>> print(nset.dumps()) &MYNAM A=3, / &TESTNAM A=1, B=5., /
For instance, this block can be renamed and the previous one deleted:
>>> nset.mvblock('TESTNAM', 'MYNAM2') >>> del nset['MYNAM'] >>> print(nset.dumps()) &MYNAM2 A=1, B=5., /
The
merge()method allows to merge two namelist sets:>>> nset2 = NamelistSet([nb, ]) >>> newblock = nset2.newblock('MYNAM2') >>> newblock.A = 999 >>> print(nset2.dumps()) &MYNAM A=3, / &MYNAM2 A=999, / >>> nset.merge(nset2) >>> print(nset.dumps()) &MYNAM A=3, / &MYNAM2 A=999, B=5., /
- Parameters:
blocks_set (list[NamelistBlock]) – A list of
NamelistBlockobjects (if missing, an empty list is assumed).
- add(namblock)[source]¶
Add a namelist block object to the present namelist set.
- Parameters:
namblock (NamelistBlock) – The namelist block to add.
- dumps(sorting=0, block_sorting=True)[source]¶
Join the fortran’s strings dumped by each namelist block.
- Parameters:
sorting – Sorting option. One of
NO_SORTING,FIRST_ORDER_SORTING(sort based on variable names) orSECOND_ORDER_SORTING(sort only within indexes or attributes of the same variable: usefull with arrays).block_sorting (bool) – if True, namelist blocks are ordered based on their name.
- merge(delta, rmkeys=None, rmblocks=None, clblocks=None)[source]¶
Merge of the current namelist set with the set of namelist blocks provided.