PyPI package aliases

03 May 2014 (updated 07 July 2015)

One common annoyance with python packaging is the lack of a standard distribution naming convention. The distribution is the archive you download from PyPI. The distribution contains the actual packages and/or modules. So basically the distribution name is the name argument in setup.py's setup( ... ) call.

The naming is a bit confusing, the package is not like the package in your favourite Linux distro - the distribution is. And yes, the title is wrong. Intentionally wrong :)

Now guess the actual distribution name for the most popular mysql client:

  • mysqldb - Makes sense right? MySQLdb is what you would import in your code. But alas, this is not the distribution name.
  • mysql - Maybe this? Nope.
  • python-mysqldb - No.
  • python-mysql - No.
  • mysqldb-python - No.
  • mysql-python - It can't be this can it? Surprise, surprise, it is.

Now that was an extreme case but there's always this predilection of prefixing distributions with python-.

Note

Update: there's a pypi-alias tool you should use instead.

There should be an easy way to create aliases on PyPI. I like to name distributions with the actual package name (or whatever users would import) and use this script to create a "python-<name>" alias for confused users:

#!/usr/bin/python
import os
import shutil
import subprocess
import sys
import tempfile

name = subprocess.check_output(['python', 'setup.py', '--name']).strip()
url = "https://pypi.python.org/pypi/%s/" % name
description = subprocess.check_output(['python', 'setup.py', '--description']).strip()
assert 'python' not in name
alias = "python-%s" % name
author = subprocess.check_output(['python', 'setup.py', '--author']).strip()
author_email = subprocess.check_output(['python', 'setup.py', '--author-email']).strip()

try:
    path = tempfile.mkdtemp()
    os.chdir(path)
    with open(os.path.join(path, 'setup.py'), 'wb') as fh:
        fh.write(b"""# encoding: utf8

from setuptools import setup

setup(
    name=%(alias)r,
    version="0.0",
    url=%(url)r,
    description=%(description)r,
    long_description='''Use `%(name)s <%(url)s>`_ instead.''',
    author=%(author)r,
    platforms=['all'],
    zip_safe=False,
    author_email=%(author_email)r,
    install_requires=[%(name)r],
)
""" % globals())

    subprocess.call(['python', 'setup.py'] + sys.argv[1:])
finally:
    shutil.rmtree(path)

This assumes your actual distribution name is not prefixed with python-. I use it like this:

pypi-link register sdist upload

You could easily change the script to take the alias name as an argument.

Now back to the original nuisance - should MySQL-python have aliases or not?

This entry was tagged as packaging python