Skip to content

Commit

Permalink
refactor logger declaration in protected, make still public API
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
  • Loading branch information
jkowalleck committed Sep 27, 2023
1 parent e3c8c5f commit 190c775
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 37 deletions.
66 changes: 34 additions & 32 deletions serializable/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,16 @@
else:
from typing_extensions import Protocol # type: ignore

from ._logging import _LOGGER, _warning_kwargs
from .formatters import BaseNameFormatter, CurrentFormatter
from .helpers import BaseHelper
from .logging import LOGGER, _warning_kwargs

# !! version is managed by semantic_release
# do not use typing here, or else `semantic_release` might have issues finding the variable
__version__ = '0.12.0'

# make logger publicly available, as stable API
LOGGER = _LOGGER

_F = TypeVar("_F", bound=Callable[..., Any])
_T = TypeVar('_T', bound='_Klass')
Expand Down Expand Up @@ -225,7 +227,7 @@ def _as_json(self: _T, view_: Optional[Type[Any]] = None) -> str:
Internal function that is injected into Classes that are annotated for serialization and deserialization by
``serializable``.
"""
LOGGER.debug(f'Dumping {self} to JSON with view: {view_}...')
_LOGGER.debug(f'Dumping {self} to JSON with view: {view_}...')
return json.dumps(self, cls=_SerializableJsonEncoder, view_=view_)


Expand All @@ -234,13 +236,13 @@ def _from_json(cls: Type[_T], data: Dict[str, Any]) -> object:
Internal function that is injected into Classes that are annotated for serialization and deserialization by
``serializable``.
"""
LOGGER.debug(f'Rendering JSON to {cls}...')
_LOGGER.debug(f'Rendering JSON to {cls}...')
klass_qualified_name = f'{cls.__module__}.{cls.__qualname__}'
klass = ObjectMetadataLibrary.klass_mappings.get(klass_qualified_name, None)
klass_properties = ObjectMetadataLibrary.klass_property_mappings.get(klass_qualified_name, {})

if klass is None:
LOGGER.warning(
_LOGGER.warning(
f'{klass_qualified_name} is not a known serializable class',
)
return None
Expand All @@ -255,7 +257,7 @@ def _from_json(cls: Type[_T], data: Dict[str, Any]) -> object:
for k, v in data.items():
decoded_k = CurrentFormatter.formatter.decode(property_name=k)
if decoded_k in klass.ignore_during_deserialization:
LOGGER.debug(f'Ignoring {k} when deserializing {cls.__module__}.{cls.__qualname__}')
_LOGGER.debug(f'Ignoring {k} when deserializing {cls.__module__}.{cls.__qualname__}')
del _data[k]
continue

Expand All @@ -268,7 +270,7 @@ def _from_json(cls: Type[_T], data: Dict[str, Any]) -> object:
new_key = decoded_k

if new_key is None:
LOGGER.error(
_LOGGER.error(
f'Unexpected key {k}/{decoded_k} in data being serialized to {cls.__module__}.{cls.__qualname__}'
)
raise ValueError(
Expand Down Expand Up @@ -306,22 +308,22 @@ def _from_json(cls: Type[_T], data: Dict[str, Any]) -> object:
else:
_data[k] = prop_info.concrete_type(v)
except AttributeError as e:
LOGGER.error(f'There was an AttributeError deserializing JSON to {cls}.{os.linesep}'
f'The Property is: {prop_info}{os.linesep}'
f'The Value was: {v}{os.linesep}'
f'Exception: {e}{os.linesep}')
_LOGGER.error(f'There was an AttributeError deserializing JSON to {cls}.{os.linesep}'
f'The Property is: {prop_info}{os.linesep}'
f'The Value was: {v}{os.linesep}'
f'Exception: {e}{os.linesep}')
raise AttributeError(
f'There was an AttributeError deserializing JSON to {cls} the Property {prop_info}: {e}'
)

LOGGER.debug(f'Creating {cls} from {_data}')
_LOGGER.debug(f'Creating {cls} from {_data}')

return cls(**_data)


def _as_xml(self: _T, view_: Optional[Type[_T]] = None, as_string: bool = True, element_name: Optional[str] = None,
xmlns: Optional[str] = None) -> Union[Element, str]:
LOGGER.debug(f'Dumping {self} to XML with view {view_}...')
_LOGGER.debug(f'Dumping {self} to XML with view {view_}...')

this_e_attributes = {}
klass_qualified_name = f'{self.__module__}.{self.__class__.__qualname__}'
Expand Down Expand Up @@ -445,10 +447,10 @@ def _as_xml(self: _T, view_: Optional[Type[_T]] = None, as_string: bool = True,

def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],
default_namespace: Optional[str] = None) -> object:
LOGGER.debug(f'Rendering XML from {type(data)} to {cls}...')
_LOGGER.debug(f'Rendering XML from {type(data)} to {cls}...')
klass = ObjectMetadataLibrary.klass_mappings.get(f'{cls.__module__}.{cls.__qualname__}', None)
if klass is None:
LOGGER.warning(
_LOGGER.warning(
f'{cls.__module__}.{cls.__qualname__} is not a known serializable class',
**_warning_kwargs) # type:ignore[arg-type]
return None
Expand All @@ -473,7 +475,7 @@ def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],
for k, v in data.attrib.items():
decoded_k = CurrentFormatter.formatter.decode(property_name=k)
if decoded_k in klass.ignore_during_deserialization:
LOGGER.debug(f'Ignoring {decoded_k} when deserializing {cls.__module__}.{cls.__qualname__}')
_LOGGER.debug(f'Ignoring {decoded_k} when deserializing {cls.__module__}.{cls.__qualname__}')
continue

if decoded_k not in klass_properties:
Expand Down Expand Up @@ -507,7 +509,7 @@ def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],

decoded_k = CurrentFormatter.formatter.decode(property_name=child_e_tag_name)
if decoded_k in klass.ignore_during_deserialization:
LOGGER.debug(f'Ignoring {decoded_k} when deserializing {cls.__module__}.{cls.__qualname__}')
_LOGGER.debug(f'Ignoring {decoded_k} when deserializing {cls.__module__}.{cls.__qualname__}')
continue

if decoded_k not in klass_properties:
Expand All @@ -531,7 +533,7 @@ def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],

try:

LOGGER.debug(f'Handling {prop_info}')
_LOGGER.debug(f'Handling {prop_info}')

if prop_info.is_array and prop_info.xml_array_config:
array_type, nested_name = prop_info.xml_array_config
Expand Down Expand Up @@ -580,15 +582,15 @@ def _from_xml(cls: Type[_T], data: Union[TextIOWrapper, Element],
else:
_data[decoded_k] = prop_info.concrete_type(child_e.text)
except AttributeError as e:
LOGGER.error(f'There was an AttributeError deserializing JSON to {cls}.{os.linesep}'
f'The Property is: {prop_info}{os.linesep}'
f'The Value was: {v}{os.linesep}'
f'Exception: {e}{os.linesep}')
_LOGGER.error(f'There was an AttributeError deserializing JSON to {cls}.{os.linesep}'
f'The Property is: {prop_info}{os.linesep}'
f'The Value was: {v}{os.linesep}'
f'Exception: {e}{os.linesep}')
raise AttributeError(
f'There was an AttributeError deserializing XML to {cls} the Property {prop_info}: {e}'
)

LOGGER.debug(f'Creating {cls} from {_data}')
_LOGGER.debug(f'Creating {cls} from {_data}')

if len(_data) == 0:
return None
Expand Down Expand Up @@ -972,7 +974,7 @@ def register_klass(cls, klass: _T, custom_name: Optional[str],

qualified_class_name = f'{klass.__module__}.{klass.__qualname__}'
cls.klass_property_mappings.update({qualified_class_name: {}})
LOGGER.debug(f'Registering Class {qualified_class_name} with custom name {custom_name}')
_LOGGER.debug(f'Registering Class {qualified_class_name} with custom name {custom_name}')
for name, o in inspect.getmembers(klass, ObjectMetadataLibrary.is_property):
qualified_property_name = f'{qualified_class_name}.{name}'
prop_arg_specs = inspect.getfullargspec(o.fget)
Expand Down Expand Up @@ -1129,7 +1131,7 @@ def type_mapping(type_: _T) -> Callable[[_F], _F]:
"""

def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with custom type: {type_}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with custom type: {type_}')
ObjectMetadataLibrary.register_property_type_mapping(
qual_name=f'{f.__module__}.{f.__qualname__}', mapped_type=type_
)
Expand All @@ -1145,7 +1147,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def include_none(view_: Optional[Type[_T]] = None, none_value: Optional[Any] = None) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} to include None for view: {view_}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} to include None for view: {view_}')
ObjectMetadataLibrary.register_property_include_none(
qual_name=f'{f.__module__}.{f.__qualname__}', view_=view_, none_value=none_value
)
Expand All @@ -1161,7 +1163,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def json_name(name: str) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with JSON name: {name}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with JSON name: {name}')
ObjectMetadataLibrary.register_custom_json_property_name(
qual_name=f'{f.__module__}.{f.__qualname__}', json_property_name=name
)
Expand All @@ -1177,7 +1179,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def string_format(format_: str) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with String Format: {format_}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with String Format: {format_}')
ObjectMetadataLibrary.register_custom_string_format(
qual_name=f'{f.__module__}.{f.__qualname__}', string_format=format_
)
Expand All @@ -1193,7 +1195,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def view(view_: ViewType) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with View: {view_}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with View: {view_}')
ObjectMetadataLibrary.register_property_view(
qual_name=f'{f.__module__}.{f.__qualname__}', view_=view_
)
Expand All @@ -1209,7 +1211,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def xml_attribute() -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} as XML attribute')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} as XML attribute')
ObjectMetadataLibrary.register_xml_property_attribute(qual_name=f'{f.__module__}.{f.__qualname__}')

@functools.wraps(f)
Expand All @@ -1223,7 +1225,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def xml_array(array_type: XmlArraySerializationType, child_name: str) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} as XML Array: {array_type}:{child_name}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} as XML Array: {array_type}:{child_name}')
ObjectMetadataLibrary.register_xml_property_array_config(
qual_name=f'{f.__module__}.{f.__qualname__}', array_type=array_type, child_name=child_name
)
Expand All @@ -1239,7 +1241,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def xml_name(name: str) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with XML name: {name}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with XML name: {name}')
ObjectMetadataLibrary.register_custom_xml_property_name(
qual_name=f'{f.__module__}.{f.__qualname__}', xml_property_name=name
)
Expand All @@ -1255,7 +1257,7 @@ def inner(*args: Any, **kwargs: Any) -> Any:

def xml_sequence(sequence: int) -> Callable[[_F], _F]:
def outer(f: _F) -> _F:
LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with XML sequence: {sequence}')
_LOGGER.debug(f'Registering {f.__module__}.{f.__qualname__} with XML sequence: {sequence}')
ObjectMetadataLibrary.register_xml_property_sequence(
qual_name=f'{f.__module__}.{f.__qualname__}', sequence=sequence
)
Expand Down
4 changes: 2 additions & 2 deletions serializable/logging.py → serializable/_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import logging
from sys import version_info

LOGGER = logging.getLogger(f'{__name__}.LOGGER')
LOGGER.setLevel(logging.DEBUG)
_LOGGER = logging.getLogger(f'{__name__}.LOGGER')
_LOGGER.setLevel(logging.DEBUG)

# logger.warning() got additional kwarg since py38
_warning_kwargs = {'stacklevel': 2} if version_info >= (3, 8) else {}
6 changes: 3 additions & 3 deletions serializable/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from datetime import date, datetime
from typing import Any

from .logging import LOGGER, _warning_kwargs
from ._logging import _LOGGER, _warning_kwargs


class BaseHelper(ABC):
Expand Down Expand Up @@ -76,12 +76,12 @@ def deserialize(cls, o: object) -> date:

if str(o).endswith('Z'):
o = str(o)[:-1]
LOGGER.warning(
_LOGGER.warning(
'Potential data loss will occur: dates with timezones not supported in Python',
**_warning_kwargs) # type:ignore[arg-type]
if '+' in str(o):
o = str(o)[:str(o).index('+')]
LOGGER.warning(
_LOGGER.warning(
'Potential data loss will occur: dates with timezones not supported in Python',
**_warning_kwargs) # type:ignore[arg-type]
return date.fromisoformat(str(o))
Expand Down

0 comments on commit 190c775

Please sign in to comment.