basedpyright icon indicating copy to clipboard operation
basedpyright copied to clipboard

Some inlay hints result in invalid types when inserted

Open decorator-factory opened this issue 8 months ago • 3 comments

Description

Basedpyright version: 1.29.4

[based]pyright sometimes infers types that are not expressible in source code. For example:

Code as text
import random

class Foo: pass
class Bar: pass

class NiceThings[*Ts]:
    def __init__(self, things: tuple[*Ts]) -> None:
        self.things = things

    def cant_have_them(self):
        return random.choice(self.things)

    def nope(self, foo: Foo):
        if isinstance(foo, Bar):
            return foo
        else:
            raise RuntimeError

Playground screenshot (works the same way in VSCode)

Union[*Ts] is invalid, and <subclass of Foo and Bar> isn't even valid Python syntax. However, basedpyright allows you to insert those return types by double-clicking on the inlay hint.

Should these unspeakable types appear in return type inference in the first place? Maybe they could be reduced to the closest legal type, like object/Any instead of Union[*Ts], and Foo (or Bar?) instead of the intersection type. If these internal types are allowed to escape, I'm sure some codebases will take advantage of that and just skip annotating the return type. But maybe that's okay?

decorator-factory avatar Jun 26 '25 14:06 decorator-factory

I think that if the type isn't valid, then it could be rendered in a different style

KotlinIsland avatar Jun 26 '25 20:06 KotlinIsland

Inlay hints use the PythonSyntax flag in the type printer, so this invalid syntax is definitely a bug

DetachHead avatar Jun 26 '25 22:06 DetachHead

Code sample in basedpyright playground

def f(a: str) -> str:
    return a

a`: str` = b`: str` = f("foo")

Here's another slightly different case that a and b here cannot insert any annotations.

NCBM avatar Nov 14 '25 15:11 NCBM