Open tylerlaprade opened 2 weeks ago
Can you provide a minimal self-contained example? The code posted above contains many symbols that are not defined.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Iterable
class ModelBase(type):
pass
class Model(metaclass=ModelBase):
pass
def register(
model_or_iterable: 'type[Model] | Iterable[type[Model]]',
):
if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for _model in model_or_iterable: # "type[Model]" is not iterable "__iter__" method not definedPylance[reportGeneralTypeIssues]
pass
You mentioned the "pre-release version". Do you suspect that this is a regression? Are you building your own version of pyright from source? I'm not seeing any difference in behavior between the main branch and the latest published version of pyright.
I'm not sure I'd classify this as a bug, but I agree there's an opportunity for further narrowing in the negative case when using a metaclass in an isinstance
type guard.
class Meta(type):
pass
class A(metaclass=Meta):
pass
def func(m: type[A] | str):
if not isinstance(m, Meta):
reveal_type(m) # type[A] | str, but could be just str
Ah, it just occurred to me that you're talking about the pre-release version of pylance, not of pyright.
Pyright's type narrowing logic changed two versions ago (in 1.1.387) to fix some bugs. It looks like the behavior changed in this case. I'll look at restoring the previous behavior.
Perfect, thanks Eric! Sorry for the confusion.
Hi, I'm not sure if this is a bug in the pre-release version or if it's working as intended.
Model
in this case comes from Django, and its metaclass isModelBase
. This code typechecks just fine on the release version but errors on the commented line when on the pre-release version. The detected type ismodel_or_iterable: list[type[Model]] | type[Model] | Iterable[type[Model]]
.