Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions acclimatise/cli_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,19 @@ class CliBoolean(CliType):


@dataclass(unsafe_hash=True)
class CliDir(CliType):
class CliFileSystemType(CliType):
Comment thread
bernt-matthias marked this conversation as resolved.
"""
Takes a directory / file path
"""

output: bool = False
"""
Indicator if it is input or output
"""


@dataclass(unsafe_hash=True)
class CliDir(CliFileSystemType):
"""
Takes a directory path
"""
Expand All @@ -83,7 +95,7 @@ class CliDir(CliType):


@dataclass(unsafe_hash=True)
class CliFile(CliType):
class CliFile(CliFileSystemType):
"""
Takes a file path
"""
Expand Down
56 changes: 42 additions & 14 deletions acclimatise/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,31 +370,59 @@ def capital(self):
)


int_re = re.compile("(int(eger)?)|size|length|max|min", flags=re.IGNORECASE)
str_re = re.compile("str(ing)?", flags=re.IGNORECASE)
float_re = re.compile("float|decimal", flags=re.IGNORECASE)
bool_re = re.compile("bool(ean)?", flags=re.IGNORECASE)
file_re = re.compile("file|path", flags=re.IGNORECASE)
dir_re = re.compile("folder|directory", flags=re.IGNORECASE)
int_re = re.compile(
r"\b((int(eger)?)|size|length|max|min|(num(ber)?))\b", flags=re.IGNORECASE
)
str_re = re.compile(r"\bstr(ing)?\b", flags=re.IGNORECASE)
float_re = re.compile(r"\b(float|decimal)\b", flags=re.IGNORECASE)
bool_re = re.compile(r"\bbool(ean)?\b", flags=re.IGNORECASE)
file_re = re.compile(r"\b(file|path)\b", flags=re.IGNORECASE)
input_re = re.compile(r"input", flags=re.IGNORECASE)
Comment thread
multimeric marked this conversation as resolved.
output_re = re.compile(r"output", flags=re.IGNORECASE)
dir_re = re.compile(r"\b(folder|directory)\b", flags=re.IGNORECASE)

float_num_re = re.compile(
r"[+-]?(([0-9]*\.[0-9]+)|((?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)))",
flags=re.IGNORECASE,
)
int_num_re = re.compile(r"([+-]?[0-9]+)", flags=re.IGNORECASE)


def distinguish_inout(
string, cls: typing.Type[cli_types.CliFileSystemType]
) -> cli_types.CliFileSystemType:
"""
distinguish input/output files/directories given a string
"""
im = input_re.search(string)
om = output_re.search(string)
if not im and om:
return cls(output=True)
else:
return cls(output=False)


def infer_type(string) -> typing.Optional[cli_types.CliType]:
"""
Reads a string (argument description etc) to find hints about what type this argument might be. This is
generally called by the get_type() methods
"""
if bool_re.match(string):
Comment thread
bernt-matthias marked this conversation as resolved.
if bool_re.search(string):
return cli_types.CliBoolean()
elif float_re.match(string):
elif float_re.search(string):
return cli_types.CliFloat()
elif int_re.match(string):
elif int_re.search(string):
return cli_types.CliInteger()
elif file_re.match(string):
return cli_types.CliFile()
elif dir_re.match(string):
return cli_types.CliDir()
elif str_re.match(string):
elif file_re.search(string):
return distinguish_inout(string, cli_types.CliFile)
elif dir_re.search(string):
return distinguish_inout(string, cli_types.CliDir)
elif str_re.search(string):
return cli_types.CliString()
elif float_num_re.search(string):
return cli_types.CliFloat()
elif int_num_re.search(string):
return cli_types.CliInteger()
else:
return None

Expand Down
42 changes: 42 additions & 0 deletions test/test_type_inference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pytest

from acclimatise.cli_types import (
CliBoolean,
CliDir,
CliFile,
CliFloat,
CliInteger,
CliString,
)
from acclimatise.model import infer_type


@pytest.mark.parametrize(
Comment thread
bernt-matthias marked this conversation as resolved.
"string,typ",
[
("", None),
("int", CliInteger()),
("size", CliInteger()),
("length", CliInteger()),
("max", CliInteger()),
("min", CliInteger()),
("str", CliString()),
("float", CliFloat()),
("decimal", CliFloat()),
("bool", CliBoolean()),
("file", CliFile()),
("path", CliFile()),
("input file", CliFile(output=False)),
("output file", CliFile(output=True)),
("folder", CliDir()),
("directory", CliDir()),
("output directory", CliDir(output=True)),
("blah 23 blub", CliInteger()),
("nonsense 23.42", CliFloat()),
(".42 gibberish", CliFloat()),
("1E-5", CliFloat()),
],
)
def test_type_inference(string, typ):
inferred_type = infer_type(string)
assert inferred_type == typ