Skip to content

Instantly share code, notes, and snippets.

@ExpHP
Last active March 1, 2016 05:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ExpHP/e83e4bfea4b7827d785f to your computer and use it in GitHub Desktop.
Save ExpHP/e83e4bfea4b7827d785f to your computer and use it in GitHub Desktop.
diff --git a/f90nml/parser.py b/f90nml/parser.py
index 687de10..7fb42d7 100644
--- a/f90nml/parser.py
+++ b/f90nml/parser.py
@@ -75,25 +75,39 @@ class Parser(object):
>>> parser = Parser()
>>> data_nml = parser.read('data.nml')"""
- nml_file = open(nml_fname, 'r')
+ nml_is_file = hasattr(nml_fname, 'read')
+ nml_file = nml_fname if nml_is_file else open(nml_fname, 'r')
+ try:
if nml_patch_in:
if not isinstance(nml_patch_in, dict):
- nml_file.close()
- raise ValueError('Input patch must be a dict or a Namelist.')
+ raise ValueError('Input patch must be a dict or a '
+ 'Namelist.')
nml_patch = copy.deepcopy(Namelist(nml_patch_in))
if not patch_fname:
patch_fname = nml_fname + '~'
elif nml_fname == patch_fname:
- nml_file.close()
- raise ValueError('f90nml: error: Patch filepath cannot be the '
- 'same as the original filepath.')
- self.pfile = open(patch_fname, 'w')
+ raise ValueError('f90nml: error: Patch filepath cannot be '
+ 'the same as the original filepath.')
+
+ patch_is_file = hasattr(patch_fname, 'read')
+ self.pfile = patch_fname if patch_is_file else open(patch_fname, 'w')
else:
nml_patch = Namelist()
+ return self._read(nml_file, nml_patch)
+
+ finally:
+ if not nml_is_file:
+ nml_file.close()
+ if self.pfile and not patch_is_file:
+ self.pfile.close()
+
+ def _read(self, nml_file, nml_patch):
+ """ implementaton of read given an open file handle and a Namelist """
+
f90lex = shlex.shlex(nml_file)
f90lex.whitespace = ''
f90lex.wordchars += '.-+' # Include floating point tokens
@@ -140,14 +154,8 @@ class Parser(object):
# Set the next active variable
if self.token in ('=', '(', '%'):
- try:
- v_name, v_values = self.parse_variable(
- g_vars, patch_nml=grp_patch)
- except ValueError:
- nml_file.close()
- if self.pfile:
- self.pfile.close()
- raise
+ v_name, v_values = self.parse_variable(g_vars,
+ patch_nml=grp_patch)
if v_name in g_vars:
v_prior_values = g_vars[v_name]
@@ -195,10 +203,6 @@ class Parser(object):
except StopIteration:
break
- nml_file.close()
- if self.pfile:
- self.pfile.close()
-
return nmls
def parse_variable(self, parent, patch_nml=None):
diff --git a/f90nml/parser.py b/f90nml/parser.py
index 6a582f5..44a72cf 100644
--- a/f90nml/parser.py
+++ b/f90nml/parser.py
@@ -75,6 +75,9 @@ class Parser(object):
>>> parser = Parser()
>>> data_nml = parser.read('data.nml')"""
+ nml_is_file = hasattr(nml_fname, 'read')
+ patch_is_file = hasattr(patch_fname, 'read')
+
# Convert patch data to a Namelist object
if nml_patch_in:
if not isinstance(nml_patch_in, dict):
@@ -83,15 +86,37 @@ class Parser(object):
nml_patch = copy.deepcopy(Namelist(nml_patch_in))
if not patch_fname:
- patch_fname = nml_fname + '~'
+ if nml_is_file:
+ # TODO - probably ValueError: No output file for patch, or
+ # maybe warning?
+ else:
+ patch_fname = nml_fname + '~'
elif nml_fname == patch_fname:
raise ValueError('f90nml: error: Patch filepath cannot be the '
'same as the original filepath.')
- self.pfile = open(patch_fname, 'w')
+
+ self.pfile = patch_fname if patch_is_file else open(patch_fname, 'w')
else:
nml_patch = Namelist()
- nml_file = open(nml_fname, 'r')
+ # auto-close self.pfile
+ try:
+ nml_file = nml_fname if nml_is_file else open(nml_fname, 'r')
+
+ # auto-close nml_file
+ try:
+
+ return self._read(nml_file, nml_patch)
+
+ finally:
+ if not nml_is_file:
+ nml_file.close()
+ finally:
+ if self.pfile and not patch_is_file:
+ self.pfile.close()
+
+ def _read(self, nml_file, nml_patch):
+ """ implementaton of read given an open file handle and a Namelist """
f90lex = shlex.shlex(nml_file)
f90lex.whitespace = ''
@@ -139,14 +164,8 @@ class Parser(object):
# Set the next active variable
if self.token in ('=', '(', '%'):
- try:
- v_name, v_values = self.parse_variable(
- g_vars, patch_nml=grp_patch)
- except ValueError:
- nml_file.close()
- if self.pfile:
- self.pfile.close()
- raise
+ v_name, v_values = self.parse_variable(
+ g_vars, patch_nml=grp_patch)
if v_name in g_vars:
v_prior_values = g_vars[v_name]
@@ -194,10 +213,6 @@ class Parser(object):
except StopIteration:
break
- nml_file.close()
- if self.pfile:
- self.pfile.close()
-
return nmls
def parse_variable(self, parent, patch_nml=None):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment