pyroma icon indicating copy to clipboard operation
pyroma copied to clipboard

Add new check: package-name should correspond uniquely to module-name

Open woutervh opened this issue 1 year ago • 6 comments

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("-", "_")

woutervh avatar May 09 '23 19:05 woutervh

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.

regebro avatar May 11 '23 18:05 regebro

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.

hugovk avatar May 11 '23 19:05 hugovk

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?

woutervh avatar May 11 '23 20:05 woutervh

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/

woutervh avatar May 11 '23 20:05 woutervh

I guess there are no Pypi-classifiers to indicate a package is a compatible drop-in replacement for another package?

woutervh avatar May 11 '23 20:05 woutervh

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.

hugovk avatar May 12 '23 19:05 hugovk