Source code for esm_rcfile.esm_rcfile
"""
=====
Usage
=====
This package contains functions to set, get, and use entries stored in the
esmtoolsrc file.
To use ESM RCFile in a project::
import esm_rcfile
You can set specific values in the ``~/.esmtoolsrc`` with::
set_rc_entry(key, value)
For example::
>>> set_rc_entry("SCOPE_CONFIG", "/pf/a/a270077/Code/scope/configs/")
Retriving an entry::
>>> fpath = get_rc_entry("FUNCTION_PATH")
>>> print(fpath)
/pf/a/a270077/Code/esm_tools/esm_tools/configs
With a default value for a non-existing key::
>>> scope_config = get_rc_entry("SCOPE_CONFIG", "/dev/null")
>>> print(scope_config)
/dev/null
Without a default value, you get ``EsmRcfileError``::
>>> echam_namelist = get_rc_entry("ECHAM_NMLDIR")
EsmRcFileError: No value for ECHAM_NMLDIR found in esmtoolsrc file!!
This error is also raised if there is no ``~/.esmtoolsrc`` file, and no default
is provided.
You can also get the entire rcfile as a dict::
>>> rcdict = import_rc_file()
API Documentation
-----------------
"""
import os
import esm_tools
rcfile = os.path.expanduser("~") + "/.esmtoolsrc"
[docs]class EsmToolsDir(str):
"""
A string subclass whose instances provide the paths to `esm_tools` folders
(`configs`, `namelists` and `runscripts`) when evaluated as a string (i.e.
`str(<your_instance>)` or `<your_instance> + <a_string>`).
This class is thought as a generalised solution for the problem of removing the
`FUNCTION_PATH`, `NAMELIST_PATH` and `RUNSCRIPT_PATH` from the `.esmtoolsrc` file,
and intends to provide those paths correctly, both for virtual environment and open
runs, right at the time where the variable containing the instance is evaluated
by the `esm_parser`, as a string.
This should solve issues with, for example, preprocessing and postprocessing scripts
called during runtime with a `NONE_YET/<path_to_the_script>`.
"""
def __init__(self, path_type):
"""
Initializes the instance. To do that, use `<your_instance_name> =
EsmToolsDir(<path_type>)` where `path_type` can be::
- "FUNCTION_PATH"
- "NAMELIST_PATH"
- "RUNSCRIPT_PATH"
Parameters
----------
path_type : str
ESM-Tools path type to be loaded by the object.
"""
self.path_type = path_type
def __str__(self):
"""
When the instance is evaluated as a string, it returns the correct path to its
corresponding `esm_tools` folder.
Returns
-------
<esm_tools_folder_type_PATH> : str
The path to the required folder.
"""
return self.find_path()
def __add__(self, add_string):
"""
When the instance is used together with a sum operation, it returns the correct
path to its corresponding `esm_tools` folder, plus the operation input.
Parameters
----------
add_string : str
String to be added to the path.
Returns
-------
<PATH+add_string> : str
The path to the required folder plus the string that follows (`add_string`).
"""
return self.find_path() + add_string
[docs] def find_path(self):
"""
This method returns the path of the `esm_tools` folder required.
Returns
-------
<esm_tools_folder_type_PATH> : str
The path to the required folder.
"""
if self.path_type=="FUNCTION_PATH":
return esm_tools.get_config_filepath("") + "/"
elif self.path_type=="NAMELIST_PATH":
return esm_tools.get_namelist_filepath("") + "/"
elif self.path_type=="RUNSCRIPT_PATH":
return esm_tools.get_runscript_filepath("") + "/"
else:
raise Exception("Incorrect path type!")
[docs]def set_rc_entry(key, value):
"""
Sets values in ``esmtoolsrc``
Parameters
----------
key : str
value : str
Note
----
Using this functions modifies the ``rcfile``; which is stored in the
current user's home directory.
"""
all_lines = [key + "=" + value]
if os.path.isfile(rcfile):
with open(rcfile) as rc:
for line in rc.readlines():
line = line.strip()
if not key == line.split("=", 1)[0]:
all_lines.append(line)
os.remove(rcfile)
with open(rcfile, "w") as rc:
for line in all_lines:
rc.write(line + "\n")
[docs]def get_rc_entry(key, default=None):
"""
Gets a specific entry
Parameters
----------
key : str
default : str
Returns
-------
str
Value for key, or default if provided
Raises
------
EsmRcfileError
* Raised if key cannot be found in the rcfile and no default is
provided
* Raised if the esmtoolsrc file cannot be found and no default is
provided.
"""
if os.path.isfile(rcfile):
with open(rcfile) as rc:
for line in rc.readlines():
line = line.strip()
if line.split("=", 1)[0] == key.upper():
return line.split("=", 1)[1]
if default:
return default
else:
raise EsmRcfileError("No value for %s found in esmtoolsrc file!" % key)
if default:
return default
else:
raise EsmRcfileError("The file esmtoolsrc file was not found!")
[docs]def import_rc_file():
"""
Gets current values of the esmtoolsrc file
Returns
-------
dict
A dictionary representation of the rcfile
"""
if os.path.isfile(rcfile):
rcdict = {}
with open(rcfile) as rc:
for line in rc.readlines():
line = line.strip()
rcdict[line.split("=", 1)[0]] = line.split("=", 1)[1]
return rcdict
raise EsmRcfileError("The file esmtoolsrc file was not found!")
# PG: Should this be in a if __name__ == "__main__" ?
# MA: The following lines are most likely never reached since the work
# from PG in implementing the venv. It is probably wise to remove them
# in the next cleanup.
if os.path.isfile(rcfile):
FUNCTION_PATH = get_rc_entry("FUNCTION_PATH", "NONE_YET")
else:
FUNCTION_PATH = "NONE_YET"