facebook / pyre-check

Performant type-checking for python.

Home Page:https://pyre-check.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pyre false positive with type defined by NewType

nerdinand opened this issue · comments

Bug description
We're using pyre to type check code that uses the snowflake-snowpark-python package. It defines some custom types using the typing.NewType function: https://github.com/snowflakedb/snowpark-python/blob/main/src/snowflake/snowpark/_internal/type_utils.py#L617-L627. When using these types, we're getting type errors, for example this:

src/reproduction.py:3:8 Incompatible parameter type [6]: In call `spf.min`, for 1st positional argument, expected `ColumnOrName` but got `str`.

Clearly, this shouldn't be the case, because ColumnOrName is defined as:

ColumnOrName = NewType("ColumnOrName", Union["snowflake.snowpark.column.Column", str])

Note that defining the type without NewType, for example

ColumnOrName = Union["snowflake.snowpark.column.Column", str]

does not result in the type error.

Reproduction steps
Minimal example to reproduce: pyre-bug-reproduction.zip

  1. Extract zip
  2. Run poetry install
  3. Run poetry run pyre check
  4. Result:
ƛ Found 1 type error!
src/reproduction.py:3:8 Incompatible parameter type [6]: In call `spf.min`, for 1st positional argument, expected `ColumnOrName` but got `str`.

Expected behavior
I'd expect this not to result in a type error.

Hey - sorry about the delay in responding. Would you mind making a repro of your issue in the pyre playground?

Hi @kinto0, unfortunately the playground doesn't seem to work, it gives me a CORS error in the developer console...

I just looked into this a bit more. Considering the code:

from typing import NewType, Union

ColumnOrName = NewType("ColumnOrName", Union["snowflake.snowpark.column.Column", str])

def min(e: ColumnOrName) -> None:
    pass

min("foo")

with the definition for ColumnOrName copied from https://github.com/snowflakedb/snowpark-python/blob/491599ae1c52e112070bb9b68ce58d847f350f1a/src/snowflake/snowpark/_internal/type_utils.py#L625, we actually get 2 type errors:

ƛ Found 2 type errors!
src/reproduction.py:3:39 Invalid inheritance [39]: `Union[snowflake.snowpark.column.Column, str]` is not a valid parent class.
src/reproduction.py:8:4 Incompatible parameter type [6]: In call `min`, for 1st positional argument, expected `ColumnOrName` but got `str`.

In contrast, not using NewType in the definition, the code passes type checks:

from typing import NewType, Union

ColumnOrName = Union["snowflake.snowpark.column.Column", str]

def min(e: ColumnOrName) -> None:
    pass

min("foo")

So is snowflakedb/snowpark-python using NewType wrongly? Maybe this is a bug there?