lanl / pyxDamerauLevenshtein

pyxDamerauLevenshtein implements the Damerau-Levenshtein (DL) edit distance algorithm for Python in Cython for high performance.
BSD 3-Clause "New" or "Revised" License
243 stars 31 forks source link

PEP561 type stubs for mypy #31

Closed xzy3 closed 1 year ago

xzy3 commented 2 years ago

I've written the needed pyi files to type the library. It looks like it would take some pretty big changes to the package structure to make it work with side by side stubs. Would you prefer I keep trying to get it to work side by side? I can also make a stub-only package and give it to you to upload separately? Or would you prefer something else?

gfairchild commented 2 years ago

Thanks for your patience!

I admittedly have never heard of mypy before. I'm familiar with Python's built-in typing. Can you give me a brief rundown of what all your proposed changes entail, perhaps with some examples?

xzy3 commented 2 years ago

Mypy is one of the static type checkers that use the type annotations. All I did was create the pyi typing stubs which describe an interface's types. Sort of like a C header file. The pyi files are mainly for backporting types into older packages. But since none of the type-checkers do analysis of Cython code directly they are also useful for providing typing information in that case. There's two ways to distribute the pyi files. You can put them in the installed files alongside python code in the same project. The second is to upload a second package to pypi that has the same name but adds "-stubs" to the end. The type checkers can find those packages and will download them to have the type information available.

Getting setuptools to do the side by side installation of pyi files and extension modules isn't obvious. I really don't think I did it correctly. Normally you have to turn on package_data and include the files through that mechanism. That method requires a restructuring of your project into a multiple file project with some renaming, basically it needs a root directory with an __init__.py to put the type files into (At least I think). Single file projects don't really support the side by side style.

Of course if the stub package method is used then they must be maintained separately. This package's interface seems pretty stable so it might not be that bad to do. I can send you the pyi file if you want to do it yourself. It's pretty easy to generate though.

gfairchild commented 2 years ago

Sorry for the slow responses here!

Can you show me some examples of the changes you made? I see your fork here, but it looks to be current with the master branch on this project. I'm really curious to see how this works in practice.

xzy3 commented 2 years ago
from typing import Sequence, Any, List

def damerau_levenshtein_distance(seq1: Sequence[Any], seq2: Sequence[Any]) -> int: ...
def normalized_damerau_levenshtein_distance(seq1: Sequence[Any], seq2: Sequence[Any]) -> float: ...
def damerau_levenshtein_distance_seqs(seq: Sequence[Any], seqs: Sequence[Sequence[Any]]) -> List[int]: ...
def normalized_damerau_levenshtein_distance_seqs(seq: Sequence[Any], seqs: Sequence[Sequence[Any]]) -> List[float]: ...

That's pretty much the whole thing as far as code goes. The problem is I haven't really figured out how to package this file up into the project correctly. If this is made as a stub package you really just need to put this in an __init__.pyi in it's own project with a specific file structure and upload it to pypi. There isn't much guidance for side by side installation of interface files with extension packages. Instructions for using this pyi file with a pure python project are available.

gfairchild commented 2 years ago

Do we actually even need an interface file, though? Can we not just put it directly in pyxdameraulevenshtein.pyx? I haven't tried it myself yet, but it looks like Cython supports static type definitions. I'd need to spend time digesting this, though, and this project is unfortunately not a priority for me at the moment. I'd love a PR, though!

xzy3 commented 2 years ago

As far as I know the Python typing system and Cython typing system are separate. Mypy et al. don't really deal with Cython types. I'll keep working on it when I get a chance and try and figure out the packaging stuff.

gfairchild commented 2 years ago

Thanks! I look forward to seeing what you discover.

xzy3 commented 2 years ago

Ok got to it faster than I expected. I just made a second stubs package in the same repo. So now you have to push to pypi once in the main directory, then move to type-stubs and upload from there too. I have it in my fork if you want to look at it. I'll do a pull request if this mechanism works for you.

gfairchild commented 2 years ago

Looks very simple actually! Would you mind creating a PR?

gfairchild commented 1 year ago

Done via #37.