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
65 changes: 6 additions & 59 deletions doc/source/logwrap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,10 @@ API: Decorators: `LogWrap` class and `logwrap` function.
:rtype: typing.Union[typing.Callable, typing.Awaitable]


.. py:class:: BoundParameter(object)
.. py:class:: BoundParameter(inspect.Parameter)

Parameter-like object store BOUND with value parameter.
.. versionchanged:: 5.3.1 subclass inspect.Parameter

.. versionadded:: 3.3.0

Expand All @@ -127,77 +128,23 @@ API: Decorators: `LogWrap` class and `logwrap` function.
:type value: typing.Any
:raises ValueError: No default value and no value

.. py:attribute:: POSITIONAL_ONLY

``enum.IntEnum``
Parameter.POSITIONAL_ONLY

.. py:attribute:: POSITIONAL_OR_KEYWORD

``enum.IntEnum``
Parameter.POSITIONAL_OR_KEYWORD

.. py:attribute:: VAR_POSITIONAL

``enum.IntEnum``
Parameter.VAR_POSITIONAL

.. py:attribute:: KEYWORD_ONLY

``enum.IntEnum``
Parameter.KEYWORD_ONLY

.. py:attribute:: VAR_KEYWORD

``enum.IntEnum``
Parameter.VAR_KEYWORD

.. py:attribute:: empty

``typing.Type``
Parameter.empty

.. py:attribute:: parameter

Parameter object.

:rtype: inspect.Parameter

.. py:attribute:: name

Parameter name.

:rtype: typing.Union[None, str]

.. py:attribute:: default

Parameter default value.

:rtype: typing.Any

.. py:attribute:: annotation

Parameter annotation.

:rtype: typing.Union[Parameter.empty, str]

.. py:attribute:: kind

Parameter kind.

:rtype: enum.IntEnum
:rtype: BoundParameter

.. py:attribute:: value

Parameter value.

:rtype: typing.Any

.. py:method:: __hash__(self)
.. py:method:: __str__(self)

Block hashing.
String representation.

:raises TypeError: Not hashable.
:rtype: ``str``


.. py:function:: bind_args_kwargs(sig, *args, **kwargs)
Expand Down
50 changes: 9 additions & 41 deletions logwrap/log_wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import sys
import traceback
import typing
import warnings

import logwrap as core
from . import class_decorator
Expand All @@ -38,21 +39,14 @@
comment = "\n{spc:<{indent}}# {{kind!s}}:".format(spc="", indent=indent).format


class BoundParameter:
class BoundParameter(inspect.Parameter):
"""Parameter-like object store BOUND with value parameter.

.. versionadded:: 3.3.0
.. versionchanged:: 5.3.1 subclass inspect.Parameter
"""

__slots__ = ("_parameter", "_value")

POSITIONAL_ONLY = inspect.Parameter.POSITIONAL_ONLY
POSITIONAL_OR_KEYWORD = inspect.Parameter.POSITIONAL_OR_KEYWORD
VAR_POSITIONAL = inspect.Parameter.VAR_POSITIONAL
KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY
VAR_KEYWORD = inspect.Parameter.VAR_KEYWORD

empty = inspect.Parameter.empty
__slots__ = ("_value",)

def __init__(self, parameter: inspect.Parameter, value: typing.Any = inspect.Parameter.empty) -> None:
"""Parameter-like object store BOUND with value parameter.
Expand All @@ -63,7 +57,9 @@ def __init__(self, parameter: inspect.Parameter, value: typing.Any = inspect.Par
:type value: typing.Any
:raises ValueError: No default value and no value
"""
self._parameter = parameter
super(BoundParameter, self).__init__(
name=parameter.name, kind=parameter.kind, default=parameter.default, annotation=parameter.annotation
)

if value is self.empty:
if parameter.default is self.empty and parameter.kind not in (self.VAR_POSITIONAL, self.VAR_KEYWORD):
Expand All @@ -75,42 +71,14 @@ def __init__(self, parameter: inspect.Parameter, value: typing.Any = inspect.Par
@property
def parameter(self) -> inspect.Parameter:
"""Parameter object."""
return self._parameter

@property
def name(self) -> typing.Union[None, str]:
"""Parameter name."""
return self.parameter.name

@property
def default(self) -> typing.Any:
"""Parameter default value."""
return self.parameter.default

@property
def annotation(self) -> typing.Union[inspect.Parameter.empty, str]:
"""Parameter annotation."""
return self.parameter.annotation

@property
def kind(self) -> int:
"""Parameter kind."""
return self.parameter.kind # type: ignore
warnings.warn("BoundParameter is subclass of `inspect.Parameter`", DeprecationWarning)
return self

@property
def value(self) -> typing.Any:
"""Parameter value."""
return self._value

# noinspection PyTypeChecker
def __hash__(self) -> int: # pragma: no cover
"""Block hashing.

:raises TypeError: Not hashable.
"""
msg = "unhashable type: '{0}'".format(self.__class__.__name__)
raise TypeError(msg)

def __str__(self) -> str:
"""Debug purposes."""
# POSITIONAL_ONLY is only in precompiled functions
Expand Down
57 changes: 15 additions & 42 deletions logwrap/log_wrap.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import logging
import sys
import traceback
import typing
import warnings

from logwrap cimport repr_utils
from logwrap cimport class_decorator
Expand All @@ -36,18 +37,13 @@ fmt = "\n{spc:<{indent}}{{key!r}}={{val}},{{annotation}}".format(spc="", indent=
comment = "\n{spc:<{indent}}# {{kind!s}}:".format(spc="", indent=indent).format


class BoundParameter:
"""Parameter-like object store BOUND with value parameter."""
class BoundParameter(inspect.Parameter):
"""Parameter-like object store BOUND with value parameter.

__slots__ = ("_parameter", "_value")

POSITIONAL_ONLY = inspect.Parameter.POSITIONAL_ONLY
POSITIONAL_OR_KEYWORD = inspect.Parameter.POSITIONAL_OR_KEYWORD
VAR_POSITIONAL = inspect.Parameter.VAR_POSITIONAL
KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY
VAR_KEYWORD = inspect.Parameter.VAR_KEYWORD
.. versionchanged:: 5.3.1 subclass inspect.Parameter
"""

empty = inspect.Parameter.empty
__slots__ = ("_value",)

def __init__(self, parameter: inspect.Parameter, value: typing.Any = inspect.Parameter.empty) -> None:
"""Parameter-like object store BOUND with value parameter.
Expand All @@ -58,7 +54,12 @@ class BoundParameter:
:type value: typing.Any
:raises ValueError: No default value and no value
"""
self._parameter = parameter
super(BoundParameter, self).__init__(
name=parameter.name,
kind=parameter.kind,
default=parameter.default,
annotation=parameter.annotation
)

if value is self.empty:
if parameter.default is self.empty and parameter.kind not in (self.VAR_POSITIONAL, self.VAR_KEYWORD):
Expand All @@ -70,42 +71,14 @@ class BoundParameter:
@property
def parameter(self) -> inspect.Parameter:
"""Parameter object."""
return self._parameter

@property
def name(self) -> typing.Union[None, str]:
"""Parameter name."""
return self.parameter.name

@property
def default(self) -> typing.Any:
"""Parameter default value."""
return self.parameter.default

@property
def annotation(self) -> typing.Union[inspect.Parameter.empty, str]:
"""Parameter annotation."""
return self.parameter.annotation

@property
def kind(self) -> int:
"""Parameter kind."""
return self.parameter.kind # type: ignore
warnings.warn("BoundParameter is subclass of `inspect.Parameter`", DeprecationWarning)
return self

@property
def value(self) -> typing.Any:
"""Parameter value."""
return self._value

# noinspection PyTypeChecker
def __hash__(self) -> int:
"""Block hashing.

:raises TypeError: Not hashable.
"""
cdef str msg = "unhashable type: '{0}'".format(self.__class__.__name__)
raise TypeError(msg)

def __str__(self) -> str:
"""Debug purposes."""
cdef str as_str
Expand Down Expand Up @@ -328,7 +301,7 @@ cdef class LogWrap(class_decorator.BaseDecorator):
str annotation

last_kind = None
for param in bind_args_kwargs(sig, *args, **kwargs):
for param in bind_args_kwargs(sig, *args, **kwargs): # type: BoundParameter
if param.name in self.blacklisted_names:
continue

Expand Down
1 change: 1 addition & 0 deletions logwrap/repr_utils.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ cdef:
str _repr_callable(self, src: typing.Union[types.FunctionType, types.MethodType], unsigned int indent=?)
str _repr_simple(self, src: typing.Any, unsigned int indent=?, bint no_indent_start=?)
str _repr_iterable_item(self, bint nl, str obj_type, str prefix, unsigned int indent, str result, str suffix)
str _repr_iterable_items(self, src: typing.Iterable, unsigned int indent=?)

cpdef str process_element(self, src: typing.Any, unsigned int indent=?, bint no_indent_start=?)

Expand Down
8 changes: 5 additions & 3 deletions logwrap/repr_utils.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ cdef class PrettyFormat:
"""
raise NotImplementedError()

def _repr_iterable_items(self, src: typing.Iterable, unsigned int indent=0) -> typing.Iterator[str]:
cdef str _repr_iterable_items(self, src: typing.Iterable, unsigned int indent=0):
"""Repr iterable items (not designed for dicts).

:param src: object to process
Expand All @@ -202,8 +202,10 @@ cdef class PrettyFormat:
:return: repr of element in iterable item
:rtype: typing.Iterator[str]
"""
cdef str result = ""
for elem in src:
yield "\n" + self.process_element(src=elem, indent=self.next_indent(indent)) + ","
result += "\n" + self.process_element(src=elem, indent=self.next_indent(indent)) + ","
return result

cpdef str process_element(self, src: typing.Any, unsigned int indent=0, bint no_indent_start=False):
"""Make human readable representation of object.
Expand Down Expand Up @@ -242,7 +244,7 @@ cdef class PrettyFormat:
prefix, suffix = "(", ")"
else:
prefix, suffix = "{", "}"
result = "".join(self._repr_iterable_items(src=src, indent=indent))
result = self._repr_iterable_items(src=src, indent=indent)
return self._repr_iterable_item(
nl=no_indent_start,
obj_type=src.__class__.__name__,
Expand Down