Skip to content

Commit

Permalink
Patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
b8raoult committed Dec 18, 2020
1 parent 7990696 commit 5987ec1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
54 changes: 43 additions & 11 deletions climetlab/utils/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,76 @@


class Any:
def substitute(self, value):
def substitute(self, value, name):
return value


class Enum:
def __init__(self, enum=""):
self.enum = set(enum.split(","))

def substitute(self, value, name):
if self.enum and value not in self.enum:
raise ValueError(
"Invalid value '{}' for parameter '{}', expected one of {}".format(
value, name, self.enum
)
)
return value


class Int:
def __init__(self, format="%d"):
self.format = format

def substitute(self, value):
assert isinstance(value, int)
def substitute(self, value, name):
if not isinstance(value, int):
raise ValueError(
"Invalid value '{}' for parameter '{}', expected an integer".format(
value, name
)
)
return self.format % value


class Float:
def __init__(self, format="%g"):
self.format = format

def substitute(self, value):
assert isinstance(value, (int, float))
def substitute(self, value, name):
if not isinstance(value, (int, float)):
raise ValueError(
"Invalid value '{}' for parameter '{}', expected a float".format(
value, name
)
)

return self.format % value


class Datetime:
def __init__(self, format):
self.format = format

def substitute(self, value):
def substitute(self, value, name):
return to_datetime(value).strftime(self.format)


class Str:
def __init__(self, format="%s"):
self.format = format

def substitute(self, value):
assert isinstance(value, str)
def substitute(self, value, name):
if not isinstance(value, str):
raise ValueError(
"Invalid value '{}' for parameter '{}', expected a string".format(
value, name
)
)
return self.format % value


TYPES = {"": Any, "int": Int, "float": Float, "date": Datetime}
TYPES = {"": Any, "int": Int, "float": Float, "date": Datetime, "enum": Enum}


class Constant:
Expand All @@ -79,7 +109,9 @@ def __init__(self, value):
self.kind = TYPES[kind[0]](kind[1])

def substitute(self, params):
return self.kind.substitute(params[self.name])
if self.name not in params:
raise ValueError("Missing parameter '{}'".format(self.name))
return self.kind.substitute(params[self.name], self.name)


class Pattern:
Expand Down Expand Up @@ -111,6 +143,6 @@ def substitute(self, *args, **kwargs):
used.discard(p.name)
result.append(p.substitute(params))
if used:
raise ValueError("Unused parameters: {}".format(used))
raise ValueError("Unused parameter(s): {}".format(used))

return "".join([str(x) for x in result])
9 changes: 8 additions & 1 deletion tests/test_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ def test_patterns():
assert p.names == ["date", "level", "param"], p.names

assert (
p.substitute(dict(date="2000-01-01", param="2t", level=12)) == "20000101-2t-12-012"
p.substitute(dict(date="2000-01-01", param="2t", level=12))
== "20000101-2t-12-012"
)

p = Pattern("{variable:enum(2t,tp)}.{type:enum(rt,hc)}.{date:date(%Y%m%d)}.grib")
assert (
p.substitute(dict(date="2000-01-01", variable="tp", type='rt'))
== "tp.rt.20000101.grib"
)


Expand Down

0 comments on commit 5987ec1

Please sign in to comment.