Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    armoha
    @armoha

    Hi, I'm adding type hints to unwrapping proxy class but it's getting difficult.
    I got eudplib\core\rawtrigger\constenc.py:304: error: Incompatible return value type (got "Union[int, EUDVariable, ConstExpr, ExprProxy[Any]]", expected "Union[int, EUDVariable, ConstExpr]") [return-value]

    T_co = TypeVar("T_co", covariant=True)
    
    class ExprProxy(Generic[T_co]):
        def __init__(self, initval: T_co) -> None:
            self._value: T_co = initval
    
        def getValue(self) -> T_co:
            return self._value
    
    T = TypeVar("T")
    
    
    @overload
    def unProxy(x: "ExprProxy[T]") -> T:
        ...
    
    
    @overload
    def unProxy(x: T) -> T:
        ...
    
    
    def unProxy(x):
        while isinstance(x, ExprProxy):
            x = x.getValue()
        return x
    
    def _EncodeConst(
        t: str, d: dict[_Unique, int], s: "int | _Unique | EUDVariable | ConstExpr | ExprProxy"
    ) -> "int | EUDVariable | ConstExpr":
        u = unProxy(s)
        if isinstance(u, _Unique):
            if u in d:
                return d[u]
            raise EPError(_('[Warning] "{}" is not a {}').format(u, t))
        return u

    unProxy can return any object except ExprProxy but apparently mypy can't understand this although I tried using TypeVar to hint this. Should I add type: ignore[return-value] on every functions which accepts proxy class?

    1 reply
    dmr
    @dmrobertson:matrix.org
    [m]
    glad to hear it!
    generalpp
    @generalpp:matrix.org
    [m]

    Hi everyone! I hope I might be in the right chat. I'm having some trouble with getting mypy to work correctly on my project.
    It's a Django project with restframework. All the necessary setup (stubs, plugins, etc) is done and works correctly.
    The issue is with another installed module - restframework_simplejwt. This package does not appear to have types configured; I don't even import anything directly, but I assume mypy is checking it because it's in my Django INSTALLED_APPS and the Django plugin probably typechecks those.

    So logically I am getting a Skipping analyzing "rest_framework_simplejwt.token_blacklist.models": module is installed, but missing library stubs or py.typed marker error. This should not be a big deal to fix as I can easily type that single file and make the error go away. The issue is how can I type it in a way that integrates with CI/CD.

    Basically, I created a stub file - but I can't have it inside the package file (that is installed trough pip) - it should be somewhere inside the project structure. Reading the documentation, I should perhaps change the MYPYPATH variable to point to whichever folder has this file (which I assume has to keep the rest_framework_simplejwt/token_blacklist/models.pyi file path?). The problem is that changing the MYPYPATH variable makes the Django plugin stop working (I believe it starts looking for the "app.settings" file from the MYPYPATH).

    Any clue on how I can go about this?

    1 reply
    generalpp
    @generalpp:matrix.org
    [m]

    This brings me to a new question: writting a stub, how can I indicate that something has the type of a class in another file?

    For example, I have the following project structure:

    app
    - foo.py
    - bar.py
    stubs
    - bar.pyi

    The foo.py looks like this

     class Foo:
        pass

    The bar.py look like this:

    from foo import Foo
    foo = Foo()

    The bar.pyi file should look like this:

    from foo import Foo
    foo: Foo

    But that throws an error: Cannot find implementation or library stub for module named "foo"

    5 replies
    Bob Gregory
    @bobthemighty

    Does anyone have resources on the workings of mypy plugins? For my own dark reasons, I want to generate a django model from another object using the type function.

    MyType = type('MyType', (models.Model,),  namespace_mapped_from_some_other_object())
    instance = MyType()

    That works, but I'm trying to get mypy to recognise instance as an instance of the MyType class. From what I can gather, I'm supposed to use a plugin with get_dynamic_class_hook, which fires for the fullname module.MyType, but I'm struggling to make head or tail of the requirements.

    eo
    @eo:ong.ac
    [m]

    not sure where the best place to put this is, but reporting a potential mypy bug:

    given this preamble

    from typing import Union, Dict, Optional, List, TypeAlias, TypeVar
    
    U = TypeVar("U")
    V = TypeVar("V")

    the following code typechecks:

    _TreeNode: TypeAlias = Union[
        Dict[U, "_TreeNode[U, V]"], List["_TreeNode[U, V]"], V
    ]

    but the following code fails with INTERNAL ERROR: maximum semantic analysis iteration count reached:

    _TreeNode: TypeAlias = Union[
        Dict[U, Optional["_TreeNode[U, V]"]], List[Optional["_TreeNode[U, V]"]], V
    ]

    is this a bug, or am I abusing python types?

    1 reply
    Sergei Vorobev
    @vors
    Is there a way to run compiled mypy in a non-compiled mode? (I want to add some debug prints to the python source code)
    EXPLOSION
    @A5rocks
    What do you mean by that?
    • Compile a dev version of mypy?
    • Run your own dev version?
    Rafał Pitoń
    @rafalp
    Hello, is there a workaround for callable protocol with positional args and kwargs?
    This works:
    class Middleware(Protocol):
        def __call__(
            self,
            __next_resolver: Resolver,
            __parent: Any,
            __info: GraphQLResolveInfo,
        ) -> Any:
            ...
    But this doesn't:
    class Middleware(Protocol):
        def __call__(
            self,
            __next_resolver: Resolver,
            __parent: Any,
            __info: GraphQLResolveInfo,
            **kwargs: Any,
        ) -> Any:
            ...
    Alice
    @alicederyn
    I have a Python module that, for unavoidable reasons, generates some code files during install as part of setup.py. Is it possible to run mypy against the post-install module instead of the source code? I know that's suboptimal (e.g. won't integrate nicely with editors).
    1 reply
    Tory Clasen
    @tclasen
    Is it possible to combine mypy strict mode and type inference so that I don't have to be the one to type everything?
    EXPLOSION
    @A5rocks
    You can disable errors codes while remaining in strict mode, if that's what you mean. In theory types should already be inferred, even in strict mode. What are you seeing?
    Tory Clasen
    @tclasen
    I would need to test it to verify, but basically when in strict mode I have to have 100% type hints on both inputs and outputs to functions. With Pylance the output can be inferred based on what is returned and sometimes the input can be inferred based on usage.
    EXPLOSION
    @A5rocks
    Ah you mean type-hinting outputs. Yeah, mypy doesn't infer those. (there's an open feature request about this, python/mypy#10149)
    Amruta Turlapati
    @tamruta

    Hi I'm having sending a file as a parameter to pickle.load. I get this error

    conver_pickle.py:2: error: Argument 1 to "load" has incompatible type "TextIOWrapper"; expected "_ReadableFileobj"  [arg-type]

    While the code is :

        with open(pickle_filename, 'r') as file:
            data = pickle.load(file)    # type: typing.TextIO

    I'm not sure what is going on and why Readable FileObj doesn't cover TextIOWrapper or if I need to add a different hint

    1 reply
    Adrian Garcia Badaracco
    @adriangb
    Does anyone remember where discussion about expanding type annotation sytax to support callables happened? I know for a fact this has been discussed before but I can’t find the discussion (probably buried in typing sig mailing list). To be clear I’m talking about this specific use case: https://mypy-play.net/?mypy=latest&python=3.11&gist=9fb65ea76a0696a877c3bee6132ae430
    1 reply
    gandalfs_cat
    @gandalfs_cat:matrix.org
    [m]
    hello, I have a question (i think) about typeshed; asyncio.create_datagram_endpoint accepts either an (address, port) tuple or a str for its local_addr argument, depending on if the family parameter is set to AF_UNIX or not (at least, since around python 3.7 when the ability to use unix sockets was added to this function). However, this possibility isn't represented in typeshed as far as I can tell: https://github.com/python/typeshed/blob/main/stdlib/asyncio/base_events.pyi#L345
    is there a way to represent the dependence on the family argument? or would it be appropriate to just add str to the union?
    ...or just create an issue and let someone else fix it?
    Kris Harper
    @krispharper

    Hi, I'm wondering if someone can help me figure out the correct types for this series of classes.

    from abc import ABC, abstractmethod
    from typing import TypeVar
    
    T = TypeVar("T", bound="A")
    U = TypeVar("U", bound="ThirdPartyClass")
    
    class ThirdPartyClass:
        """
        This is from a third-party library and I don't control the implementation.
        """
        @classmethod
        def create(cls: type[U]) -> U:
            return cls()
    
    class A(ABC):
        @classmethod
        @abstractmethod
        def f(cls: type[T]) -> T:
            pass
    
    class B(ThirdPartyClass, A):
        @classmethod
        def f(cls) -> T:
            return cls.create()

    Mypy errors on the last two lines with

    error: A function returning TypeVar should receive at least one argument containing the same Typevar

    error: Incompatible return value type (got "B", expected "T")

    Those don't seem right to me, but I don't know how to fix them.

    Vadim Levin
    @VadimLevin

    Good day, I'm trying to provide better type annotations for native library (OpenCV) wrapped in Python package using stub files and facing strange behavior when trying to validate stubs using mypy.stubtest and during package usage.

    Consider the following toy example:
    Package structure:

    . geometry
    |- typing
    |  `- __init__.pyi
    |- geometry.cpython-39-x86_64-linux-gnu.so
    |- __init__.py
    |- __init__.pyi
    `- py.typed

    Stub files have the following content:

    geometry/typing/__init__.pyi

    import geometry
    import typing
    
    Point = tuple[int, int]
    Primitive = geometry.Circle | geometry.Rect
    Primitives = typing.Sequence[Primitive]

    geometry/__init__.pyi

    import geometry.typing
    
    
    class Circle:
        center: geometry.typing.Point
        radius: int
    
        def __init__(self, center: geometry.typing.Point, radius: int): ...
    
    
    class Rect:
        top_left: geometry.typing.Point
        width: int
        height: int
    
        def __init__(self, top_left: geometry.typing.Point, width: int, height: int): ...
    
    
    def calculate_union_area(primitives: geometry.typing.Primitives) -> float: ...

    geometry/__init__.py

    from .geometry import Circle, Rect, calculate_union_area

    Running mypy.stubtest via: python -m mypy.stubtest geometry gives the following output:

    error: not checking stubs due to mypy build errors:
    geometry/__init__.pyi:4: error: Name "geometry.typing.Point" is not defined  [name-defined]
    geometry/__init__.pyi:7: error: Name "geometry.typing.Point" is not defined  [name-defined]
    geometry/__init__.pyi:10: error: Name "geometry.typing.Point" is not defined  [name-defined]
    geometry/__init__.pyi:14: error: Name "geometry.typing.Point" is not defined  [name-defined]
    geometry/__init__.pyi:16: error: Name "geometry.typing.Primitives" is not defined  [name-defined]

    If I try to use types from geometry.typing in external file:

    import geometry
    import geometry.typing
    
    from geometry.typing import Point
    
    
    def foo(pt: Point) -> None:
        print(pt)
    
    foo((1, 2))
    foo(('bar', 31))
    
    def baz(primitives: geometry.typing.Primitives) -> None:
        print(len(primitives))
    
    baz([geometry.Circle([0, 0], 3)), geometry.Rect((1, 2), width=10, height=10)])

    Type hints and autocompletion from pylance and pyright language servers are working as expected.

    Invoking mypy as python -m mypy --strict --follow_imports_for_stubs main.py on above example again gives an error regarding usage of geometry.typing.Primitives annotation: Name "geometry.typing.Primitives" is not defined [name-defined], but resolves Point name and even its type complaining about wrong usage in foo(('bar', 31)).

    Versions:

    • mypy version: 0.991

    • python version: 3.10.9

    NOTE: Changing geometry.typing.__init__.pyi to geometry.typing.__init__.py with

    import typing
    
    if typing.TYPE_CHECKING:
        # same content goes here

    does nothing - errors are still there.

    NOTE: Using from geometry.typing import Name form is not the case, because in the real package there might be name collisions between modules.

    NOTE: Using from geometry.typing import Name as geometry_typing_Name form is not the case too, because it looks ugly and apart from that it is a crutch to resolve possible mypy checker issue.

    So, the question is the following:

    Is there any flag to make mypy happy with such names or it is expected bahvoir or a bug?

    4 replies
    EXPLOSION
    @A5rocks
    So just so that I understand you, your problem is twofold:
    1) stubtest is complaining that these special objects don't exist at runtime (which.... they don't AFAICT? like it seems like it's right, based on what I understand stubtest to be checking)
    2) mypy not figuring out geometry.typing.Primitives which does seem like a bug
    Ah wait I missed your first line of stubtest output. This seems like a basic enough case to be handled, not sure why it's failing.
    Vadim Levin
    @VadimLevin
    1. I thought that stubtest checks that all types and functions accessible in runtime are present in stub files. The actual function (methods) interfaces are kind of out of scope for this check, because, as far as I know, it is impossible to precisely derive function arguments type from native code (e.g. custom conversion rules). If object exists at type checking type it should be totally fine, shouldn't it?
    2. Yep, the main concern that library user won't get warnings from mypy when he/she passes wrong arguments (as pointed in example) when using package-qualified name instead of direct import. This is true for both library and user functions.
    Jonas Krüger Svensson
    @JonasKs
    import httpx
    from pydantic import BaseModel
    
    
    class X(BaseModel):
        abc: list[str]
    
    
    x: str = await httpx.get('someURL').json()['someKey']  # x is now a str
    tunnel_info: dict[str, X | None]
    tunnel_info[x] = None
    if tunnel_info[x] is None:
        tunnel_info[x] = X(abc=['hello'])
        tunnel_info[x].abc.append('jonas')
    This raises error: Item "None" of "Optional[X]" has no attribute "abc" [union-attr].
    Can anyone explain why? This example[1] seems pretty similar..
    https://mypy.readthedocs.io/en/stable/common_issues.html#narrowing-and-inner-functions
    Jonas Krüger Svensson
    @JonasKs

    The workaround is to create a separate variable:

    this_tunnel = X(abc=['hello'])
    this_tunnel.abc.append('jonas')
    tunnel_info[x] = this_tunnel

    The code does the same, but with more lines, forced by mypy :P

    Phil-Barber
    @Phil-Barber

    I'm getting a bit confused with some TypeVar stuff that I'm finding hard to give a headline summary of.
    I have a TypeVar("Var", A, B) and a function with argument some_var: Type[Var] Being called with an argument that is Type[A] | Type[B] and mypy is not happy.

    After playing around a bit I'm unsure if there are 2 separate issues related to whether I'm using bound or not, and also whether I'm using Type or not, OR whether I've got a more fundamental misunderstanding of whats going on.
    Here's the mypy-play which hopefully makes things clearer
    https://mypy-play.net/?mypy=latest&python=3.11&gist=664ac4f67d5887022fa879d6478a0952

    Jonas Krüger Svensson
    @JonasKs
    @me above: This seems to answer the question: https://github.com/python/mypy/issues/14164#issuecomment-1323889537
    Piotr Lobacz
    @Dvergatal

    Hi all, I'm having a code like this:

    from typing import Iterable, TypeVar, Generic
    from multimethod import multimethod
    from abc import ABC
    from types import GenericAlias
    
    
    T = TypeVar("T")
    class MyIterable(ABC, Generic[T]):
        @classmethod
        def __subclasshook__(cls, subclass):
            return issubclass(subclass, Iterable) and not issubclass(subclass, str)
    
        def __class_getitem__(cls, key):
            return GenericAlias(cls, key)
    
    
    @multimethod
    def validate_enum_list(key: str, value: str, allowed_values: MyIterable[str]) -> None:
        print("key: str, value: str, allowed_values: MyIterable[str]")
        print(type(value))
        print(type(allowed_values))
    
    @validate_enum_list.register
    def _(key: str, value: MyIterable[str], allowed_values: MyIterable[MyIterable[str]]) -> None:
        print("key: str, value: List[str], allowed_values: MyIterable[MyIterable[str]]")
        print(type(value))
        print(type(allowed_values))
    
        value = sorted(value)
        allowed_values = sorted([sorted(item) for item in allowed_values]) 
    
    validate_enum_list("test1", "test1", ["test1"])
    validate_enum_list("test2", ["test2"], [["test2"]])
    validate_enum_list("test1", "test1", [["test1"]])

    and the problem with mypy is that it returns me this errors:

    multi2.py:29: error: No overload variant of "sorted" matches argument type "MyIterable[str]"  [call-overload]
    multi2.py:29: note: Possible overload variants:
    multi2.py:29: note:     def [SupportsRichComparisonT] sorted(Iterable[SupportsRichComparisonT], /, *, key: None = ..., reverse: bool = ...) -> List[SupportsRichComparisonT]
    multi2.py:29: note:     def [_T] sorted(Iterable[_T], /, *, key: Callable[[_T], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]], reverse: bool = ...) -> List[_T]
    multi2.py:30: error: Incompatible types in assignment (expression has type "List[List[Any]]", variable has type "MyIterable[MyIterable[str]]")  [assignment]
    multi2.py:30: error: "MyIterable[MyIterable[str]]" has no attribute "__iter__" (not iterable)  [attr-defined]
    Found 3 errors in 1 file (checked 1 source file)

    So am I suppoused to overload sorted method with MyIterable? Shouldn't It be working automatically? Another thing is why mypy is complaining about __iter__ if MyIterable has defined __class_getitem__?

    headtrick
    @headtrick:matrix.org
    [m]
    @Dvergatal in oder to be iterable your class needs to define __iter__. Then sorted should also work.
    Piotr Lobacz
    @Dvergatal
    @headtrick:matrix.org OK so I shall define this __iter__ and what the implementation of it should look like? I wanted to have it for generic iterable type. Btw. wouldn't it be better if I changed inheritance from ABC to Iterable?
    Liam Clarke-Hutchinson
    @LiamClarkeNZ
    Kia ora all, I've just hit an interesting issue when using --disallow-any-expr in that mypy (version 0.971) resolves this strictly local variable to Any but, well, it was just assigned a known type. I can't find anything about this in the docs for the above option. Is this working as intended?
        def test_header_values_properly_converted_to_str(self, _: MockedEntity):
            f = CdcMessageFixtures(self)
    tests/processors/messages/test_cdc_message.py:66: error: Expression has type "Any"  [misc]
                f = CdcMessageFixtures(self)
    Phil-Barber
    @Phil-Barber
    Is anyone able to help explain this for me please?
    https://mypy-play.net/?mypy=latest&python=3.11&gist=2435d36bbca03f698a3775f114b5e251
    import typing as t
    class A:
        a = 1
    
    class B:
        a = 2
    
    VarBound = t.TypeVar('VarBound', bound=A | B)
    
    def init_bound_type(var: t.Type[VarBound]) -> VarBound:
        return var()  # error: Incompatible return value type (got "Union[A, B]", expected "VarBound")
    
    VarExact = t.TypeVar('VarExact', A, B)
    
    def init_exact_type(var: t.Type[VarExact]) -> VarExact:
        return var()
    headtrick
    @headtrick:matrix.org
    [m]
    @LiamClarkeNZ: where is CdcMessageFixtures defined? If it is from a third party module without typing it will be imported as Any
    2 replies
    Piotr Lobacz
    @Dvergatal

    Hi all, I'm having a code like this:

    from typing import Iterable, TypeVar, Generic
    from multimethod import multimethod
    from abc import ABC
    from types import GenericAlias
    
    
    T = TypeVar("T")
    class MyIterable(ABC, Generic[T]):
        @classmethod
        def __subclasshook__(cls, subclass):
            return issubclass(subclass, Iterable) and not issubclass(subclass, str)
    
        def __class_getitem__(cls, key):
            return GenericAlias(cls, key)
    
    
    @multimethod
    def validate_enum_list(key: str, value: str, allowed_values: MyIterable[str]) -> None:
        print("key: str, value: str, allowed_values: MyIterable[str]")
        print(type(value))
        print(type(allowed_values))
    
    @validate_enum_list.register
    def _(key: str, value: MyIterable[str], allowed_values: MyIterable[MyIterable[str]]) -> None:
        print("key: str, value: List[str], allowed_values: MyIterable[MyIterable[str]]")
        print(type(value))
        print(type(allowed_values))
    
        value = sorted(value)
        allowed_values = sorted([sorted(item) for item in allowed_values]) 
    
    validate_enum_list("test1", "test1", ["test1"])
    validate_enum_list("test2", ["test2"], [["test2"]])
    validate_enum_list("test1", "test1", [["test1"]])

    and the problem with mypy is that it returns me this errors:

    multi2.py:29: error: No overload variant of "sorted" matches argument type "MyIterable[str]"  [call-overload]
    multi2.py:29: note: Possible overload variants:
    multi2.py:29: note:     def [SupportsRichComparisonT] sorted(Iterable[SupportsRichComparisonT], /, *, key: None = ..., reverse: bool = ...) -> List[SupportsRichComparisonT]
    multi2.py:29: note:     def [_T] sorted(Iterable[_T], /, *, key: Callable[[_T], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]], reverse: bool = ...) -> List[_T]
    multi2.py:30: error: Incompatible types in assignment (expression has type "List[List[Any]]", variable has type "MyIterable[MyIterable[str]]")  [assignment]
    multi2.py:30: error: "MyIterable[MyIterable[str]]" has no attribute "__iter__" (not iterable)  [attr-defined]
    Found 3 errors in 1 file (checked 1 source file)

    So am I suppoused to overload sorted method with MyIterable? Shouldn't It be working automatically? Another thing is why mypy is complaining about __iter__ if MyIterable has defined __class_getitem__?

    I have few more questions if I'm having additional functions which are calling validate_enum_list e.g.:

    def get_enum_str(key: str, value: str, allowed_values: MyIterable[str]) -> None:
        validate_enum_list(key, value, allowed_values)
        print("get_enum_str")
    
    def get_enum_str_list(key: str, value: MyIterable[str], allowed_values: MyIterable[MyIterable[str]]) -> None:
        validate_enum_list(key, value, allowed_values)
    
    get_enum_str("test1", "test1", ["test1"])
    get_enum_str_list("test2", ["test2"], [["test2"]])
    get_enum_str_list("test2", ["test2"], [["test2", "tkip", "ccmp"]])

    I'm getting this mypy errors:

    multi2.py:51: error: Argument 3 to "get_enum_str" has incompatible type "List[str]"; expected "MyIterable[str]"  [arg-type]
    multi2.py:52: error: Argument 2 to "get_enum_str_list" has incompatible type "List[str]"; expected "MyIterable[str]"  [arg-type]
    multi2.py:52: error: Argument 3 to "get_enum_str_list" has incompatible type "List[List[str]]"; expected "MyIterable[MyIterable[str]]"  [arg-type]
    multi2.py:53: error: Argument 2 to "get_enum_str_list" has incompatible type "List[str]"; expected "MyIterable[str]"  [arg-type]
    multi2.py:53: error: Argument 3 to "get_enum_str_list" has incompatible type "List[List[str]]"; expected "MyIterable[MyIterable[str]]"  [arg-type]

    Does anyone know how may I solve that mypy could verify statically that MyIterable[str] is any type of Iterable without str?

    Piotr Lobacz
    @Dvergatal
    Ahhh OK I have finally found python/mypy#11001 this is a common problem with python
    Travis Hesketh
    @thesketh

    Hey folks, I'm new here, just wondering if what I'm seeing is a bug in mypy or a bug in my understanding.

    I've got a function that returns a tuple containing a bool as the first element and, if that bool is True, an int as the second element . If the bool is False, the second position is None instead.

    The naive type for that would be something like tuple[bool, Optional[int]], but that's not strictly correct: it's more like Union[tuple[Literal[True], int], tuple[Literal[False], None]]. When I try using the latter type, though, mypy seems to break it down into the former.

    I've got a minimal example here which shows this:

    import random
    from typing import Literal, Union
    
    
    def check_type_variant() -> Union[
        tuple[Literal[True], int], tuple[Literal[False], None]
    ]:
        if random.random() > 0.5:
            return True, 1
        return False, None
    
    
    is_int, maybe_int = check_type_variant()
    if is_int:
        maybe_int += 1

    and mypy produces the following output:

    example.py:15: error: Unsupported operand types for + ("None" and "int")  [operator]
    example.py:15: note: Left operand is of type "Optional[int]"
    Found 1 error in 1 file (checked 1 source file)
    headtrick
    @headtrick:matrix.org
    [m]
    @thesketh: python and mypy don't have dependent types, so is_int will be mapped into bool, and maybe_int into int | None.
    If you want to keep this dependency you cannot unpack these values. You can use:
    res=check_type_variant() 
    if res[0]:
        ...
    1 reply
    George Sakkis
    @gsakkis
    Hi all, the following snippet gives Incompatible return value type (got "int", expected "slice"). Is there a way to make it type check?
    from typing import TypeVar, Union
    
    Idx = TypeVar("Idx", int, slice)
    # Idx = Union[int, slice]
    
    
    def incr(obj: Idx, delta: int) -> Idx:
        if isinstance(obj, int):
            return obj + delta
        else:
            return slice(obj.start + delta, obj.stop + delta)
    
    
    def negate(i: int) -> int:
        return -i
    
    
    def reverse(s: slice) -> slice:
        return slice(s.stop - 1, s.start - 1, -1)
    
    
    def test() -> None:
        negate(incr(5, 3))
        reverse(incr(slice(5, 10), 3))
    3 replies
    Peterl777
    @Peterl777

    According to PEP 673 this code should work:

    from typing import Self
    
    class Shape:
        def difference(self: Self, other: Self) -> float:
            return 0

    "Note that specifying self: Self is harmless, so some users may find it more readable to write" as above.

    But I'm getting the error:

    testTypeHintingSelf.py:4: error: Variable "typing.Self" is not valid as a type  [valid-type]
            def difference(self: Self, other: Self) -> float:
                                 ^
    testTypeHintingSelf.py:4: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
    Found 1 error in 1 file (checked 1 source file)

    Am I doing something wrong, or is mypy not checking Self correctly?
    (I understand the first Self is not needed, but according to the PEP it should be allowed, and I like it for consistency).
    (I'm running Python 3.11.1 on Windows with mypy 0.991)

    4 replies
    TheMythologist
    @TheMythologist

    Hi, I get the following error (no-redef) when running mypy against this code snippet:

    import json
    import os
    
    
    class A:
        def __init__(self, file: str = "file.json"):
            if os.path.isfile(file):
                with open(file, 'r') as f:
                    self.data: dict = json.load(f)
            else:
                self.data: dict = {"random_data": "asdf"}

    Received error message:

    script.py:11: error: Attribute "data" already defined on line 9  [no-redef]
    Found 1 error in 1 file (checked 1 source file)

    Can anyone else confirm if this is a bug?

    Callek
    @jwood:mozilla.org
    [m]
    Try, right above the if: self.data: dict and then remove the type hint on both assignment lines
    TheMythologist
    @TheMythologist
    Ahh I see, that works.
    Thanks :)
    George Sakkis
    @gsakkis
    Follow-up to my previous question: can someone explain the different behavior between TypeVar("IntOrStr", int, str) and TypeVar("IntOrSlice", int, slice) at https://mypy-play.net/?mypy=latest&python=3.11&gist=71d1dd4d4d02e5427cc55a4d6e573280? Why does the second may have <subclass of "slice" and "int"> revealed type but the first one doesn't? By the way at runtime both attempts to extend from these two pairs of classes raise TypeError:
    In [6]: class IntOrStr(int, str):
       ...:     pass
    
    TypeError: multiple bases have instance lay-out conflict
    
    In [7]: class IntOrSlice(int, slice):
       ...:     pass
    
    TypeError: type 'slice' is not an acceptable base type
    Alice
    @alicederyn

    I want to import an enum from an optional dependency, but fall back to a local declaration of a matching type if the optional dependency isn't installed.

    try:
      from foo import SomeEnum
    except ImportError:
      class SomeEnum(Enum):
        ...

    I can't find a way to make mypy happy with this.