python / python/mypy

Supporting attrs extensions with different default arguments for decorators.

Open
#12,774 4 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

false-positive feature topic-attrs
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

attrs' decorators can (and sometimes should) be wrapped, to create custom decorators. Using a "fake plugin", the custom decorators can be added to the maker lists and thus receive the special attrs treatment from mypy.
However, currently, mypy's attrs plugin has the default values of the arguments of attrs' decorators hardcoded. This means that it does not detect when the custom decorators define different default values, and thus raises (false positive) errors on some cases.

Here is an example for such a case:

import attr
from typing import Any

def my_attr_s(cls, kw_only: bool = True) -> Any:  # Added to attr_class_makers using "fake plugin".
    return attr.s(kw_only=kw_only)(cls)

def my_attr_ib(**kwargs) -> Any:  # Added to attr_attrib_makers using "fake plugin".
    return attr.ib(**kwargs)

@my_attr_s
class A:
    optional: str = my_attr_ib(default="This attrib is not required now.")

@my_attr_s
class B(A):
    required: str = my_attr_ib()

When type-checking this file, mypy gives the following error:

16: error: Non-default attributes not allowed after default attributes.

This error should actually not be emitted, because as opposed to what would happen if we we decorate A and B with attr.s, there is no problem here, because here we have kw_only set to True (by default, and nothing else was passed), so the order of the attributes is actually valid.

If mypy would take the decorator's arguments' default values for arguments that were not passed, it could avoid such false positives.
I would like to submit a PR which fixes this.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied example with mypy's attrs plugin and the fake-plugin maker lists, especially attr_class_makers and attr_attrib_makers. Trace how omitted decorator arguments are handled. Done means custom decorator defaults are respected and the false-positive non-default attribute error is no longer emitted.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.