koxudaxi / pydantic-pycharm-plugin

PyCharm plugin for pydantic. This plugin provides autocompletion, inspection, type-checking, inserting unfilled argument, and more.
https://koxudaxi.github.io/pydantic-pycharm-plugin/
MIT License
451 stars 16 forks source link

False-Positive "Unresolved attribute ..." everywhere #924

Open dantetemplar opened 5 months ago

dantetemplar commented 5 months ago

Describe the bug False-Positive unresolved attribute appears everywhere after updating plugin to 0.4.13 version

Expected behavior Only True-Positive and True-Negative unresolved attribute warnings.

Screenshots image image image

Environments (please complete the following information):

dantetemplar commented 5 months ago

Sorry for huge amount of code in screenshots, I'm in haste...

koxudaxi commented 5 months ago

@dantetemplar Thank you for creating the issue. Sorry, I can't reproduce the warning. Could you please share your code as text? Especially,the model definition part.

dantetemplar commented 5 months ago

@koxudaxi, I guess problem is that Beanie uses model fields as class attributes.

from beanie import Document, init_beanie
from motor.motor_asyncio import AsyncIOMotorClient

class Car(Document):
    car_number: int

async def read_by_car_number(car_number: int) -> Car | None:
    _car = await Car.find(Car.car_number == car_number).first_or_none()
    return _car

async def setup_database() -> AsyncIOMotorClient:
    # ------------------- Repositories Dependencies -------------------

    motor_client = AsyncIOMotorClient(
        "mongodb://*******:*******@localhost:27017/db?authSource=admin",
        connectTimeoutMS=5000,
        serverSelectionTimeoutMS=5000,
    )

    mongo_db = motor_client.get_default_database()
    await init_beanie(database=mongo_db, document_models=[Car], recreate_views=True)
    return motor_client

if __name__ == "__main__":
    import asyncio

    async def main():
        await setup_database()
        print(await read_by_car_number(1))

    asyncio.run(main())

image

dantetemplar commented 5 months ago

The simplest solution is to add a switch to the plugin settings for "Always allow model fields to be used as class variables".

dantetemplar commented 5 months ago

I found where is magic.

beanie.odm.utils.init.py#L372

class Initializer:
    def init_document_fields(self, cls) -> None:
        """
        Init class fields
        :return: None
        """

        if not IS_PYDANTIC_V2:
            self.update_forward_refs(cls)

        if cls._link_fields is None:
            cls._link_fields = {}
        for k, v in get_model_fields(cls).items():
            path = v.alias or k
            setattr(cls, k, ExpressionField(path))   # <---------------- Here, dynamically assign attributes to model

            link_info = self.detect_link(v, k)
            depth_level = cls.get_settings().max_nesting_depths_per_field.get(
                k, None
            )
            if depth_level is None:
                depth_level = cls.get_settings().max_nesting_depth
            if link_info is not None:
                if depth_level > 0 or depth_level is None:
                    cls._link_fields[k] = link_info
                    self.check_nested_links(
                        link_info, current_depth=depth_level
                    )
                elif depth_level <= 0:
                    link_info.is_fetchable = False
                    cls._link_fields[k] = link_info

        cls.check_hidden_fields()
dantetemplar commented 5 months ago

May it be related to code from #919 ?

dantetemplar commented 5 months ago

@koxudaxi What should I look into to try to fix this?

powerfulyang commented 3 months ago

I encountered the same issue while using sqlmodel.

from sqlmodel import Field, SQLModel

class Hero(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: int | None = None

print(Hero.name)

image

powerfulyang commented 3 months ago

@dantetemplar Did you find a solution?

powerfulyang commented 3 months ago

Downgrade to v0.4.12, it's ok. image But no model fields autocompletion. image

dantetemplar commented 3 months ago

@dantetemplar Did you find a solution?

Nope :6

By the way, How to downgrade plugin in jetbrains?

powerfulyang commented 3 months ago

goto https://plugins.jetbrains.com/plugin/12861-pydantic/versions/stable, image image

HeiziND commented 2 months ago

I have this issue when using SQLModel as well. downgrading to 4.12 does indeed stop the error but it also stops auto-completion on class attributes.

wushaojun321 commented 1 month ago

I have this issue when using SQLModel as well. downgrading to 4.12 does indeed stop the error but it also stops auto-completion on class attributes.我在使用 SQLModel 时也遇到这个问题。降级到 4.12 确实会停止错误,但也会停止类属性的自动完成。

There is no automatic completion of class attributes in 4.14