Source: python-typing-inspect, python-marshmallow-dataclass
Control: found -1 python-typing-inspect/0.8.0-1
Control: found -1 python-marshmallow-dataclass/8.5.8-2
Severity: serious
Tags: sid bookworm
User: debian...@lists.debian.org
Usertags: breaks needs-update

Dear maintainer(s),

With a recent upload of python-typing-inspect the autopkgtest of python-marshmallow-dataclass fails in testing when that autopkgtest is run with the binary packages of python-typing-inspect from unstable. It passes when run with only packages from testing. In tabular form:

                             pass            fail
python-typing-inspect        from testing    0.8.0-1
python-marshmallow-dataclass from testing    8.5.8-2
all others                   from testing    from testing

I copied some of the output at the bottom of this report.

Currently this regression is blocking the migration of python-typing-inspect to testing [1]. Due to the nature of this issue, I filed this bug report against both packages. Can you please investigate the situation and reassign the bug to the right package?

More information about this bug and the reason for filing it can be found on
https://wiki.debian.org/ContinuousIntegration/RegressionEmailInformation

Paul

[1] https://qa.debian.org/excuses.php?package=python-typing-inspect

https://ci.debian.net/data/autopkgtest/testing/amd64/p/python-marshmallow-dataclass/25831906/log.gz

=================================== FAILURES =================================== ___________________ TestClassSchema.test_validator_stacking ____________________

class_or_instance = <function NewType.<locals>.new_type at 0x7f0b19be1990>

    def fields(class_or_instance):
        """Return a tuple describing the fields of this dataclass.
Accepts a dataclass or an instance of one. Tuple elements are of
        type Field.
        """
            # Might it be worth caching this, per class?
        try:
          fields = getattr(class_or_instance, _FIELDS)
E AttributeError: 'function' object has no attribute '__dataclass_fields__'

/usr/lib/python3.10/dataclasses.py:1197: AttributeError

During handling of the above exception, another exception occurred:

clazz = <function NewType.<locals>.new_type at 0x7f0b19be1990>
base_schema = None
clazz_frame = <frame at 0x55c027b54830, file '/tmp/autopkgtest-lxc.c9zyolii/downtmp/autopkgtest_tmp/tests/test_class_schema.py', line 319, code test_validator_stacking>

    @lru_cache(maxsize=MAX_CLASS_SCHEMA_CACHE_SIZE)
    def _internal_class_schema(
        clazz: type,
        base_schema: Optional[Type[marshmallow.Schema]] = None,
        clazz_frame: types.FrameType = None,
    ) -> Type[marshmallow.Schema]:
        _RECURSION_GUARD.seen_classes[clazz] = clazz.__name__
        try:
            # noinspection PyDataclass
          fields: Tuple[dataclasses.Field, ...] = dataclasses.fields(clazz)

/usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:370: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
class_or_instance = <function NewType.<locals>.new_type at 0x7f0b19be1990>

    def fields(class_or_instance):
        """Return a tuple describing the fields of this dataclass.
Accepts a dataclass or an instance of one. Tuple elements are of
        type Field.
        """
            # Might it be worth caching this, per class?
        try:
            fields = getattr(class_or_instance, _FIELDS)
        except AttributeError:
          raise TypeError('must be called with a dataclass type or instance')
E           TypeError: must be called with a dataclass type or instance

/usr/lib/python3.10/dataclasses.py:1199: TypeError

During handling of the above exception, another exception occurred:

clazz = <function NewType.<locals>.new_type at 0x7f0b19be1990>
base_schema = None
clazz_frame = <frame at 0x55c027b54830, file '/tmp/autopkgtest-lxc.c9zyolii/downtmp/autopkgtest_tmp/tests/test_class_schema.py', line 319, code test_validator_stacking>

    @lru_cache(maxsize=MAX_CLASS_SCHEMA_CACHE_SIZE)
    def _internal_class_schema(
        clazz: type,
        base_schema: Optional[Type[marshmallow.Schema]] = None,
        clazz_frame: types.FrameType = None,
    ) -> Type[marshmallow.Schema]:
        _RECURSION_GUARD.seen_classes[clazz] = clazz.__name__
        try:
            # noinspection PyDataclass
fields: Tuple[dataclasses.Field, ...] = dataclasses.fields(clazz)
        except TypeError:  # Not a dataclass
            try:
                warnings.warn(
                    "****** WARNING ****** "
f"marshmallow_dataclass was called on the class {clazz}, which is not a dataclass. " "It is going to try and convert the class into a dataclass, which may have " "undesirable side effects. To avoid this message, make sure all your classes and " "all the classes of their fields are either explicitly supported by " "marshmallow_dataclass, or define the schema explicitly using " "field(metadata=dict(marshmallow_field=...)). For more information, see "

"https://github.com/lovasoa/marshmallow_dataclass/issues/51 "
                    "****** WARNING ******"
                )
              created_dataclass: type = dataclasses.dataclass(clazz)

/usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:384: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <function NewType.<locals>.new_type at 0x7f0b19be1990>

def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
                  unsafe_hash=False, frozen=False, match_args=True,
                  kw_only=False, slots=False):
        """Returns the same class as was passed in, with dunder methods
        added based on the fields defined in the class.
            Examines PEP 526 __annotations__ to determine fields.
            If init is true, an __init__() method is added to the class. If
        repr is true, a __repr__() method is added. If order is true, rich
        comparison dunder methods are added. If unsafe_hash is true, a
        __hash__() method function is added. If frozen is true, fields may
        not be assigned to after instance creation. If match_args is true,
        the __match_args__ tuple is added. If kw_only is true, then by
        default all fields are keyword-only. If slots is true, an
        __slots__ attribute is added.
        """
            def wrap(cls):
            return _process_class(cls, init, repr, eq, order, unsafe_hash,
                                  frozen, match_args, kw_only, slots)
            # See if we're being called as @dataclass or @dataclass().
        if cls is None:
            # We're called with parens.
            return wrap
            # We're called as @dataclass without parens.
      return wrap(cls)

/usr/lib/python3.10/dataclasses.py:1185: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <function NewType.<locals>.new_type at 0x7f0b19be1990>

    def wrap(cls):
      return _process_class(cls, init, repr, eq, order, unsafe_hash,
                              frozen, match_args, kw_only, slots)

/usr/lib/python3.10/dataclasses.py:1176: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <function NewType.<locals>.new_type at 0x7f0b19be1990>, init = True
repr = True, eq = True, order = False, unsafe_hash = False, frozen = False
match_args = True, kw_only = False, slots = False

    def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
                       match_args, kw_only, slots):
        # Now that dicts retain insertion order, there's no reason to use
        # an ordered dict.  I am leveraging that ordering here, because
        # derived class fields overwrite base class fields, but the order
        # is defined by the base class, which is found first.
        fields = {}
            if cls.__module__ in sys.modules:
            globals = sys.modules[cls.__module__].__dict__
        else:
            # Theoretically this can happen if someone writes
            # a custom string to cls.__module__.  In which case
            # such dataclass won't be fully introspectable
            # (w.r.t. typing.get_type_hints) but will still function
            # correctly.
            globals = {}
            setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
                                               unsafe_hash, frozen))
            # Find our base classes in reverse MRO order, and exclude
        # ourselves.  In reversed order so that more derived classes
        # override earlier field definitions in base classes.  As long as
        # we're iterating over them, see if any are frozen.
        any_frozen_base = False
        has_dataclass_bases = False
      for b in cls.__mro__[-1:0:-1]:
E       AttributeError: 'function' object has no attribute '__mro__'

/usr/lib/python3.10/dataclasses.py:909: AttributeError

During handling of the above exception, another exception occurred:

self = <tests.test_class_schema.TestClassSchema testMethod=test_validator_stacking>

    def test_validator_stacking(self):
        # See: https://github.com/lovasoa/marshmallow_dataclass/issues/91
        class SimpleValidator(Validator):
# Marshmallow checks for valid validators at construction time only using `callable`
            def __call__(self):
                pass
            validator_a = SimpleValidator()
        validator_b = SimpleValidator()
        validator_c = SimpleValidator()
        validator_d = SimpleValidator()
            CustomTypeOneValidator = NewType(
            "CustomTypeOneValidator", str, validate=validator_a
        )
CustomTypeNoneValidator = NewType("CustomTypeNoneValidator", str, validate=None)
        CustomTypeMultiValidator = NewType(
"CustomTypeNoneValidator", str, validate=[validator_a, validator_b]
        )
            @dataclasses.dataclass
        class A:
            data: CustomTypeNoneValidator = dataclasses.field()
    >       schema_a = class_schema(A)()

tests/test_class_schema.py:319: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:356: in class_schema
    return _internal_class_schema(clazz, base_schema, clazz_frame)
/usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:402: in _internal_class_schema
    attributes.update(
/usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:405: in <genexpr>
    field_for_schema(
/usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:729: in field_for_schema
    or _internal_class_schema(typ, base_schema, typ_frame)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
clazz = <function NewType.<locals>.new_type at 0x7f0b19be1990>
base_schema = None
clazz_frame = <frame at 0x55c027b54830, file '/tmp/autopkgtest-lxc.c9zyolii/downtmp/autopkgtest_tmp/tests/test_class_schema.py', line 319, code test_validator_stacking>

    @lru_cache(maxsize=MAX_CLASS_SCHEMA_CACHE_SIZE)
    def _internal_class_schema(
        clazz: type,
        base_schema: Optional[Type[marshmallow.Schema]] = None,
        clazz_frame: types.FrameType = None,
    ) -> Type[marshmallow.Schema]:
        _RECURSION_GUARD.seen_classes[clazz] = clazz.__name__
        try:
            # noinspection PyDataclass
fields: Tuple[dataclasses.Field, ...] = dataclasses.fields(clazz)
        except TypeError:  # Not a dataclass
            try:
                warnings.warn(
                    "****** WARNING ****** "
f"marshmallow_dataclass was called on the class {clazz}, which is not a dataclass. " "It is going to try and convert the class into a dataclass, which may have " "undesirable side effects. To avoid this message, make sure all your classes and " "all the classes of their fields are either explicitly supported by " "marshmallow_dataclass, or define the schema explicitly using " "field(metadata=dict(marshmallow_field=...)). For more information, see "

"https://github.com/lovasoa/marshmallow_dataclass/issues/51 "
                    "****** WARNING ******"
                )
                created_dataclass: type = dataclasses.dataclass(clazz)
return _internal_class_schema(created_dataclass, base_schema, clazz_frame)
            except Exception:
              raise TypeError(
f"{getattr(clazz, '__name__', repr(clazz))} is not a dataclass and cannot be turned into one."
                )
E TypeError: CustomTypeNoneValidator is not a dataclass and cannot be turned into one.

/usr/lib/python3/dist-packages/marshmallow_dataclass/__init__.py:387: TypeError

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to