shabbyrobe / grpc-stubs

gRPC typing stubs for Python
MIT License
35 stars 21 forks source link

Consider using pytest-mypy-plugins #1

Closed sobolevn closed 4 years ago

sobolevn commented 5 years ago

Hi! Thanks for this awesome project!

I am TypedDjango team member, we maintain types for, well, django. And we do pretty much the same job.

For example, we test our types like so: tests/. We even created a tool called pytest-mypy-plugins (announcing post) to help us with this task. Maybe it will be also helpful to you as well.

That's how the simplest test looks like:

- case: compose_two_wrong_functions
  main: |
    from returns.functions import compose

    def first(num: int) -> float:
        return float(num)

    def second(num: float) -> str:
        return str(num)

    reveal_type(compose(first, second)(1))  # N: builtins.str*

Ask any questions you have!

P.S. This project was listed in awesome-python-stubs list.

shabbyrobe commented 5 years ago

Hello! Thanks so much for reaching out. That testing stuff looks great, I'll definitely look to getting it integrated with this. It's still early days for me with typed python so I'm likely to make a few more egregious errors before I find an equilibrium... maybe I'm not quite across the fine details of writing typing stubs for them to be fit for public consumption yet so I'm grateful for your support. Hopefully I don't break too many people's builds as I learn my way around.

Also, I was not aware of awesome-python-stubs, so thank you also for the link.

sobolevn commented 5 years ago

@shabbyrobe awesome! Thanks 🙂

Feel free to reach out in case you need any help!

shabbyrobe commented 5 years ago

That went in really easily. The instructions in your blog post were super clear. I'll work on adding more cases over time; at least I know now I have a good way to prevent further regressions. Thanks again!

shabbyrobe commented 5 years ago

It has only been 10 minutes, I only have 2 test cases, and I already flushed out a bug. Pretty quick payoff here! 👍

shabbyrobe commented 4 years ago

Hi @sobolevn; I hope you don't mind me "@"-ing you, but I'm having some trouble with pytest-mypy-plugins in this project; it doesn't appear to actually be loading the stubs when I run pytest. It reports the types are all Any and if I fill the stub files with junk it doesn't fail with syntax errors. I figure I'm doing something silly while sewing it together but I just can't seem to find the magic incantation

sobolevn commented 4 years ago

@shabbyrobe no problem, I am at your service 🙂

Can you please show me the code?

shabbyrobe commented 4 years ago

Sure! Thank you!

The issue is the grpc_channel_context_manager test in test_grpc.yml:

- case: grpc_channel_context_manager
  main: |
    from grpc import Channel
    reveal_type(Channel())  # N: Revealed type is 'Channel'

When I try to run it (pytest --mypy-ini-file=setup.cfg), I get the following error, which indicates the stubs aren't loading at all:

/home/bl/code/py/grpc-stubs/typesafety/test_grpc.yml:5:
E   pytest_mypy.utils.TypecheckAssertionError: Invalid output:
E   Expected:
E     main:3: note: Revealed type is 'Channel'      (diff)
E   Actual:
E     main:3: note: Revealed type is 'Any'          (diff)
E
E   Alignment of first line difference:
E     E: ...te: Revealed type is 'Channel'
E     A: ...te: Revealed type is 'Any'
E                                 ^
sobolevn commented 4 years ago

My wild guess is that mypy cannot find your stub files for some reason. Things to try:

  1. Make sure that your stubs are found by setuptools: https://github.com/typeddjango/django-stubs/blob/master/setup.py#L43 Docs on module resolution: https://www.python.org/dev/peps/pep-0561/#type-checker-module-resolution-order
  2. Make sure that PYTHONPATH is set correctly on your system

You can have a look at the fully-working example here: https://github.com/typeddjango/django-stubs/tree/master/test-data It also works with stubs.

shabbyrobe commented 4 years ago

Thanks for getting back to me so quickly!

I've just confirmed your theory - I edited __init__.pyi, added a whole bunch of unparseable junk, and the output was the same; the same failed test, the same error message.

I'm using I think the exact same find_stub_files function in my setup.py (probably copy-pasted from django-stubs); I checked it and the output is what I expect: {'grpc-stubs': ['__init__.pyi'], 'grpc_status-stubs': ['__init__.pyi', 'rpc_status.pyi']}

PYTHONPATH is not set, but I'm in a virtualenv.

shabbyrobe commented 4 years ago

Oh no! It's so obvious now, as soon as I type the word virtualenv... I must be using a globally installed pytest, I mustn't've installed it in the venv...

Just checked, that was indeed it. I'm so sorry to waste your time on something so silly!

sobolevn commented 4 years ago

Hm, will regular mypy calls work? Like so:

# ./ex.py
from grpc import Channel
reveal_type(Channel())

And then mypy ex.py

sobolevn commented 4 years ago

@shabbyrobe no problem! Glad that it worked! 👍

shabbyrobe commented 4 years ago

Now that it's all working and sorted, I'll close this issue as solved. Thank you again for your help, and for the recommendation for the package too!