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

https://github.com/microsoft/vscode/issues/229111 #6417

Closed
jefer94 opened this issue Sep 20, 2024 · 10 comments
Closed

https://github.com/microsoft/vscode/issues/229111 #6417

jefer94 opened this issue Sep 20, 2024 · 10 comments
Assignees
Labels
by design user responded Was "waiting for user response" and they responded

Comments

@jefer94
Copy link

jefer94 commented Sep 20, 2024

microsoft/vscode#229111

@jefer94
Copy link
Author

jefer94 commented Sep 20, 2024

Also, python allows redefining variables, if you have a variable that you are using, and in the middle you redefine it, this redefinition affects the lines above, which have no sense (I know that the code is bad written)

image

@karthiknadig karthiknadig transferred this issue from microsoft/vscode-python Sep 20, 2024
@github-actions github-actions bot added the needs repro Issue has not been reproduced yet label Sep 20, 2024
@debonte
Copy link
Contributor

debonte commented Sep 20, 2024

microsoft/vscode#229111

It's not clear to me what the issue is. Can you provide more detail on what you're seeing vs. what you are expecting. Also a simpler example with a list of package dependencies (with versions if appropriate) would help us when we try to reproduce what you're seeing.

Also, python allows redefining variables, if you have a variable that you are using, and in the middle you redefine it, this redefinition affects the lines above, which have no sense (I know that the code is bad written)

The f in async for f in e: and the f in f: pagers.ListTranscriptsAsyncPager... are the same variable. You can read more about Python's name scoping rules here, or perhaps prove it to yourself by running this simplified example:

e: list[int] = [1]
for f in e:
    pass

print(f"Before annotation: {f}")
f: list[str]
print(f"After annotation: {f}")

# Outputs:
# Before annotation: 1
# After annotation: 1

Since these two fs are the same f, it is expected that the annotation on one affects them all.

@debonte debonte added the waiting for user response Requires more information from user label Sep 20, 2024
@jefer94
Copy link
Author

jefer94 commented Sep 21, 2024

I am confused, I am reading the response, and you seem like you read it, what am I expecting? that the highlighter works, I wrote a sentence twice, all types were in the wrapper, the horrible Google Meet API library, and the sentence repeated are the same, in the first line it fails, in the second repeating the same type it works, the type did not change, what typed manually with the same type that it has, if both sentences contain exactly the same type, both should be looked equals
image

For the second response, could you let me know if you got the wrong value from the Python Built-in library? because I am typing a variable and the variables has particular features, like changing its type all times you want, so, whose issue is it? I should open this issue in the Python forum, I had no hope that a Microsoft developer would do it, they didn't open this issue here even knowing that this issue existed, I do

@github-actions github-actions bot added user responded Was "waiting for user response" and they responded and removed waiting for user response Requires more information from user labels Sep 21, 2024
@erictraut
Copy link
Contributor

@jefer94, you're correct that Python allows you to assign different types to any symbol. For example:

f = 1
f = "hi"

However, if you use static type annotations, you are declaring that a symbol's type is limited to a particular type (or subtypes thereof). In your code, you are using such type declarations. Once you declare the type of a symbol, it is the job of a static type checker to prevent you from violating that type declaration.

If you provide no type declaration for a symbol, pyright (the type checker upon which pylance is built) will allow you to assign any value to it. In your screen shot above, you have provided a type declaration for symbols e and f.

For more details about type declarations, refer to this documentation.

@jefer94
Copy link
Author

jefer94 commented Sep 21, 2024

If that type checker applies the types statically on the scope, I think it should, or:

  1. The highlighter should show an error on type redefinition
a = 1
a: str = "2" # TypeError: `a` is `int` and can be changed 
  1. The highlighter should try to guess the type and accept changes the types of variable
def my_pretty_func():
    a = False
    def my_prettiest_func():
        a = 3
        
    a: str = "hi"
    my_prettiest_func()
    # more lines
    print(a)

Maybe the first approach is easier to apply and is better than saying that the lines 2, 4, 6, and n are str, I should understand that should be complicated to infer the value of n line, but in each other line has no reason to show something like a = False is str that is completely unacceptable

@erictraut
Copy link
Contributor

Your mental model is a bit off here. Let me try to clear things up.

If you provide a type annotation for a symbol, you are declaring its type. If you declare that the type of symbol a is str, then a type checker will enforce that any value assigned to a is assignable to type str. If you attempt to assign a value that isn't compatible with str and you have type checking enabled, you will see these errors in your editor.

Screenshot 2024-09-21 at 5 10 56 PM

The rules for type assignability are spelled out in the Python typing spec, which can be found here.

A symbol can have only one declared type. If you attempt to declare its type multiple times in conflicting ways, a type checker will generate an error telling you about this inconsistency.

Screenshot 2024-09-21 at 5 13 39 PM

Simply assigning a value to a symbol does not declare the type of that symbol. If a symbol's type hasn't been explicitly declared, it's declared type is implicitly object, and it can be assigned a value of any type without generating any type errors. It's not uncommon in Python code to reuse a variable and assign it values of different types.

Screenshot 2024-09-21 at 5 14 11 PM

Pylance is working as intended here, so this isn't a bug.

@jefer94
Copy link
Author

jefer94 commented Sep 22, 2024

That wasn't my case

image

image

image

image

image

Even asserting that a is a str it says that it's a Literal of type string, if it insists on do these assertions, why doesn't it insist on showing the truth, I don't tell the type checker that it was a Literal, it insists, and it fails

@jefer94
Copy link
Author

jefer94 commented Sep 22, 2024

The number 1 function of a highlighter is showing information that the developer can't see easily, and it's failing, even in cases easily predicable

@debonte
Copy link
Contributor

debonte commented Sep 23, 2024

@jefer94, I was able to reproduce the semantic highlighting behavior that you reported in microsoft/vscode#229111.

The problem there is that your first call to client.alist_conference_records() is missing arguments for the required page_size, page_token, and filter parameters. Due to these missing arguments, Pyright (the type checker that Pylance is based on) treats the return value as Unknown (equivalent to Any) and therefore the semantic token provider doesn't know what f.expire_time is, which is why it is uncolored. If you provide those required arguments, you'll see that f.expire_time is colored as you'd expect.

You may want to enable our typeCheckingMode config setting. If you set "python.analysis.typeCheckingMode": "basic", Pylance will report an error on the alist_conference_records call: Arguments missing for parameters "page_size", "page_token", "filter"

image

Regarding your my_pretty_func question above, Pyright will narrow the type of a variable when it can. See the documentation here. After the assignment of "hi", we know that a won't be just any str, but specifically "hi". We don't track the side-effects of function calls, so we're unaware that my_prettiest_func changes the value of a. This is by design. There's a brief discussion of why in this comment.

If you set typeCheckingMode as mentioned above, you'll get errors on the a = False and a = 3 assignments since a is annotated as str. You could change that annotation to str | int | bool (or more simply, str | int) if those assignments are intentional.

image

@debonte debonte closed this as completed Sep 23, 2024
@jefer94
Copy link
Author

jefer94 commented Sep 23, 2024

I suppose that if that method isn't overloaded it will take the only return mark, so, changing

class ListRecordingsRequest(TypedDict):
    parent: str
    page_size: int
    page_token: str

For

class ListRecordingsRequest(TypedDict, total=False):
    parent: str
    page_size: int
    page_token: str

Fix that issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
by design user responded Was "waiting for user response" and they responded
Projects
None yet
Development

No branches or pull requests

4 participants