diff --git a/pyproject.toml b/pyproject.toml index f497e26..3be0f2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "megasniff" -version = "0.2.4" +version = "0.2.4.post1" description = "Library for in-time codegened type validation" authors = [ { name = "nikto_b", email = "niktob560@yandex.ru" } diff --git a/src/megasniff/__main__.py b/src/megasniff/__main__.py index 46601ca..a43a2b6 100644 --- a/src/megasniff/__main__.py +++ b/src/megasniff/__main__.py @@ -81,10 +81,11 @@ class ZSchema: def main_deflator(): deflator = SchemaDeflatorGenerator(store_sources=True, explicit_casts=True, strict_mode=True) - fn = deflator.schema_to_deflator(DSchema) - print(getattr(fn, '__megasniff_sources__', '## No data')) + fn = deflator.schema_to_deflator(DSchema | int) + # ret = fn(ZSchema(ZSchema(ZSchema(None, 42), 42), ZSchema(None, 42))) - ret = fn(DSchema({'a': 34}, {}, ASchema(1, 'a', None), ESchema([[['a'], ['b']]], ['b']))) + ret = fn(DSchema({'a': 34}, {}, ASchema(1, 'a', None), ESchema([[['a'], ['b']]], 'b'))) + ret = fn(42) # assert ret['a'] == 1 # assert ret['b'] == 1.1 # assert ret['c'] == 'a' diff --git a/src/megasniff/deflator.py b/src/megasniff/deflator.py index b8ee8f3..6743039 100644 --- a/src/megasniff/deflator.py +++ b/src/megasniff/deflator.py @@ -99,7 +99,14 @@ def _flatten_type(t: type | TypeAliasType) -> tuple[type, Optional[str]]: def _schema_to_deflator_func(t: type | TypeAliasType) -> str: t, _ = _flatten_type(t) - return 'deflate_' + typename(t).replace('.', '_') + ret = 'deflate_' + typename(t).replace('.', '_') + ret = ret.replace(' | ', '__OR__') + ret = ret.replace('<', '') + ret = ret.replace('>', '') + ret = ret.replace(' ', '__') + ret = ret.replace("'", '') + ret = ret.replace('.', '_') + return ret def _fallback_unwrapper(obj: Any) -> JsonObject: @@ -152,7 +159,7 @@ class SchemaDeflatorGenerator: self.object_template = self.templateEnv.get_template(object_template_filename) def schema_to_deflator(self, - schema: type, + schema: type | UnionType, strict_mode_override: Optional[bool] = None, explicit_casts_override: Optional[bool] = None, ) -> Callable[[Any], dict[str, Any]]: @@ -163,13 +170,15 @@ class SchemaDeflatorGenerator: imports = ('from typing import Any\n' 'from megasniff.exceptions import MissingFieldException, FieldValidationException\n') txt = imports + '\n' + txt + print(txt) exec(txt, namespace) fn = namespace[_schema_to_deflator_func(schema)] if self._store_sources: setattr(fn, '__megasniff_sources__', txt) return fn - def schema_to_unwrapper(self, schema: type | TypeAliasType, *, _visited_types: Optional[list[type]] = None): + def schema_to_unwrapper(self, schema: type | UnionType | TypeAliasType, *, + _visited_types: Optional[list[type]] = None): if _visited_types is None: _visited_types = [] else: @@ -249,12 +258,11 @@ class SchemaDeflatorGenerator: return ret_unw, field_rename, set(_visited_types) | ongoing_types, recurcive_types def _schema_to_deflator(self, - schema: type | Sequence[TupleSchemaItem | tuple[str, type]] | OrderedDict[str, type], + schema: type | UnionType, strict_mode_override: Optional[bool] = None, explicit_casts_override: Optional[bool] = None, into_type_override: Optional[type | TypeAliasType] = None, *, - _funcname='deflate', _namespace=None, ) -> tuple[str, dict]: if strict_mode_override is not None: diff --git a/src/megasniff/utils.py b/src/megasniff/utils.py index a6c00c2..089ce0d 100644 --- a/src/megasniff/utils.py +++ b/src/megasniff/utils.py @@ -68,9 +68,18 @@ def is_builtin_type(tp: type) -> bool: def typename(tp: type) -> str: + ret = '' if get_origin(tp) is None and hasattr(tp, '__name__'): - return tp.__name__ - return str(tp) + ret = tp.__name__ + ret = str(tp) + + ret = ret.replace(' | ', '__OR__') + ret = ret.replace('<', '') + ret = ret.replace('>', '') + ret = ret.replace(' ', '__') + ret = ret.replace("'", '') + ret = ret.replace('.', '_') + return ret def is_class_definition(obj): @@ -78,4 +87,11 @@ def is_class_definition(obj): def hashname(obj) -> str: - return '_' + str(hash(obj)).replace('-', '_') + ret = '_' + str(hash(obj)).replace('-', '_') + ret = ret.replace(' | ', '__OR__') + ret = ret.replace('<', '') + ret = ret.replace('>', '') + ret = ret.replace(' ', '__') + ret = ret.replace("'", '') + ret = ret.replace('.', '_') + return ret