Skip to content

Possibly nonsensical false positive for Generic class C must not reference type variables bound in an enclosing scope #2780

@amluto

Description

@amluto

Summary

Here's some Python code extracted from a project I'm working on:

class TypedFieldValue[T]:
    pass

class CodecBase[T]:
    typed_field_value_cls: type[TypedFieldValue[T]]

    def __init_subclass__(cls) -> None:
        class ConcreteTypedFieldValue[U](TypedFieldValue[U]):
            pass
            
        cls.typed_field_value_cls = ConcreteTypedFieldValue[T]

Mypy accepts it and ty does not. While, in general, I tend to trust ty more than mypy, the error message and, in particular, its details, make me highly suspicious that ty is very confused:

error[invalid-generic-class]: Generic class `ConcreteTypedFieldValue` must not reference type variables bound in an enclosing scope
 --> ty_is_sad.py:8:15
  |
7 |     def __init_subclass__(cls) -> None:
8 |         class ConcreteTypedFieldValue[U](TypedFieldValue[U]):
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` referenced in class definition here
9 |             pass
  |
 ::: ty_is_sad.py:4:7
  |
2 |     pass
3 |
4 | class CodecBase[T]:
  |       --------- Type variable `T` is bound in this enclosing scope
5 |     typed_field_value_cls: type[TypedFieldValue[T]]
  |
info: rule `invalid-generic-class` is enabled by default

Found 1 diagnostic

I don't think I'm referencing T from the class definition. Certainly the line that ty indicates does not contain [T] or any other explicit reference to the type variale T. The variable U is not T! (I can omit the [U] in both places in that line, and ty accepts the entire file, but I find that rather surprising, too.)

Maybe I'm missing something and, if so, I apologize for the noise, but at the very least the error message could be less bizarre.

Version

0.0.16

Metadata

Metadata

Assignees

No one assigned

    Labels

    genericsBugs or features relating to ty's generics implementation

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions