diff --git a/acclimatise/cli_types.py b/acclimatise/cli_types.py index 4df8ed8..1a7338b 100644 --- a/acclimatise/cli_types.py +++ b/acclimatise/cli_types.py @@ -13,6 +13,11 @@ class CliType: A data type used in the command-line """ + default: Optional[typing.Any] = None + """ + A default value, None if unknown + """ + @property def representable(self) -> set: """ @@ -31,6 +36,11 @@ class CliEnum(CliType): One of a list of possible options """ + default: Optional[Enum] = None + """ + A default value, None if unknown + """ + enum: Enum """ The possible options as a Python Enum @@ -43,7 +53,10 @@ class CliFloat(CliType): Takes a floating-point value """ - pass + default: Optional[float] = None + """ + A default value, None if unknown + """ @dataclass(unsafe_hash=True) @@ -52,6 +65,11 @@ class CliInteger(CliType): Takes an integer value """ + default: Optional[int] = None + """ + A default value, None if unknown + """ + _representable = {CliFloat} @@ -61,7 +79,10 @@ class CliString(CliType): Takes a string value """ - pass + default: Optional[str] = None + """ + A default value, None if unknown + """ @dataclass(unsafe_hash=True) @@ -70,7 +91,10 @@ class CliBoolean(CliType): Takes a boolean value """ - pass + default: Optional[bool] = None + """ + A default value, None if unknown + """ @dataclass(unsafe_hash=True) @@ -79,7 +103,10 @@ class CliDir(CliType): Takes a directory path """ - pass + default: Optional[str] = None + """ + A default value, None if unknown + """ @dataclass(unsafe_hash=True) @@ -88,7 +115,10 @@ class CliFile(CliType): Takes a file path """ - pass + default: Optional[str] = None + """ + A default value, None if unknown + """ @dataclass(unsafe_hash=True) @@ -97,6 +127,11 @@ class CliDict(CliType): Takes a dictionary value """ + default: Optional[str] = None + """ + A default value, None if unknown + """ + key: CliType """ Data type of the keys to this dictionary @@ -114,6 +149,11 @@ class CliList(CliType): Takes a list value """ + default: Optional[typing.List[CliType]] = None + """ + A default value, None if unknown + """ + value: CliType """ Data type of the values in this list @@ -126,6 +166,12 @@ class CliTuple(CliType): Takes a list of values with a fixed length, possibly each with different types """ + default: Optional[typing.Tuple[CliType]] = None + + """ + A default value, None if unknown + """ + values: typing.List[CliType] """ List of types, in order, held within the tuple diff --git a/acclimatise/model.py b/acclimatise/model.py index 53eb03a..0745fa1 100644 --- a/acclimatise/model.py +++ b/acclimatise/model.py @@ -371,33 +371,48 @@ def capital(self): ) -int_re = re.compile("(int(eger)?)|size|length|max|min", flags=re.IGNORECASE) +int_re = re.compile("(int(eger)?)|size|length|max|min|num(ber)?", 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) +default_re = re.compile(r"default(?: value)?(?:[:=] ?| )([^ )\]]+)", flags=re.IGNORECASE) + +float_re = re.compile('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)', flags=re.IGNORECASE) +int_re = re.compile('[+-]?([0-9]+[^.0-9])', flags=re.IGNORECASE) + 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 """ + default_match = default_re.match() + if default_match is not None: + default = default_match.group(1) + else: + default = None + if bool_re.match(string): - return cli_types.CliBoolean() + return cli_types.CliBoolean(default = default) elif float_re.match(string): - return cli_types.CliFloat() + return cli_types.CliFloat(default = default) elif int_re.match(string): - return cli_types.CliInteger() + return cli_types.CliInteger(default = default) elif file_re.match(string): - return cli_types.CliFile() + return cli_types.CliFile(default = default) elif dir_re.match(string): - return cli_types.CliDir() + return cli_types.CliDir(default = default) elif str_re.match(string): - return cli_types.CliString() + return cli_types.CliString(default = default) + elif float_re.search(string) and not int_re.search(string): + return cli_types.CliFloat(default = default) + elif not int_re.search(string) and int_re.search(string): + return cli_types.CliInteger(default = default) else: - return cli_types.CliString() + return cli_types.CliString(default = default) @yaml_object(yaml)