pyroma
pyroma copied to clipboard
Add new check: package-name should correspond uniquely to module-name
When you publish a package on pypi, the package-name is unique across all packages. Unfortunately some packages choose a very different name for their toplevel module. They use a module-name that actually corresponds to a different package-name.
For example:
- https://github.com/pedroburon/dotenv
- https://pypi.org/project/django-dotenv
- https://pypi.org/project/python-dotenv
These package by themselves could score 10/10 in pyroma. You can install them via their unique package-name:
> pip install dotenv
> pip install django-dotenv
> pip install python-dotenv
But, they all use the same top-level module-name.
>>> import dotenv
therefore one package is shadowing another, making them unusable in the same project.
IMHO the package named dotenv
should score 10/10 in pyroma,
but the django-dotenv
and python-dotenv
should be disqualified with 0/10.
So the modulename should be unique across all python-packages:
assert modulename == package_name.lower().replace("-", "_")
It's not unusual to have packages called "python-something" for python integration of libraries called "something" especially when somebody tried to implement "something" and abandoned it half-way.
So disqualifying them isn't a good idea. But certainly warning against it makes sense.
For packages that have been this way for a long time, changing them to be consistent would cause problems or unnecessary churn for users having to update their code or dependencies.
The suggestion from a warning would make things worse for forks intended as drop-in replacements: they would no longer be drop-in replacements.
Pillow is the only exception I've come across so far where that was intentionally violating this rule. Pillow is indeed was fully compatible drop-in replacement for PIL. On the other side PIL was never properly packaged, and therefore never declared in any package as a dependency.
Packages declare their dependencies via package-name, not by module-name. So how does a drop-in replacement work in such case? @hugovk Can you give an example?
The Django-community has been diabolically promoting "django-foo" + "import foo" for many years. None of them are intended to be drop-in replacements, they are largely unaware about the packages they are conflicting with. Private / public forking and republishing is the only option to make both packages work in the same env. Been there, done that.
python-foo remains a very bad name for a python-package, will there ever be a rust-foo / go-foo / ruby-foo python-package?
Give my example above, I would indeed like to see corrections in new releases:
>>> import dotenv
>>> import django_dotenv
>>> import python_dotenv
Semantic versioning can flag the backwards compatibility, and dependent code can use an import-alias:
>>> import django_dotenv as dotenv
better then maintaining private forks, no?
flask-dotenv does correctly: https://github.com/grauwoelfchen/flask-dotenv/
I guess there are no Pypi-classifiers to indicate a package is a compatible drop-in replacement for another package?
Hmm, none come to mind right now. Being a Pillow maintainer may skew my viewpoint though!
Nope, no classifier for that, as far as I'm aware.