Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type information to API #368

Open
Kriechi opened this issue Oct 27, 2016 · 8 comments
Open

Add type information to API #368

Kriechi opened this issue Oct 27, 2016 · 8 comments

Comments

@Kriechi
Copy link
Member

Kriechi commented Oct 27, 2016

Due to small type inconsistencies one might fall into a trap where incompatible objects might still be auto-mangled into something that fits, but isn't right. One example of such a case just happened: ref #367. The docs clearly stated one thing, but passing in something completely different still worked, until the the last release. The public API was still the same, but the underlying implementation changed.

How do you feel about adding type checks, type hints, or similar annotations to help the user avoid such mistakes?

E.g.:
http://mypy-lang.org/
https://www.python.org/dev/peps/pep-0484/
https://docs.python.org/3/library/typing.html
and similar

I think, since python-hyper aims for Python 2 support as well, this might be a bit more difficult.

@Lukasa
Copy link
Member

Lukasa commented Oct 27, 2016

I would be totally happy to add type hints, beginning at least with the public API. In fact, most of the public API defines its expected types already using the magic Sphinx docstrings, so we're not that far from being able to do it.

However, you're right that the Python 2 compat requirement makes this more tricky. What we need is something that can satisfy the following rules:

  • Can be enforced by the CI. I'd like the CI to be able to tell us if we totally screwed up the type declarations.
  • Work with Python 2 and Python 3
  • Ideally are inline so that it's easier for contributors to remember that they need to be updated
  • Can be extracted into Sphinx

I'm not yet sure if there are any type annotation systems that cover all those bases. We should take a look.

@alexwlchan
Copy link
Contributor

I have yet to try it in anger, but I think (based on a few conversations at PyCon) that MyPy would get us part of the way.

I don’t think it can do the Sphinx-extraction (yet, I know the idea’s been floated), but I think it can do the other stuff.

@Lukasa
Copy link
Member

Lukasa commented Oct 27, 2016

Yeah, so I assume that mypy would be the type checker to use. The biggest issue is: how do we convince Sphinx to use the types so that we don't have to duplicate them.

@Lukasa
Copy link
Member

Lukasa commented Oct 27, 2016

I'm somewhat nervously considering the possibility that "write a Sphinx plugin" may be the actual solution to this problem, and wow do I not want that to be the solution.

@alexwlchan
Copy link
Contributor

ponders

I'm somewhat nervously considering the possibility that "write a Sphinx plugin" may be the actual solution to this problem, and wow do I not want that to be the solution.

I thought the same thing, but I also think “write a Sphinx plugin” might be a fun and useful challenge. (I also got about two hours of sleep last night, so my judgement may be a little suspect.)

I’ve never written a Sphinx plugin, so I have no idea how hard it would be; I’ll look at it properly when I get some free time at the weekend.

@Lukasa
Copy link
Member

Lukasa commented Oct 27, 2016

So I know there is a Sphinx plugin to get types out of function annotations, so such a thing is clearly possible, in the abstract sense.

@Lukasa
Copy link
Member

Lukasa commented Oct 27, 2016

@jonparrott has mentioned that he's worked on something related that might be adaptable to our use-case.

@theacodes
Copy link

theacodes commented Oct 27, 2016

sphinx-docstring-typing seems to take a different approach than you guys are wanting here. Some context - I wrote it for the new google-auth-library-python. I wanted us to be able to express our arguments and return types using pep 484 / typing. I looked into the approach you guys are talking about here (using mypy annotations and then convincing sphinx/autodoc to pick them up) - but there was seemingly a lot of complexity around doing that and I already have to deal with writing an auth library. I also had to deal with pylint.

In summary - for Python 2:

  1. Pylint expects docstrings to contain type declarations for arguments and returns - so the types must be in the docstring, or you have to disable this feature ☹️ .
  2. Sphinx will format typing-style stuff (e.g. Mapping[str, int]) completely wrong unless you do some crazy stuff.
  3. Mypy won't pick-up the types in docstrings, it requires them to be in a comment after the function's definition. Of course, sphinx and pylint won't recognize this.

I ended up tabling (3) for the time being, and just fixing (2). That's what sphinx-docstring-typing does - it transforms any typing-style annotations into rst with proper cross-linking. See here for an example (and here if you want to see it without).

So - this might be useful to you guys in a few ways:

  1. Use sphinx-docstring typing and use typing-style types in your docstrings and provide stubs for mypy checking. You could and probably should generate the stubs from the docstring without much fuss.
  2. Use sphinx-docstring typing and use typing-style types in your docstrings and add the mypy-style comment. Again you could and probably should generate one or the other.
  3. You can forgo specifying types in your docstrings altogether (like a python3-only project could do) and try to figure out how to get sphinx to acknowledge your mypy comment. (this was the one I looked into and decided it wasn't worth my time).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants