...
 
Commits (4)
......@@ -4,3 +4,4 @@ dist
namelist.egg-info
*.pyc
.coverage
.cache
......@@ -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"^=$")
......@@ -151,53 +151,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: # container is a list
container.append(value)
def _tokenize(text):
"""Extract syntax tokens."""
fs = "$$$FS$$$"
......
......@@ -150,7 +150,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\nval1=34\nval2=35\n&end",
]
)
......@@ -215,6 +215,33 @@ 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 val= {}, val2='lsl'/"])
@pytest.mark.parametrize("op", ["+", "-", "/", "*", "**"])
@pytest.mark.parametrize(
......