Skip to content

Commit

Permalink
Add regex Pattern type cast
Browse files Browse the repository at this point in the history
  • Loading branch information
yar-kik committed Dec 24, 2022
1 parent c74116a commit 2392238
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
21 changes: 17 additions & 4 deletions app_properties/type_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)

import inspect
import re
from collections.abc import Iterable, Mapping
from dataclasses import MISSING, Field, fields, is_dataclass
from datetime import date, datetime, time, timedelta
Expand Down Expand Up @@ -46,13 +47,17 @@ def cast_types(self, type_: Union[type, Any], value: Any) -> Any:
return self._apply_dataclass(type_, value)
return self._cast_base(type_, value)

def _cast_base(self, type_: type, value: Any) -> Any:
def _cast_base(self, type_: Type, value: Any) -> Any:
if self._is_none_type(type_):
return None
if value is None and not issubclass(type_, Enum):
return type_()
if type_ == bool:
return self._cast_bool(value)
if type_ == re.Pattern:
return self._apply_regex_pattern(value)
if issubclass(type_, Enum):
return self._apply_enum(type_, value)
if value is None:
return type_()
return type_(value)

def _cast_bool(self, value: Any) -> Optional[bool]:
Expand All @@ -61,7 +66,7 @@ def _cast_bool(self, value: Any) -> Optional[bool]:
value = str(value)
if value in ("true", "True", "1"):
return True
if value in ("false", "False", "0"):
if value in ("false", "False", "0", "None"):
return False
return None

Expand Down Expand Up @@ -178,6 +183,14 @@ def _apply_union(self, args: Any, value: Any) -> Any:
return None
raise ValueError(f"Couldn't cast '{value}' to any of types: {args}")

def _apply_regex_pattern(self, values: Any) -> re.Pattern:
if not isinstance(values, str):
raise ValueError("Regex pattern should be string!")
return re.compile(values)

def _apply_enum(self, type_: Type[Enum], values: Any) -> Enum:
return type_(values)

def _is_terminate(self, type_: Any, args: tuple) -> bool:
return (
self._is_any(args)
Expand Down
26 changes: 26 additions & 0 deletions tests/test_type_converter/test_regex_pattern_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest
import re
from re import Pattern

from app_properties import properties


@pytest.fixture
def regex_class_fixt():
@properties(filename="types_cast.yml", root="regex")
class RegexClass:
some_pattern_var: Pattern

return RegexClass


def test_regex_pattern_field(regex_class_fixt):
assert regex_class_fixt.some_pattern_var == re.compile(r"\w+")


def test_regex_pattern_wrong_value():
with pytest.raises(ValueError):

@properties(filename="types_cast.yml", root="regex")
class WrongRegexClass:
wrong_pattern_var: Pattern
6 changes: 5 additions & 1 deletion tests/test_type_converter/types_cast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,8 @@ datetime:
enum:
simple_enum_var: GREEN
int_enum_var: 3
invalid_enum_var: INVALID
invalid_enum_var: INVALID

regex:
some_pattern_var: \w+
wrong_pattern_var: 10

0 comments on commit 2392238

Please sign in to comment.