Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Martin Claus
py-namelist
Commits
eab9c087
Commit
eab9c087
authored
Oct 05, 2018
by
Martin Claus
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '6-fix-index-assignment' into 'develop'
Resolve "Fix index assignment" Closes
#6
See merge request
!8
parents
8b94fbba
7aa86d68
Pipeline
#1899
passed with stage
in 42 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
138 additions
and
12 deletions
+138
-12
.gitignore
.gitignore
+1
-0
examples/merge_NEMO_namelists.py
examples/merge_NEMO_namelists.py
+21
-0
namelist/namelist.py
namelist/namelist.py
+48
-11
tests/test_parsing.py
tests/test_parsing.py
+68
-1
No files found.
.gitignore
View file @
eab9c087
...
...
@@ -4,3 +4,4 @@ dist
namelist.egg-info
*.pyc
.coverage
.cache
examples/merge_NEMO_namelists.py
0 → 100644
View file @
eab9c087
from
context
import
namelist
in_file_ref
=
"namelist_ref"
in_file_cfg
=
"namelist_cfg"
with
open
(
in_file_ref
)
as
f
:
ref_nmls
=
namelist
.
parse_namelist_file
(
f
)
with
open
(
in_file_cfg
)
as
f
:
cfg_nmls
=
namelist
.
parse_namelist_file
(
f
)
nmls
=
ref_nmls
.
copy
()
for
k
in
cfg_nmls
:
if
k
in
nmls
:
nmls
[
k
].
update
(
cfg_nmls
[
k
])
else
:
nmls
[
k
]
=
cfg_nmls
[
k
]
for
nml
in
nmls
:
print
(
str
(
nmls
[
nml
]))
namelist/namelist.py
View file @
eab9c087
...
...
@@ -19,7 +19,7 @@ valueBool = re.compile(r"(\.(true|false|t|f)\.)", re.I)
quote
=
re
.
compile
(
r
"([\']{1}[^\']*[\']{1}|[\"]{1}[^\"]*[\"]{1})"
,
re
.
MULTILINE
)
namelistname
=
re
.
compile
(
r
"&("
+
varname
+
r
")"
)
paramname
=
re
.
compile
(
r
"^("
+
varname
+
r
")"
)
paramname
=
re
.
compile
(
r
"^("
+
varname
+
r
")"
+
r
"(\(([0-9]*)\))?"
+
r
"$"
)
namlistend
=
re
.
compile
(
r
'^(&(end)?|/)$'
,
re
.
I
)
comment
=
re
.
compile
(
r
"!.*$"
,
re
.
MULTILINE
)
equalsign
=
re
.
compile
(
r
"^=$"
)
...
...
@@ -62,8 +62,13 @@ class Namelist(DictClass):
"""
retstr
=
"&%s
\n
"
%
str
(
self
.
name
)
for
k
,
v
in
self
.
items
():
if
hasattr
(
v
,
'__iter__'
):
retstr
+=
"%s = (/ "
%
k
if
hasattr
(
v
,
'islower'
):
# is a string
retstr
+=
"{} = {}
\n
"
.
format
(
k
,
repr
(
v
))
elif
hasattr
(
v
,
'items'
):
# is a dictionary
for
i
,
ival
in
v
.
items
():
retstr
+=
"{}({}) = {}
\n
"
.
format
(
k
,
i
,
repr
(
ival
))
elif
hasattr
(
v
,
'index'
):
# is an array
retstr
+=
"{} = (/ "
.
format
(
k
)
tmpstr
=
""
for
vv
in
v
:
if
isinstance
(
vv
,
bool
):
...
...
@@ -151,53 +156,85 @@ def parse_namelist_string(in_string):
"""
retlist
=
[]
content
=
_tokenize
(
in_string
)
index
=
0
for
item
in
content
:
match
=
re
.
match
(
namelistname
,
item
)
if
match
:
nmlname
=
match
.
group
(
1
)
nml
=
Namelist
(
nmlname
)
retlist
.
append
(
nml
)
continue
match
=
re
.
match
(
paramname
,
item
)
if
match
:
pname
=
match
.
group
(
1
)
nml
[
pname
]
=
[]
continue
index
=
match
.
group
(
3
)
try
:
# index assignment
index
=
int
(
index
)
if
pname
not
in
nml
:
nml
[
pname
]
=
DictClass
()
except
TypeError
:
# index is None
nml
[
pname
]
=
[]
continue
# pragma no cover
if
re
.
match
(
namlistend
,
item
):
continue
if
re
.
match
(
equalsign
,
item
):
continue
match
=
re
.
match
(
valueBool
,
item
)
if
match
:
nml
[
pname
]
.
append
(
match
.
group
(
1
)[
1
].
lower
()
==
"t"
)
_add_value
(
nml
[
pname
]
,
match
.
group
(
1
)[
1
].
lower
()
==
"t"
,
index
)
continue
match
=
re
.
match
(
quote
,
item
)
if
match
:
nml
[
pname
]
.
append
(
match
.
group
(
1
)[
1
:
-
1
])
_add_value
(
nml
[
pname
]
,
match
.
group
(
1
)[
1
:
-
1
]
,
index
)
continue
try
:
nml
[
pname
].
append
(
int
(
item
))
i
=
int
(
item
)
_add_value
(
nml
[
pname
],
i
,
index
)
except
ValueError
:
pass
else
:
continue
# pragma: no cover
try
:
nml
[
pname
].
append
(
float
(
item
))
f
=
float
(
item
)
_add_value
(
nml
[
pname
],
f
,
index
)
except
ValueError
:
pass
else
:
continue
# pragma: no cover
match
=
re
.
match
(
computation
,
item
)
if
match
:
nml
[
pname
].
append
(
eval
(
item
))
_add_value
(
nml
[
pname
],
eval
(
item
),
index
)
for
nml
in
retlist
:
for
k
,
v
in
nml
.
items
():
if
len
(
v
)
==
1
:
nml
[
k
]
=
v
[
0
]
try
:
nml
[
k
]
=
v
[
0
]
except
KeyError
:
pass
ret_dict
=
DictClass
(
zip
([
nml
.
name
for
nml
in
retlist
],
retlist
))
return
ret_dict
def
_add_value
(
container
,
value
,
key
):
try
:
# test if container is a dict like object
container
.
keys
()
container
[
key
]
=
value
except
AttributeError
:
# container is a list
container
.
append
(
value
)
def
_tokenize
(
text
):
"""Extract syntax tokens."""
fs
=
"$$$FS$$$"
...
...
tests/test_parsing.py
View file @
eab9c087
...
...
@@ -58,6 +58,7 @@ def test_parse_file(string):
"&nml
\n
val1 = .FALSE.
\n
/
\n
"
,
"&nml
\n
val1 = (/ 1,2,3,4,5,6 /)
\n
/
\n
"
,
"&nml
\n
val1 = (/ .TRUE.,.FALSE.,.TRUE.,.TRUE. /)
\n
/
\n
"
,
"&nml
\n
val1 = 3
\n
val2 = 5
\n
/
\n
"
,
]
)
def
test_string_out
(
string
):
...
...
@@ -150,7 +151,7 @@ def test_val_conversion(string, val):
@
pytest
.
mark
.
parametrize
(
"string"
,
[
"&nml3 val1=34, val2=35 &end"
,
"&nml3 val1
=
34 val2
=
35 &end"
,
"&nml3 val1
=
34 val2
=
35 &end"
,
"&nml3
\n
val1=34
\n
val2=35
\n
&end"
,
]
)
...
...
@@ -189,6 +190,7 @@ def test_var_bool(string, val):
)
def
test_var_string
(
string
,
val
):
nml
=
namelist
.
parse_namelist_string
(
string
)[
"nml"
]
print
(
str
(
nml
))
assert
nml
[
"val"
]
==
val
...
...
@@ -215,6 +217,71 @@ def test_var_array(string, arr):
assert
type
(
a
)
==
type
(
b
)
@
pytest
.
mark
.
parametrize
(
"string"
,
[
"&nml {} /"
,
"&nml {} val2=34 /"
])
@
pytest
.
mark
.
parametrize
(
"val1"
,
[
"lala"
,
"((1 + 2) + 3)"
,
3
,
3.0
,
3e6
,
".T."
])
@
pytest
.
mark
.
parametrize
(
"d"
,
[{
1
:
None
,
2
:
35
},{
1
:
None
}])
def
test_index_assignment
(
string
,
val1
,
d
):
val_str
=
""
try
:
int
(
eval
(
val1
))
is_expression
=
True
except
:
is_expression
=
False
is_bool
=
(
val1
==
".T."
)
d
[
1
]
=
val1
for
k
,
v
in
d
.
items
():
if
is_expression
|
is_bool
:
val_str
+=
"val({}) = {} "
.
format
(
k
,
v
)
else
:
val_str
+=
"val({}) = {} "
.
format
(
k
,
repr
(
v
))
if
is_expression
:
d
[
1
]
=
eval
(
d
[
1
])
if
is_bool
:
d
[
1
]
=
(
val1
==
".T."
)
nml_string
=
string
.
format
(
val_str
)
nml
=
namelist
.
parse_namelist_string
(
nml_string
)[
"nml"
]
print
(
nml_string
)
print
(
repr
(
nml
),
d
)
assert
nml
[
"val"
]
==
d
@
pytest
.
mark
.
parametrize
(
"string"
,
[
"&nml
\n
{}/
\n
"
,
"&nml
\n
{}val2 = 34
\n
/
\n
"
])
@
pytest
.
mark
.
parametrize
(
"val1"
,
[
"some_string"
,
"((1 + 2) + 3)"
,
3
,
3.0
,
3e6
,
".T."
]
)
@
pytest
.
mark
.
parametrize
(
"d"
,
[{
1
:
None
,
2
:
35
},
{
1
:
None
}])
def
test_index_assignment_to_str
(
string
,
d
,
val1
):
try
:
int
(
eval
(
val1
))
is_expression
=
True
except
(
NameError
,
SyntaxError
,
TypeError
):
is_expression
=
False
is_bool
=
(
val1
==
".T."
)
d
[
1
]
=
val1
val_str
=
""
for
k
,
v
in
d
.
items
():
if
is_expression
|
is_bool
:
val_str
+=
"val({}) = {}
\n
"
.
format
(
k
,
v
)
else
:
val_str
+=
"val({}) = {}
\n
"
.
format
(
k
,
repr
(
v
))
nml_string
=
string
.
format
(
val_str
)
nml
=
namelist
.
parse_namelist_string
(
nml_string
)[
"nml"
]
if
is_expression
:
d
[
1
]
=
eval
(
d
[
1
])
if
is_bool
:
d
[
1
]
=
(
val1
==
".T."
)
valid_String
=
""
for
k
,
v
in
d
.
items
():
valid_String
+=
"val({}) = {}
\n
"
.
format
(
k
,
repr
(
v
))
valid_String
=
string
.
format
(
valid_String
)
print
(
valid_String
,
nml_string
,
str
(
nml
))
print
(
is_expression
,
is_bool
)
assert
valid_String
==
str
(
nml
)
@
pytest
.
mark
.
parametrize
(
"string"
,
[
"&nml val= {}, val2='lsl'/"
])
@
pytest
.
mark
.
parametrize
(
"op"
,
[
"+"
,
"-"
,
"/"
,
"*"
,
"**"
])
@
pytest
.
mark
.
parametrize
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment