Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instance of 'Field' has no 'append' member #4899

Closed
yellowhat opened this issue Aug 23, 2021 · 19 comments · Fixed by pylint-dev/astroid#1144 or pylint-dev/astroid#1178
Closed

Instance of 'Field' has no 'append' member #4899

yellowhat opened this issue Aug 23, 2021 · 19 comments · Fixed by pylint-dev/astroid#1144 or pylint-dev/astroid#1178
Assignees
Labels
Bug 🪲 False Positive 🦟 A message is emitted but nothing is wrong with the code Needs astroid update Needs an astroid update (probably a release too) before being mergable
Milestone

Comments

@yellowhat
Copy link

yellowhat commented Aug 23, 2021

Bug description

Hi,
I have the following code:

from dataclasses import field
from typing import List
from pydantic.dataclasses import dataclass

@dataclass
class Case:
    """Case class (group Item)"""

    name: str
    irr: float = 0
    items: List[Item] = field(default_factory=lambda: [])

    def add_item(self, item: Item) -> None:
        """Add an item to the item list."""

        self.items.append(item)

    def find_item(self, description: str) -> Item:
        """Find an item by description"""

        return next((item for item in self.items if item.description == description), None)

With version 2.10.2, pylint returns:

E1101: Instance of 'Field' has no 'append' member (no-member)

Is this related to pylint-dev/astroid#1126?

Thanks

Configuration

No response

Command used

pylint --verbose --disable=W0123 --max-locals=20 --extension-pkg-whitelist="pydantic" --max-line-length=480 **/*.py

Pylint output

************* Module tco.classes
tco/classes.py:240:8: E1101: Instance of 'Field' has no 'append' member (no-member)
tco/classes.py:245:38: E1133: Non-iterable value self.items is used in an iterating context (not-an-iterable)

Expected behavior

No errors

Pylint version

astroid-2.7.2 iniconfig-1.1.1 isort-5.9.3 lazy-object-proxy-1.6.0 platformdirs-2.2.0 pluggy-0.13.1 py-1.10.0 pylint-2.10.2 pytest-6.2.4 toml-0.10.2 wrapt-1.12.1

OS / Environment

No response

Additional dependencies

No response

@yellowhat yellowhat added Bug 🪲 Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels Aug 23, 2021
@david-yz-liu
Copy link
Contributor

Yup, I can reproduce this! I can work on this one.

@Pierre-Sassoulas Pierre-Sassoulas added False Positive 🦟 A message is emitted but nothing is wrong with the code Needs astroid update Needs an astroid update (probably a release too) before being mergable and removed Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels Aug 23, 2021
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.10.3 milestone Aug 23, 2021
Pierre-Sassoulas added a commit to Pierre-Sassoulas/pylint that referenced this issue Aug 27, 2021
@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.10.3, 2.11.0 Aug 30, 2021
Pierre-Sassoulas added a commit to Pierre-Sassoulas/pylint that referenced this issue Aug 30, 2021
Pierre-Sassoulas added a commit to Pierre-Sassoulas/pylint that referenced this issue Aug 30, 2021
Pierre-Sassoulas added a commit to Pierre-Sassoulas/pylint that referenced this issue Aug 30, 2021
Pierre-Sassoulas added a commit that referenced this issue Aug 30, 2021
@yellowhat
Copy link
Author

Hi,
I can see the same error with astroid-2.7.3:

Successfully installed astroid-2.7.3 iniconfig-1.1.1 isort-5.9.3 lazy-object-proxy-1.6.0 pluggy-1.0.0 py-1.10.0 pylint-2.10.2 pytest-6.2.5 toml-0.10.2 wrapt-1.12.1

E1101: Instance of 'Field' has no 'append' member (no-member)
E1133: Non-iterable value self.items is used in an iterating context (not-an-iterable)

Should I wait for pylint 2.11.0?

Thanks

@Pierre-Sassoulas
Copy link
Member

There was no changes in pylint so using astroid to 2.7.3 is supposed to work imo. What do you think @david-yz-liu ?

@david-yz-liu
Copy link
Contributor

Hmmm, yes it should be working. I can't reproduce this locally (Windows):

$ pylint --version
pylint 2.10.2
astroid 2.7.3
Python 3.9.1 (tags/v3.9.1:1e5d33e, Dec  7 2020, 17:08:21) [MSC v.1927 64 bit (AMD64)]

$ cat issue1158.py
from dataclasses import field
from typing import List
from pydantic.dataclasses import dataclass


@dataclass
class Item:
    description: str


@dataclass
class Case:
    """Case class (group Item)"""

    name: str
    irr: float = 0
    items: List[Item] = field(default_factory=lambda: [])

    def add_item(self, item: Item) -> None:
        """Add an item to the item list."""

        self.items.append(item)

    def find_item(self, description: str) -> Item:
        """Find an item by description"""

        return next((item for item in self.items if item.description == description), None)

$ pylint issue1158.py

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

Without the Item dataclass, I get E0602: Undefined variable 'Item' (undefined-variable) but not the no-member errors.

@yellowhat
Copy link
Author

Just tried on a archlinux podman image:

# pylint --version
pylint 2.10.2
astroid 2.7.3
Python 3.9.6 (default, Jun 30 2021, 10:22:16)
[GCC 11.1.0]
# cat a.py
from dataclasses import field
from typing import List
from pydantic.dataclasses import dataclass


@dataclass
class Item:
    description: str


@dataclass
class Case:
    """Case class (group Item)"""

    name: str
    irr: float = 0
    items: List[Item] = field(default_factory=lambda: [])

    def add_item(self, item: Item) -> None:
        """Add an item to the item list."""

        self.items.append(item)

    def find_item(self, description: str) -> Item:
        """Find an item by description"""

        return next((item for item in self.items if item.description == description), None)

# pylint a.py
************* Module a
a.py:28:0: C0305: Trailing newlines (trailing-newlines)
a.py:1:0: C0114: Missing module docstring (missing-module-docstring)
a.py:7:0: C0115: Missing class docstring (missing-class-docstring)
a.py:22:8: E1101: Instance of 'Field' has no 'append' member (no-member)
a.py:27:38: E1133: Non-iterable value self.items is used in an iterating context (not-an-iterable)

------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)

@yellowhat
Copy link
Author

Can this be reopen?

Thanks

@Pierre-Sassoulas
Copy link
Member

Did you try with the latest pylint ? I can't reproduce on the latest main branch.

@yellowhat
Copy link
Author

yellowhat commented Sep 1, 2021

Yes, as you can see above I am using pylint 2.10.2 and astroid 2.7.3.
david-yz-liu's output above seems a bit strange as it is missing:

  • Missing module docstring (missing-module-docstring)
  • Missing class docstring (missing-class-docstring) for the class Item

@Pierre-Sassoulas
Copy link
Member

Probably launched from pylint git directory using this pylintrc: https://github.com/PyCQA/pylint/blob/main/pylintrc

@yellowhat
Copy link
Author

Does this mean the the git (unreleased) version of pylint has been used?

@Pierre-Sassoulas
Copy link
Member

Pierre-Sassoulas commented Sep 1, 2021

Yes that's what I meant by "latest main branch". You can try yourself with : pip install git+git://github.com/PyCQA/pylint.git@main#egg=pylint -U (Edit: there was a typo in the branch name)

@yellowhat
Copy link
Author

Ok same error with the current git version:

# pip install git+git://github.com/PyCQA/pylint.git@main#egg=pylint -U
Collecting pylint
  Cloning git://github.com/PyCQA/pylint.git (to revision main) to /tmp/pip-install-6ytr2665/pylint_a321578df83445848ce2e945826f1f36
  Running command git clone -q git://github.com/PyCQA/pylint.git /tmp/pip-install-6ytr2665/pylint_a321578df83445848ce2e945826f1f36
Collecting platformdirs>=2.2.0
  Downloading platformdirs-2.3.0-py3-none-any.whl (13 kB)
Collecting astroid<2.8,>=2.7.3
  Downloading astroid-2.7.3-py3-none-any.whl (240 kB)
     |████████████████████████████████| 240 kB 8.8 MB/s
Collecting isort<6,>=4.2.5
  Downloading isort-5.9.3-py3-none-any.whl (106 kB)
     |████████████████████████████████| 106 kB 19.7 MB/s
Collecting mccabe<0.7,>=0.6
  Downloading mccabe-0.6.1-py2.py3-none-any.whl (8.6 kB)
Requirement already satisfied: toml>=0.7.1 in /usr/lib/python3.9/site-packages (from pylint) (0.10.2)
Requirement already satisfied: typing-extensions>=3.10.0 in /usr/lib/python3.9/site-packages (from pylint) (3.10.0.2)
Collecting lazy-object-proxy>=1.4.0
  Downloading lazy_object_proxy-1.6.0-cp39-cp39-manylinux1_x86_64.whl (57 kB)
     |████████████████████████████████| 57 kB 6.3 MB/s
Collecting wrapt<1.13,>=1.11
  Downloading wrapt-1.12.1.tar.gz (27 kB)
Requirement already satisfied: setuptools>=20.0 in /usr/lib/python3.9/site-packages (from astroid<2.8,>=2.7.3->pylint) (57.4.0)
Using legacy 'setup.py install' for pylint, since package 'wheel' is not installed.
Using legacy 'setup.py install' for wrapt, since package 'wheel' is not installed.
Installing collected packages: wrapt, lazy-object-proxy, platformdirs, mccabe, isort, astroid, pylint
    Running setup.py install for wrapt ... done
    Running setup.py install for pylint ... done
Successfully installed astroid-2.7.3 isort-5.9.3 lazy-object-proxy-1.6.0 mccabe-0.6.1 platformdirs-2.3.0 pylint-2.10.3.dev0 wrapt-1.12.1
# pylint --version
pylint 2.10.3-dev0
astroid 2.7.3
Python 3.9.6 (default, Jun 30 2021, 10:22:16)
[GCC 11.1.0]
# cat a.py
from dataclasses import field
from typing import List
from pydantic.dataclasses import dataclass


@dataclass
class Item:
    description: str


@dataclass
class Case:
    """Case class (group Item)"""

    name: str
    irr: float = 0
    items: List[Item] = field(default_factory=lambda: [])

    def add_item(self, item: Item) -> None:
        """Add an item to the item list."""

        self.items.append(item)

    def find_item(self, description: str) -> Item:
        """Find an item by description"""

        return next((item for item in self.items if item.description == description), None)

# pylint a.py
************* Module a
/a.py:28:0: C0305: Trailing newlines (trailing-newlines)
/a.py:1:0: C0114: Missing module docstring (missing-module-docstring)
/a.py:7:0: C0115: Missing class docstring (missing-class-docstring)
/a.py:22:8: E1101: Instance of 'Field' has no 'append' member (no-member)
/a.py:27:38: E1133: Non-iterable value self.items is used in an iterating context (not-an-iterable)

------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)

This has been run in a fresh archlinux container, just installed python-pip, python-pydantic and git.

@david-yz-liu
Copy link
Contributor

Okay, I can replicate this using pydantic v1.6.2 but not 1.8.2 or 1.7.4. To confirm, @yellowhat can you please check what version of pydantic you are currently using?

@yellowhat
Copy link
Author

yellowhat commented Sep 1, 2021

I am using:

import pydantic
pydantic.VERSION
'1.8.2'

@DanielNoord
Copy link
Collaborator

I found why @david-yz-liu couldn't reproduce this by running pylint a.py.
You need to add the --extension-pkg-whitelist="pydantic" flag in order for it to work fail. See:

❯ cat test.py
from dataclasses import field
from typing import List

from pydantic.dataclasses import dataclass


@dataclass
class Item:
    description: str


@dataclass
class Case:
    """Case class (group Item)"""

    name: str
    irr: float = 0
    items: List[Item] = field(default_factory=lambda: [])

    def add_item(self, item: Item) -> None:
        """Add an item to the item list."""

        self.items.append(item)

    def find_item(self, description: str) -> Item:
        """Find an item by description"""

        return next((item for item in self.items if item.description == description), None)

❯ pylint --extension-pkg-whitelist="pydantic" test.py
************* Module test
test.py:23:8: E1101: Instance of 'Field' has no 'append' member (no-member)
test.py:28:38: E1133: Non-iterable value self.items is used in an iterating context (not-an-iterable)

------------------------------------------------------------------
Your code has been rated at 2.31/10 (previous run: 2.31/10, +0.00)

❯ pylint test.py

-------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 2.31/10, +7.69)

This is with pydantic==1.8.2. Not sure if this gives any immediate hints as to the source of the problem, but should at least make it possible to reproduce.
I'm guessing @yellowhat has this flag in their pylint.rc and that's why it is not showing up in their shell output.

@yellowhat
Copy link
Author

@DanielNoord I have not setup any pylint.rc, all the test above were done using a fresh archlinux container, install pydantic and pylint@git and run the example code.

@yellowhat
Copy link
Author

Hi,
I have noticed that new code has been merged, so I tried again:

$ pip install git+git://github.com/PyCQA/pylint.git@main#egg=pylint -U
Collecting pylint
  Cloning git://github.com/PyCQA/pylint.git (to revision main) to /tmp/pip-install-q3y0k585/pylint_125c375d4e0e416186ea47bfa922181e
  Running command git clone -q git://github.com/PyCQA/pylint.git /tmp/pip-install-q3y0k585/pylint_125c375d4e0e416186ea47bfa922181e
Collecting platformdirs>=2.2.0
  Downloading platformdirs-2.3.0-py3-none-any.whl (13 kB)
Collecting astroid<2.9,>=2.8.0
  Downloading astroid-2.8.0-py3-none-any.whl (242 kB)
     |████████████████████████████████| 242 kB 10 kB/s
Collecting isort<6,>=4.2.5
  Downloading isort-5.9.3-py3-none-any.whl (106 kB)
     |████████████████████████████████| 106 kB 16.8 MB/s
Collecting mccabe<0.7,>=0.6
  Downloading mccabe-0.6.1-py2.py3-none-any.whl (8.6 kB)
Requirement already satisfied: toml>=0.7.1 in /usr/lib/python3.9/site-packages (from pylint) (0.10.2)
Requirement already satisfied: typing-extensions>=3.10.0 in /usr/lib/python3.9/site-packages (from pylint) (3.10.0.2)
Collecting wrapt<1.13,>=1.11
  Downloading wrapt-1.12.1.tar.gz (27 kB)
Requirement already satisfied: setuptools>=20.0 in /usr/lib/python3.9/site-packages (from astroid<2.9,>=2.8.0->pylint) (57.4.0)
Collecting lazy-object-proxy>=1.4.0
  Downloading lazy_object_proxy-1.6.0-cp39-cp39-manylinux1_x86_64.whl (57 kB)
     |████████████████████████████████| 57 kB 7.5 MB/s
Using legacy 'setup.py install' for pylint, since package 'wheel' is not installed.
Using legacy 'setup.py install' for wrapt, since package 'wheel' is not installed.
Installing collected packages: wrapt, lazy-object-proxy, platformdirs, mccabe, isort, astroid, pylint
    Running setup.py install for wrapt ... done
    Running setup.py install for pylint ... done
Successfully installed astroid-2.8.0 isort-5.9.3 lazy-object-proxy-1.6.0 mccabe-0.6.1 platformdirs-2.3.0 pylint-2.11.2.dev0 wrapt-1.12.1
$ pylint --version
pylint 2.11.2-dev0
astroid 2.8.0
Python 3.9.7 (default, Aug 31 2021, 13:28:12)
[GCC 11.1.0]
$ cat a.py
from dataclasses import field
from typing import List
from pydantic.dataclasses import dataclass


@dataclass
class Item:
    description: str


@dataclass
class Case:
    """Case class (group Item)"""

    name: str
    irr: float = 0
    items: List[Item] = field(default_factory=lambda: [])

    def add_item(self, item: Item) -> None:
        """Add an item to the item list."""

        self.items.append(item)

    def find_item(self, description: str) -> Item:
        """Find an item by description"""

        return next((item for item in self.items if item.description == description), None)
$ pylint a.py
************* Module a
/a.py:28:0: C0305: Trailing newlines (trailing-newlines)
/a.py:1:0: C0114: Missing module docstring (missing-module-docstring)
/a.py:7:0: C0115: Missing class docstring (missing-class-docstring)
/a.py:22:8: E1101: Instance of 'Field' has no 'append' member (no-member)
/a.py:27:38: E1133: Non-iterable value self.items is used in an iterating context (not-an-iterable)

-----------------------------------
Your code has been rated at 0.00/10

still no luck.
Can we reopen the bug?

Thanks

@and3rson
Copy link

and3rson commented Jan 4, 2023

I can reproduce this as well:

$ python3 -m pipdeptree -p pylint
pylint==2.15.3
  - astroid [required: >=2.12.10,<=2.14.0-dev0, installed: 2.12.13]
    - lazy-object-proxy [required: >=1.4.0, installed: 1.9.0]
    - typing-extensions [required: >=3.10, installed: 4.4.0]
    - wrapt [required: >=1.11,<2, installed: 1.14.1]
  - dill [required: >=0.2, installed: 0.3.6]
  - isort [required: >=4.2.5,<6, installed: 5.10.1]
  - mccabe [required: >=0.6,<0.8, installed: 0.7.0]
  - platformdirs [required: >=2.2.0, installed: 2.6.2]
  - tomli [required: >=1.1.0, installed: 2.0.1]
  - tomlkit [required: >=0.10.1, installed: 0.11.6]
  - typing-extensions [required: >=3.10.0, installed: 4.4.0]

$ python3 -m pipdeptree -p pydantic
pydantic==1.10.2
  - typing-extensions [required: >=4.1.0, installed: 4.4.0]
class Foo(BaseModel):
    events: List[Union[int, str]] = Field(default_factory=list)

    def bar(self):
        self.events.append(42)  # E1101: Instance of 'FieldInfo' has no 'append' member (no-member)

EDIT: This seems to reproduce only with non-binary version of pydantic (pip install pydantic --no-binary pydantic). When switching back to default binary version of the package (pip install pydantic), the error is gone.

@Pierre-Sassoulas
Copy link
Member

Please open a new bug issue, I appreciate the effort to not create a duplicate but in order to reopen I'd like to reproduce and I if I don't have the time the issue is closed so it's not going to get any attention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🪲 False Positive 🦟 A message is emitted but nothing is wrong with the code Needs astroid update Needs an astroid update (probably a release too) before being mergable
Projects
None yet
5 participants