attrs icon indicating copy to clipboard operation
attrs copied to clipboard

`attr.filters.exclude` or `include` not simultaneously usable with `validators.in_` set.

Open miki5799 opened this issue 1 year ago • 1 comments

When using one of the mentioned filter functions in attrs.as_dict or as_tuple on frozen nodes that have attributes with attrs.validators.in_ set as their validator, the following TypeError is thrown:

  File "<>/venv/lib/python3.11/site-packages/attr/filters.py", line 63, in exclude_
    or attribute in attrs
       ^^^^^^^^^^^^^^^^^^
  File "<>/venv/lib/python3.11/site-packages/attr/_funcs.py", line 57, in asdict
    if filter is not None and not filter(a, v):
                                  ^^^^^^^^^^^^
  File "<>/venv/lib/python3.11/site-packages/attr/_next_gen.py", line 211, in asdict
    return _asdict(
           ^^^^^^^^
  [...]
TypeError: unhashable type: 'set'

Trying to execute line 63, in exclude_ (top of traceback) resulted in the following error:

Traceback (most recent call last):
 [...]
  File "<attrs generated hash attr._make.Attribute>", line 2, in __hash__
    return hash((
           ^^^^^^
  File "<attrs generated hash attr.validators._InValidator>", line 2, in __hash__
    return hash((
           ^^^^^^
TypeError: unhashable type: 'set'

Therefore I suspect, that the issue lies in hashing of attrs.validators.in_.

miki5799 avatar Jun 08 '24 13:06 miki5799

Looking further into it, I noticed that this issue occurs if the options passed to to the in_ function are not of a hashable type (in my case list objects), what made the corresponding attribute unhashable.

Casting the options into a hashable type such as tuple or frozenset might resolve this issue.

miki5799 avatar Jun 08 '24 14:06 miki5799

For posterity, this is what breaks:

import attrs


@attrs.define
class C:
    x: int = attrs.field(validator=attrs.validators.in_({1, 2}))


i = C(2)

attrs.asdict(i, filter=attrs.filters.exclude(lambda val: True))

hynek avatar Aug 02 '24 07:08 hynek

I believe this is fixed in https://github.com/python-attrs/attrs/pull/1320

hynek avatar Aug 02 '24 08:08 hynek