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

Object of type "None" cannot be called #2871

Closed
daudef opened this issue May 31, 2022 · 11 comments
Closed

Object of type "None" cannot be called #2871

daudef opened this issue May 31, 2022 · 11 comments
Labels
bug Something isn't working type checking waiting for upstream Waiting for upstream to release a fix

Comments

@daudef
Copy link

daudef commented May 31, 2022

Environment data

  • Language Server version: 2022.5.3 (pyright 73c82fab)
  • OS and version: macOS Monterey 12.4
  • Python version (& distribution if applicable, e.g. Anaconda): 3.10.2 64-bit

Code Snippet

0:  from typing import Callable
1: 
2:  def bug_showcase(cb: Callable[[], int] | None):
3:     l: list[int] = []
4:     for _ in range(0):
5:         if cb is not None:
6:             l += [cb()]
7:         l.append(0)

Repro Steps

  1. Open the file in VSCode.
  2. Pylance (strict mode) underlines the cb identifier (line 6) in red.
  3. It is a bit random, I sometime need to add and remove spaces 3 or 4 times, to update Pylance so it shows the error.

Expected behavior

I'm calling an optional callable after checking that it is not None so there should not be any problem.
When hovering the cb identifier (line 6) it should show :

(parameter) cb: () -> int

Actual behavior

When hovering the cb identifier (line 6) it shows :

(parameter) cb: () -> int
Object of type "None" cannot be called   Pylance(reportOptionalCall)
View Problem   No quick fixes available

Pylance infers the correct type for cb but still detects an error.
I tried to make the smallest example possible, for example commenting line 7, fixes the issue.

@erictraut
Copy link
Contributor

Thanks for the bug report. I'm 95% sure that the underlying cause of this bug has been fixed in the past few days. I'm not entirely sure because I'm finding it difficult to repro the problem. I did get it to happen a few times with the last-published version of Pylance, but I can't get it to occur with the latest build.

The symptom would be explained by the bug fix I introduced for this issue. The code in your sample is also very similar to the code in that bug report.

I'm going to mark the bug as "fixed in next release". If it still occurs for you after the next release of Pylance, we can re-open it, and I'll take another look.

@erictraut erictraut added bug Something isn't working fixed in next version (main) A fix has been implemented and will appear in an upcoming version and removed triage labels May 31, 2022
@bschnurr
Copy link
Member

bschnurr commented Jun 1, 2022

This issue has been fixed in version 2022.6.0, which we've just released. You can find the changelog here: CHANGELOG.md

@bschnurr bschnurr closed this as completed Jun 1, 2022
@daudef
Copy link
Author

daudef commented Jun 2, 2022

I can confirm that the new version fixed the issue, thank you for your help.

@daudef
Copy link
Author

daudef commented Jun 13, 2022

I just updated Pylance to v2022.6.10 and the bug (fixed with v2022.6.0) is occurring again.

@erictraut
Copy link
Contributor

@daudef, I can't think of anything that changed between 2022.6.0 and 2022.6.10 that would have caused a regression. I suspect this is still a lingering bug. Reopening for further investigation.

I'm finding this very hard to repro. I saw it happen once with 2022.6.10, but it goes away almost immediately. I suspect it's a case where evaluation ordering is producing the wrong result.

Here's the code sample without the line numbers:

from typing import Callable

def bug_showcase(cb: Callable[[], int] | None):
    l: list[int] = []
    for _ in range(0):
        if cb is not None:
            l += [cb()]
        l.append(0)

@erictraut erictraut reopened this Jun 13, 2022
@erictraut erictraut removed the fixed in next version (main) A fix has been implemented and will appear in an upcoming version label Jun 13, 2022
@erictraut
Copy link
Contributor

I've created a tracking bug in the pyright repo.

@judej judej added the waiting for upstream Waiting for upstream to release a fix label Jun 13, 2022
@erictraut
Copy link
Contributor

I'm no longer able to repro this problem, but I struggled to repro it previously, so I don't know if it's gone.

I'm going to close the tracking bug for now. If you are able to repro it, I'll reopen and investigate further.

@konsalex
Copy link

Not sure if this issue fits this thread:

CleanShot 2022-10-25 at 20 28 44

But I get this error when I apply a hook from Wagtail. The actual code snippet:

from wagtail.core import hooks

# Remove entries from pages side menu
@hooks.register("construct_main_menu")
def hide_user_menu_item(request, menu_items):
    menu_items[:] = [item for item in menu_items if item.name != "explorer"]

and the register typings:

def register(hook_name, fn=None, order=0):
     ...

@erictraut
Copy link
Contributor

The bug reported in this issue has been fixed. I think it's safe to mark this as closed.

@rchiodo rchiodo closed this as completed Jan 24, 2023
@TimurRin
Copy link

TimurRin commented Aug 4, 2023

Pylance v2023.8.10
Type checking: simple

I got this reportOptionalCall error when I call Callable|None directly from a class instance (database_views[self.table_name])
image

But when I assign this Callable to a local variable, it works fine.
image

@erictraut
Copy link
Contributor

@TimurRin, this is expected. The type of an expression is not narrowed when using an index expression if the subscript to the index is a dynamic expression like self.table_name. A static type checker cannot guarantee that the type of the index express will remain consistent. If you assign the result of the index expression to a local variable like proc, the value is guaranteed not to change between the assignment and its usage. For more details about type narrowing, refer to this documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working type checking waiting for upstream Waiting for upstream to release a fix
Projects
None yet
Development

No branches or pull requests

7 participants