Object of type "None" cannot be called
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
- Open the file in VSCode.
- Pylance (strict mode) underlines the
cbidentifier (line 6) in red. - 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.
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.
This issue has been fixed in version 2022.6.0, which we've just released. You can find the changelog here: CHANGELOG.md
I can confirm that the new version fixed the issue, thank you for your help.
I just updated Pylance to v2022.6.10 and the bug (fixed with v2022.6.0) is occurring again.
@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)
I've created a tracking bug in the pyright repo.
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.
Not sure if this issue fits this thread:

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):
...
The bug reported in this issue has been fixed. I think it's safe to mark this as closed.
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])
But when I assign this Callable to a local variable, it works fine.
@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.