[Distutils] setuptools: name quoting

Phillip J. Eby pje at telecommunity.com
Wed Sep 21 03:31:24 CEST 2005

At 08:19 PM 9/20/2005 -0500, Ian Bicking wrote:
>Phillip J. Eby wrote:
> > At 02:59 PM 9/20/2005 -0500, Ian Bicking wrote:
> >
> >> I'm a bit confused about name quoting.  I have a package with a name
> >> "Todo_SQLObject_ZPT", and egg_info writes to
> >> "Todo-SQLObject-ZPT.egg-info".  Why?  I thought -'s were bad, but _'s
> >> were okay...?
> >
> >
> > It's safe to use either, but setuptools considers '-' to be canonical;
> > this was a heuristic decision on my part because '-' appears more
> > frequently used than '_' in the names of projects currently registered
> > with PyPI.
> >
> > The problem, however, is that PyPI wants your uploaded files to
> > *exactly* match the registered name.  If you used '-' in setup.py, you
> > must have '-' in the filename, and that's something setuptools cannot
> > do.  It would probably be best if setuptools ensured the "register"
> > command always used '_', but then this defeats the purpose of having it
> > that way in the first place!
> >
> > So, the only real fix is to change PyPI to accept files whose
> > pkg_resources.safe_name() match the safe_name() of the project.  In the
> > meantime, you can't upload eggs to PyPI for packages with '-' or '_' in
> > their names.  (You can upload source distros or other formats, since
> > those can work with ambiguous filenames.) I probably should put in an
> > RFE or proposed patch, but I've been *really* busy lately.
>Richard, would you be able to make this change?  It seems pretty
>reasonable to accept files that closely match project names.

FYI, here are the safe_name/safe_version source:

def safe_name(name):
     """Convert an arbitrary string to a standard distribution name

     Any runs of non-alphanumeric characters are replaced with a single '-'.
     return re.sub('[^A-Za-z0-9]+', '-', name)

def safe_version(version):
     """Convert an arbitrary string to a standard version string

     Spaces become dots, and all other non-alphanumeric characters become
     dashes, with runs of multiple dashes condensed to a single dash.
     version = version.replace(' ','.')
     return re.sub('[^A-Za-z0-9.]+', '-', version)

To make an egg filename, these strings are taken and the '-' converted to a 
'_' so that it isn't confused with the '-' that goes between parts of the 
name.  So given the metadata:

         name="To-Do List",
         version="1.23 alpha!",

The egg filename will be "To_Do_List-1.23.alpha_-py2.4-win32.egg" if 
generated by Python 2.4 on Windows (and it contains C 
extensions).  Currently, if I understand it correctly, PyPI will reject 
this name if the name and version used for registration were "To-Do List" 
and "1.23 alpha!".

More information about the Distutils-SIG mailing list