Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
    Torin Tung Kwok

    Hello the community,

    I just posted a question on StackOverflow: Generic types lose their Generic[T, …] base class in the .pyi file generated by stubgen. And I pasted the question here and any hint would be appreciated. :-)

    Let's say here is a very simple class that represents a generic stack and hence is inherited from Generic[T] (§1).

    from typing import TypeVar, Generic, List
    T = TypeVar('T')
    class Stack(Generic[T]): #1
        def __init__(self) -> None:
            self.items: List[T] = []
        def push(self, item: T) -> None:
        def pop(self) -> T:
            return self.items.pop()
        def empty(self) -> bool:
            return not self.items

    And then let's generate a stub file .pyi for the module in which the Stack class lies, say, stack.py:

    $ stubgen stack.py --output stubs

    It's obvious that the Generic[T] base class was unexpectedly stripped off (§2). Meanwhile, the type hint for the items property was replaced as Any (§3). Additionally, what makes things more weird is that the stubbed versions of both push and pop still bore the type hint T for the parameter and the return value respectively (§4 and §5).

    from typing import Any, TypeVar
    T = TypeVar('T')
    class Stack: #2
        items: Any = ... #3
        def __init__(self) -> None: ...
        def push(self, item: T) -> None: ... #4
        def pop(self) -> T: ... #5
        def empty(self) -> bool: ...

    What happened during the generation of the stub? Is there any explanation to justify such a behavior?

    P.S. My mypy version is 0.790.

    Thomas Grainger
    @torinkwok why are you stubgenning an annotated .py?
    I have a method that accepts one argument typed as List[Union[str, int, float, bool]], however when I use it with an argument typed as List[str] I get the following errors:
    Argument "literal" to "LITERAL" of "ATTR" has incompatible type "List[str]"; expected "List[Union[str, int, float, bool]]"mypy(error)
    "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variancemypy(note)
    Consider using "Sequence" instead, which is covariantmypy(note)
    1 reply
    Bryan Fordney
    In mypy is anyone aware of a way to make it "assume" certain custom built-ins? I would like to use it to type-check some scripts for VFX applications (Nuke, Blender, etc) which have their own built-in functions and objects. I'd like to see if I can write stubs for those, but I also would need mypy to "assume" that they have already been imported.
    For example in Blackmagic Fusion there is an object called fusion which does not need to be imported in your scripts; I need mypy to know that it's already available without being explicitly imported.
    Vito De Tullio

    can I define a type as the result value of a function?
    I am in this situation: I am using a library that "do stuff" on import. A way to "shut it" is to define an environmental variable before, and I want to do it specifically during the run of the unit tests.
    I was thinking to factor it in a importlib.import_module "wrapper", so I would have

    from package.module import Class
    def foo(obj: Class) -> None: ...

    in "normal" normal code, and

    from testsupport import my_import_function
    Class = my_import_function('package.module', 'Class') # this will internally do the "import dance"
    def mock_class_obj() -> Class:
        mock_class_obj = unittest.mock.create_autospec(spec=Class, instance=True)
        # set up behavior...
       return mock_class_obj

    unfortunately I don't get how to write the my_import_function return type... I was thinking something like

    def my_import_function(name: str, class_name: str) -> typing.Type[typing.Any]:
        module = importlib.import_module(name, package)
        return typing.cast(typing.Type[typing.Any], getattr(module, class_name))

    and "it works", but then I have the error error: Variable "mocks.C" is not valid as a type at the signature of mock_class_obj

    2 replies
    Which editor is best for python, pygame
    I prefer VSCode, but I have seen many prefer vim, or Emacs, or PyCharm, or .... <etc> - It mostly comes down to what you prefer than anything else

    Hey there. Question about Python typechecking: what tool should I use to check the types of classes with dynamically created methods?

    Let us say we have a Client class that is dynamically created with methods like this:

    >>> client = Client(open_api_spec)
    # Dynamically created method with dynamically added annotations
    >>> client.get_example.__annotations__
    {'return': MySchemaClass}

    What tool should I use to analyse my code?

    I could possibly solve this using code generation, where I would create a Client class with all of the methods and annotations as part of a pre-build step.

    But code generation is a can of worms.

    Daniel J. Beutel
    Hi everyone, we've come across a mypy error that shouldn't be an error AFAICT. Shouldn't a function returning a Dict[str, str] be compatible with an argument that expects a function returning a Dict[str, Union[str, int]? Here's the full code example:
    from typing import Callable, Dict, Union
    class Foo:
        def __init__(self, bar_fn: Callable[[int], Dict[str, Union[str, int]]]):
            self.bar_fn = bar_fn
        def get_dict(self) -> Dict[str, Union[str, int]]:
            return self.bar_fn(1)
    def fn_1(x: int) -> Dict[str, Union[str, int]]:
        return {"key1": "value1", "key2": 2}
    Foo(bar_fn=fn_1)  # This works
    def fn_2(x: int) -> Dict[str, str]:
        return {"key": "value"}
    Foo(bar_fn=fn_2)  # This raises the following mypy error:
    # [filename].py:23: error: Argument "bar_fn" to "Foo" has incompatible type "Callable[[int], Dict[str, str]]"; expected "Callable[[int], Dict[str, Union[str, int]]]"
    4 replies
    Kyle Altendorf
    i'm looking at trying to catch cases where trio has a parameter defaulted to None and trio-stubs doesn't have that parameter hinted as Optional. https://github.com/python-trio/trio/blob/d203b30f807e43dc9b101de2e52355ebd10b757a/trio/_core/_run.py#L1942 -- https://github.com/python-trio/trio-typing/blob/f32f17b0f242daf2d42407f383ca581d64b6c299/trio-stubs/lowlevel.pyi#L97 i guessed that maybe stubtest would catch this, but it doesn't seem to. is there another approach i should use to find similar cases? or perhaps there is a reason this "can't" be done?
    Kyle Altendorf
    @ignormies:matrix.org that's the idea, yeah, but this is checking separate stubs, not a program using the trio library. in fact, having that and running mypy against qtrio which uses trio is exactly what turned this up. i haven't figured out how to get that to be enforced against the combination of package and stubs.

    trio has a parameter defaulted to None and trio-stubs doesn't have that parameter hinted as Optional

    In this context, would the problem be in trio, or in trio-stubs?

    Kyle Altendorf
    @ignormies:matrix.org trio-stubs. it ought to have clock: typing.Optional[trio.abc.Clock] = ...,
    but just reporting the discrepancy would leave me a chance to pick which to change. so for the goal of catching this scenario, it doesn't matter which is wrong, i think.
    How can I trace a possible bug where class attribute with name defaults would lose its typing when used in inherited class? This only applies to an attribute with the name defaults.

    Hey there, how can I dissable the mypyc compilation when using the mypy command line?

    I'm trying to do some debugging of the source code, and I don't need it compiled. I just want to step through the code.

    4 replies
    Never mind, figured it out
    Bryan Forbes
    @hauntsaninja I noticed that X as X is only re-exported for stubs… what happens in regular modules?
    It’s not really clear in the mypy release note blog post
    Kyle Altendorf
    So is it just not possible?
    Kyle Altendorf
    @hauntsaninja should stubtest check the package and the stubs against each other when it comes to implicit optional hints? context is 9 messages up, but trio has a parameter =None and the stubs have : trio.abc.Clock = .... seems like it would be good to have some tool or another able to find this discrepancy.
    Is anyone here familiar with writting plugins for mypy?
    I'm trying to dynamically add a method to ca ClassDef in a plugin hook.
    What I can't work out is: how to construct new Function definitions.
    Because those function definitions need types in their args.
    But I don't know how to get arbitrary types
    I know this is a really dumb question, but how can I construct mypy.nodes.Var objects?
    And mypy.nodes.TypeInfo
    This message was deleted
    Sorry for thinking outloud
    I think lookup_fully_qualified is what I need.
    It'd be nice if there was autodocumentation for the plugin api
    6 replies
    Henry Schreiner
    :heart: MyPy 0.800 :heart:
    @freundTech thanks for your help. I've actually managed to do something pretty cool with it.
    Basically, I was getting really annoyed with how a lot of python web developers just do ad hoc interfaces between services. And I wanted to see if I could create a metaprogrammed OpenAPI client; but one where I could also use MyPy to verify you are using the API correctly.
    @bryanforbes agreed that the blog post is a little confusingly worded. PEP 484 was amended to say that only import X as X counts as an explicit re-export, not import X as Y. What happens in regular .py files depends on whether or not you have --implicit-reexport or not
    Bryan Forbes
    Thanks! If the import X as X is included in __all__ in a regular .py file, will it be exported?
    yeah, symbols in __all__ should be exported
    @altendky stubtest does check that default values are a subtype of the arg's type hint
    maybe the issue is that your stub is decorated?
    Bryan Forbes
    @hauntsaninja thanks!
    Kyle Altendorf
    @hauntsaninja the stub uses ... for the default. it seems like the package default isn't checked against the stub hint. or at least isn't enforcing no implicit optional
    @altendky can you remove the decorator and try?
    Kyle Altendorf
    @hauntsaninja i tried removing it and it didn't seem to make a difference. it sounds like you expect it ought to be caught so i'll make up a minimal example to try to confirm expectations and outcome. thanks.
    Kyle Altendorf
    @hauntsaninja https://gist.github.com/altendky/3327ab219a04e27f628b92aa6c480d8a here's the minimal example. i can certainly file a ticket if you think it is appropriate.
    also, this isn't a pressing issue. at this point i'm starting to just merge the stubs into the package so this is relevant primarily in the context of just improving (i think? :]) stubtest.