urschrei / pyzotero

Pyzotero: a Python client for the Zotero API
https://pyzotero.readthedocs.org
Other
908 stars 99 forks source link

Feature Suggestion/Discussion: Type Annotations ( PEP484 and related) #110

Open fmagin opened 4 years ago

fmagin commented 4 years ago

This is not an issue and not even a feature request in and of it self:

Python 2 is deprecated now which means that the full range of Python 3 type annotations can be used. This serves as indirect documentation, makes the API easier to understand and allows dynamic environments like IPython to offer better and more intuitive suggestions which would be useful for features like #92

The core question is: Under which constraints would type annotations be welcome?

Some possible constraints are supported Python Versions and technically if inline vs separate .pyi vs -stub package is preferred[0]. They can be added incrementally, so just annotation some basic types and encouraging pull requests to add annotations to new features or existing code already goes a long way.

If they are welcome and I end up using this project for my own scripts I can probably cover the basic annotations.

[0] IMO the only sensible option with Python 2 being deprecated is inline annotations that are supported in the minimum Python 3 version that the project wants to support.

urschrei commented 4 years ago

To be honest, I haven't used type annotations yet, so I haven't given any thought to their applicability here. A difficulty is that even though Python 2 is deprecated, it's not clear to me that all users of Pyzotero have switched to Python 3 (and it's all but impossible to know this with any degree of certainty). I don't envisage dropping Python 2 support in 2020, and inline type annotations would only be part of the reason for doing so.

fmagin commented 4 years ago

One practical example that I ran into: zot.items has Get user items as a docstring. zot.children states Get a specific item's child items.

The naive assumption someone might have (I had it as a first thought) is that zot.items returns a a list of those "items" and zot.children takes on as an argument. Which is in fact wrong (though it could be done with some dynamic checking).

Here it would be useful to codify the signatures are zot.items(**kwargs) -> List[Item] and zot.children(item: ItemID, **kwargs) -> List[Item].

ItemID can just be a string with a special meaning (that it is an ItemID), the feature is explained here https://docs.python.org/3/library/typing.html#newtype.

This would already make it clear that ItemID and Item are distinct concepts. Item can be either just a Dict[str, Any] or to refine it further something like TypedDict which can be used to specify that key in an Item is of type ItemID

In my personal opinion, which I am aware of doesn't mean much in a project I have barely contributed to, is that this (or anything really) is a good enough reason to drop Python 2 support in 2020. You could still start a Python 2 branch that gets critical fixes but doesn't get new features that are easier or only possible to implement in Python 3 only code.

If people are using pyzotero via PyPI I think you can even have separate packages IIRC, so pip install pyzotero in a python2 env gets the python2 branch, while a python3 gets the regular release branch (which is probably just a tag on master?).

I have done initial work for type annotations for some projects and am using them in all my private projects.

If I end up using this project for some private stuff (mostly taskwarrior/GTD system integration) I will probably end up with a fork with annotations anyway. The question is more what your preferences are so I can accommodate them while writing instead of fixing things after submitting the PR.