-
Notifications
You must be signed in to change notification settings - Fork 25
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
Make package PEP 561 compliant; add typehint stub file #49
Conversation
Reviewer's Guide by SourceryThis pull request makes the package PEP 561 compliant by adding a 'py.typed' file and type hint stubs for the underlying C extension. The 'setup.py' file was updated to include the 'crc32c' package and to ensure package data files are included. A new 'crc32c/init.pyi' file was created to provide type hints for the 'big_endian' and 'hardware_based' variables, as well as the 'crc32' and 'crc32c' functions. File-Level Changes
Tips
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @jonded94 - I've reviewed your changes and they look great!
Here's what I looked at during the review
- 🟡 General issues: 1 issue found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.
crc32c/__init__.pyi
Outdated
def crc32(inp: Buffer, crc: int = 0, release_gil: bool | int = -1) -> int: ... | ||
def crc32c(inp: Buffer, crc: int = 0, release_gil: bool | int = -1) -> int: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider clarifying the release_gil
parameter type and usage
The bool | int
type hint for release_gil
with a default of -1 might be confusing. Consider using an enum or separate boolean flags to make the intended usage more explicit. This would improve the API's clarity and make it easier for users to understand the parameter's purpose.
from enum import Enum, auto
class GILRelease(Enum):
DEFAULT = auto()
RELEASE = auto()
NO_RELEASE = auto()
def crc32(inp: Buffer, crc: int = 0, release_gil: GILRelease = GILRelease.DEFAULT) -> int: ...
def crc32c(inp: Buffer, crc: int = 0, release_gil: GILRelease = GILRelease.DEFAULT) -> int: ...
ac393de
to
8c5aa10
Compare
@rtobar rebased onto new |
@jonded94 again, thanks for this submission. I am not expert on typing, and have never maintained a stub file myself. However, the fact that you had to add a
You mentioned that this worked for you though, but by the sounds of it, it might be more chance than because all rules are followed. I do like the idea of distributing typing hints; however, it seems that a pre-requisite for this is that I turn this module-only distribution into a package instead,. This is anyway something I've waned to do for a while, just never got around doing It since there was no pressure to do so. So: let me try doing that first. It shouldn't be a difficult change though, and it will also be good time to reorganise source files around. In the meanwhile I do have one question: is there a way we can verify on CI that the typing is somewhat correct? For instance, could we maybe install mypy and run it against the test code and verify it comes back with no issue? I'd do that as a separate job, maybe even workflow, on our GHA. |
First, let me start with that modifying It works without problems like this:
Both the interpreter can find the actual library (the Why does it not work with a The only problem with a stub file would be that the required Nevertheless:
This is a pretty standard approach, I'd say. This does remove the need of some boilerplat-y With that, a proper folder for this package exists and it's not longer a single-file distribution. Unfortunately, I'm seeing some weird linker errors on Windows: https://github.com/ICRAR/crc32c/actions/runs/10270554189/job/28418529101?pr=49
Sure, I definitely can help there since I probably type hinted hundreds of thousands of lines of Python and introduced type hinting in general into many large codebases. Just as an actual example, this is
One would probably at least want to type check the For one reason, there are no type hints at all right now in this file, of course. This is not hard to do, but keep in mind that type hints were only introduced in Python 3.5 (https://peps.python.org/pep-0484/). So, type hinting the test file would lead to this file only being executable in Python >3.5. Also, there are some pretty un-pythonic and unexpeceted things happening in this file. For example, right at the start:
If you'd want to have this test file type checked in CI, this definitely would be a slightly bigger endeavour. Maybe the easiest if one simply removes that "sw mode" is set through environment variables, but do it only via a Alternatively: One could create another, very simple test file though and only check that in CI. |
775405f
to
edacda4
Compare
@jonded many thanks again for all your inputs, I've been learning a few things on the way. After my message above I also worked on converting the distribution into a package. It builds in all platforms and all tests run successfully. It's not as simple as your approach (I still build a separate extension, then import its members in (EDIT: I forgot to mention that I kept the old contents of your branch on this repo's Yes, the code in the test module is far from ideal. I still carry the baggage from the 1.x version of the package that would fail to load if no HW extensions were present. You are right that this is not the greatest approach. The intention was always to give users the ability to ensure they are using the hardware-based algorithm., so they would never accidentally end up with the slow version. If anything, this logic could be supported as a Also, as you also point out, type hints are "relatively new" (I had in my mind they were 3.7+, but I was clearly confused there too), and we still advertise 2.7+ compatibility. Only a very, very minor percentage of our users use anything other than 3.7+ though, so it's reasonable to bump up that python version requirement for the package, remove support for old python versions, and THEN finally be able to use the test module as another source of type hinting verification. In the meantime some small snippets of code that are known to fail/succeed would be a first good approach. Reading the help we can even use |
Nice! Thank you very much, this looks very nice. Sorry, I just somewhat winged it and was busy with other things.
Small sidefact: This is because But yeah, definitely I messed something up on my try, doing it like you did introduces a slight overhead but is definitely far more standard and should lead to less headaches. Baked in C source files Something small that I noticed: You now include the C source files as a part of your
The approach that I know would be slightly different:
One would include the
Very nice! Dropping all of the old baggage actually enables quite a bunch of stuff :) If you are willing to drop support for old versions, I could try typehinting the current test file. This shouldn't take too long. These ignore comments are not too bad and are very easily cleaned up afterwards. |
I dropped support for Python <3.7 in the tests file, fully type hinted it and tested that locally with Python 3.7 & 3.10. Do you want to drop support for Python <3.7 for the whole package (either in this branch or on Things to tackle later maybe: Parametrizing the tests
This block could just be replaced by a With that, this also wouldn't be required anymore:
Let "sw mode" be set via With that, this block
could also just be replaced entirely with a parameter in |
Now the linting job was triggered. Brighter minds than me have to understand why the path triggering does not work (does |
Sorry for spamming, final remarks:
Should be ready for review! :) |
cd6ab5a
to
61b34f1
Compare
61b34f1
to
f1e12a5
Compare
(I had written a reply before squashing and force-pushing, I think I missed pressing "Comment" 😢)
I love this kind of spam! @jonded94 this has been a very useful and positive discussion, and I thank you for that. The changes are in a state that I'll be merging them, only that I've squashed the CI setup commits into a single one, and added a scheduled run in there too, so that we don't bitrot against newer versions of mypy. Yes, we advertise 2.7+ support because of the source distribution. As you point out, it's a pretty wild guess whether it still works or not, although the subset of the Python C API we use is very limited and has been stable throughout the whole 3.x series. I'll probably officially drop 2.7 support (testing changes right now), but won't bother limiting the 3.x versions, since it doesn't gain us anything. After this, I'll release a new version on PyPI. Future work, all coming after a new release:
|
Has to be merged after #47.
Makes this package properly PEP 561 compliant by introducing a
py.typed
and stub files for the underlying C extension.Summary by Sourcery
Make the package PEP 561 compliant by adding type hint stub files and updating
setup.py
to include package data.New Features:
crc32c/__init__.pyi
for the underlying C extension.Enhancements:
py.typed
file and including package data insetup.py
.