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

F821 on use of Literal with strings, e.g. Literal['foo'] #128

Closed
samuelcolvin opened this issue Sep 8, 2022 · 7 comments · Fixed by #131
Closed

F821 on use of Literal with strings, e.g. Literal['foo'] #128

samuelcolvin opened this issue Sep 8, 2022 · 7 comments · Fixed by #131

Comments

@samuelcolvin
Copy link

samuelcolvin commented Sep 8, 2022

Since #119 was fixed via #125, I tried ruff again (build from main) with pydantic.

I get a few remaining F821 errors due to use of strings in Literal, the line numbers are also incorrect - seems to always be 1.

From this code (and some other places in that file), I get:

pydantic/config.py:1:1: F821 Undefined name `deep`
pydantic/config.py:1:1: F821 Undefined name `none`
pydantic/config.py:1:1: F821 Undefined name `deep`
pydantic/config.py:1:1: F821 Undefined name `shallow`
pydantic/config.py:1:1: F821 Undefined name `before_validation`
pydantic/config.py:1:1: F821 Undefined name `after_validation`
pydantic/config.py:1:1: F821 Undefined name `none`
pydantic/config.py:1:1: F821 Undefined name `shallow`
pydantic/config.py:1:1: F821 Undefined name `before_validation`
pydantic/config.py:1:1: F821 Undefined name `after_validation`

Example code:

    copy_on_model_validation: Literal['none', 'deep', 'shallow']
    post_init_call: Literal['before_validation', 'after_validation']
@samuelcolvin
Copy link
Author

I have no idea how you differentiate in a general way between the following:


from typing import Literal

def foo(x: Literal['int']):
    pass

from typing import List

def foo(x: List['int']):
    pass

from .local_types import CustomThing

def foo(x: CustomThing['int']):
    pass

Obviously you can whitelist Literal, but I have no idea how you would work out whether CustomThing is parameterised with strings or types which might be strings.

I guess you have to assume it's parameterised with types, can maybe one day allow a magic comment or magic property which tells ruff that CustomThing is parameterised with literals - maybe there's a pep for this, but I don't know of it.

@charliermarsh
Copy link
Member

Yeah it looks like PyFlakes special-cases Literal: https://github.com/PyCQA/pyflakes/blob/master/pyflakes/checker.py#L1464. Will fix.

PyFlakes actually has a lot of custom logic for caching forward-reference annotation in cast and TypeVar calls which we're yet to handle, so this may pop up there too.

@charliermarsh
Copy link
Member

(The 1:1 issue will be handled separately, tracking in #132. Thank you!)

@vianmixtkz
Copy link

I still have the same issue
image

What version of ruff fixes it ?

I am using ruff==0.0.254

@charliermarsh
Copy link
Member

@vianmixtkz - This was fixed long long ago. How are you importing Literal?

@vianmixtkz
Copy link

Gotcha,

I was importing it from another module. I tried to import it directly from typing and it fixed the issue.
Thanks.

What caused that though ?

@charliermarsh
Copy link
Member

If you add that module to typing-modules, that should fix the issue for you without having to import from typing directly. We don't trace imports across files, so if you import Literal in one file, export it, and then import that export elsewhere, we don't know that it's equivalent to typing.Literal. By adding your first-party module to typing-modules, you can tell Ruff that anything imported from that module should be considered equivalent to a typing import.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants