Pylance-release: Pylance does not recognize constructor params from attrs

Created on 10 Aug 2020  路  15Comments  路  Source: microsoft/pylance-release

Environment data

  • Language Server version: v2020.8.0
  • OS and version: macOs Mojave 10.14.6
  • Python version (& distribution if applicable, e.g. Anaconda): Python 3.6.8, pipenv
  • VSCode version: 1.47.3

Expected behaviour

Type checking should recognize attributes created by attrs library (PyCharm does).

Actual behaviour

Screen Shot 2020-08-10 at 2 12 47 PM

Code Snippet / Additional information

import attr
@attr.s
class Foo:
    bar: str = attr.ib()

Foo("aa")
enhancement needs decision

Most helpful comment

Hi, I鈥檓 the original author and maintainer of attrs. Since pylance鈥檚 support for attrs is existential for it in the long term, I鈥檇 be happy to cooperate with you however I can.

Steve Dower indicated that it would help if there鈥檇 be a fixed spec, but before I do anything I鈥檇 like to hear it from you directly, what _you_ would consider helpful.

Feel free to contact me privately.

P.S. I positively hate tooting my own horn, but attrs had 50,000,000 downloads in the past 30 days so I think it鈥檚 fair to say that support for it would be also beneficial for pylance/VS Code.

All 15 comments

The attr library introduces some non-standard Python behaviors that can't be described by the Python type language. The case you mentioned above falls into this category.

If you're using attr mainly to describe data classes like in your example above, I recommend switching to the dataclass support that was introduced in Python 3.8. Pylance has full support for dataclass.

Unfortunately we are stuck with 3.6 for at least some time, so no dataclasses. Also, attrs does not seem to go anywhere: https://www.attrs.org/en/stable/why.html#data-classes, so it would be nice to see pylance (or vscode python in general) support it.

I second the request. dataclasses are great for many use-cases, but attrs has multiple features that are not available in dataclasses (e.g. regarding inheritance, default-argument order (e.g. using keyword-only constructers)). mypy has a plugin for attrs. I don't know anything about the details, but looking at #290 it seems like pyright/pylance might be able to use this.

PS @mmiicchh: If you want to use dataclasses, there's a backport for Python 3.6: https://pypi.org/project/dataclasses

Another bump for supporting attrs.
The relationship of attrs and dataclasses is like that simplejson serves as a more feature-rich 3rd-party extension followed by the stdlib json.

This has been really painful. Pretty much anytime I construct an attrs class I have to #type: ignore it

Several major libraries, including aiohttp use attrs, and pep-557 even suggests using attrs for more complicated use-cases (dataclasses as a module exists because attrs didn't want to be locked in the standard library's release cycle)

Just ran into this as well, which is scuppering my dream of a properly type checked 2.7/3.7+ compatible codebase. (2.7 can't be dropped due to having support older Maya versions).

Since dataclasses and attrs are so similar (dataclasses basically being a strict subset), adding attrs support should be fairly straightforward in a technical sense, no? So I'm guessing the problem is a matter of process, since attrs is "just" a third-party library.

Also, dataclasses are not the way forward. It's basically for use in the standard library or if you don't have access to pip/third party packages. Most codebases would be better served by attrs, and that's not going to change.

Adding my "please". Also out of courtesy could you write the dev of attrs and let him know pylance has slotted is package for death =). I mean is it possible to write plugins for pylance that will add attrs support? Autocomplete is basically the only reason I use an IDE it is a feature that cannot be "sort of there if I don't do X".

Every few months, I try to convert to vcode and every few months. I think this is much better! and then something like this happens and I think "whelp back to pycharm".

Pylance/pyright don't have a plugin system and can't reuse plugins from mypy (as they are heavily tied with mypy's own analysis which works very, very differently to ours).

We've talked about plugins, but most typing community effort has been put into expanding typing itself to cover more ground without needing plugins (like new variadic generics, ParamSpec, better syntax, etc). I'd think we'd want to ensure that any plugin system we come up with is usable cross-type-checker (otherwise everyone will have to write their plugins over and over again).

Just to address:

Since dataclasses and attrs are so similar (dataclasses basically being a strict subset), adding attrs support should be fairly straightforward in a technical sense, no? So I'm guessing the problem is a matter of process, since attrs is "just" a third-party library.

It's not trivial _because_ it's a third party library. Dataclasses are defined in PEPs, which have specific descriptions, release versions, etc, which make them possible to implement directly and know exactly when to apply custom behaviors. A third party library is not tied to any Python release schedule, is not beholden to formal definition of behaviors, etc. There's caveats that come with having an analysis effectively reimplement the runtime behavior of a third party library, where the library may change over time, users can run older versions of it, etc. This is a motivating factor for plugins shipped with libraries themselves (as they can describe themselves at a specific revision), but that's nontrivial too.

We haven't closed this issue. This is an enhancement that would of course provide benefit, it's just not as simple as just extending dataclass support and we need to devise a real plan to get there.

Big plus one from me on the feature, and also a big plus one on @jakebailey's explanation that it would in no way be simple. Features that are simple to imagine are not necessarily simple to implement, and we should all respect the developer time it would take to do this correctly.

Here's a partial solution that may help out some of you who don't have the choice of switching from attrs to dataclass. The idea is to use the stdlib @dataclasses.dataclass decorator for type checking purposes but @attr.s decorator at runtime. Since the two are so close in functionality, it may be sufficient for many use cases. Similar aliasing can be used for dataclasses.field.

from typing import TYPE_CHECKING
import attr

if TYPE_CHECKING:
    import dataclasses
    attr_s = dataclasses.dataclass
    attr_f = dataclasses.field
else:
    attr_s = attr.s
    attr_f = attr.field

@attr_s(eq=True, order=True, frozen=True)
class MyClass:
    count: int = attr_f(default=3)
    name: str = attr_f(default="hi")

Screen Shot 2021-03-27 at 6 14 34 PM

Hi, I鈥檓 the original author and maintainer of attrs. Since pylance鈥檚 support for attrs is existential for it in the long term, I鈥檇 be happy to cooperate with you however I can.

Steve Dower indicated that it would help if there鈥檇 be a fixed spec, but before I do anything I鈥檇 like to hear it from you directly, what _you_ would consider helpful.

Feel free to contact me privately.

P.S. I positively hate tooting my own horn, but attrs had 50,000,000 downloads in the past 30 days so I think it鈥檚 fair to say that support for it would be also beneficial for pylance/VS Code.

@hynek, thanks for reaching out. Your timing is good. We've been discussing some ideas for how to support attrs and similar libraries that have "dataclass-like" semantics. I was planning to reach out to you to get your input on some of the ideas we were exploring and see if you have any alternative suggestions. I'll follow up with you privately within the next several days.

We have been exploring ways to provide better support for attrs and other libraries that support semantics similar to dataclass. Pylance version 2021.4.2 (released earlier today) contains a proposed solution that is documented in this spec. If you want to try it, I've included instructions on how to modify your local copy of attrs (or pydantic) source code. We welcome early feedback.

I've started a discussion in the pyright repo. Please post questions, comments, or feedback there.

Was this page helpful?
0 / 5 - 0 ratings