سؤال

I've just registered my new package with PIP

python setup.py register
python setup.py sdist upload

And I wanted to install it on other machine globally (i.e. no virtualenv) using 'PIP':

sudo pip install standardiser

This all went fine, since I have one file registered as a script:

setup(
...
scripts=['standardiser/bin/standardiser.py'],
)

'standariser.py' is now available as CLI command system wide. But if I execute it, I'm getting:

mnowotka@candela:~/Documents/ci/curation_interface/trunk/src$ standardiser.py 
Traceback (most recent call last):
  File "/usr/local/bin/standardiser.py", line 32, in <module>
    from standardiser import standardise, SDF
  File "/usr/local/bin/standardiser.py", line 32, in <module>
    from standardiser import standardise, SDF
ImportError: cannot import name standardise

I get the same when I explicitly call python:

python /usr/local/bin/standardiser.py

But if I copy this to some local folder:

sudo cp python /usr/local/bin/standardiser.py bla.py

And run it from there:

mnowotka@candela:~$ python bla.py
usage: bla.py [-h] [-V] [-r] infile
bla.py: error: too few arguments

I don't have any ImportErors. What I'm doing wrong? Can you help me?

My setyp.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = 'mnowotka'

import sys

try:
    from setuptools import setup
except ImportError:
    from ez_setup import use_setuptools
    use_setuptools()
    from setuptools import setup
setup(
    name='standardiser',
    version='0.1.4',
    author='Francis Atkinson',
    author_email='francis@ebi.ac.uk',
    description='Provides a simple way of standardising molecules as a prelude to e.g. molecular modelling exercises.',
    url='https://www.ebi.ac.uk/chembldb/index.php/ws',
    license='Apache License, Version 2.0',
    scripts=['standardiser/bin/standardiser.py'],
    packages=['standardiser'],
    long_description=open('ReadMe.txt').read(),
    package_data={
        'standardiser': ['bin/*', 'data/*', 'docs/*', 'knime/*', 'test/*',],
        },
    classifiers=['Development Status :: 2 - Pre-Alpha',
                 'Environment :: Console',
                 'Intended Audience :: Science/Research',
                 'License :: OSI Approved :: Apache Software License',
                 'Operating System :: OS Independent',
                 'Programming Language :: Python',
                 'Topic :: Scientific/Engineering :: Chemistry'],
    zip_safe=False,
)
هل كانت مفيدة؟

المحلول

You are asking for a script to be installed named standardiser.py; that script (at least, the one you've uploaded to the cheese shop) contains the line:

from standardiser import standardise, SDF

But thats an ambigious import; the script you're executing, /usr/local/bin/standardise.py appears in sys.path, because the main script is located there. it's importing itself!

you should be using the console_scripts feature of setuptools anyway.

alter your script file from

#! /guess/path/to python
from standardise import import *
do_things()
do_more_things()

to

from __future__ import absolute_import
from standardise import import *

def main():
    do_things()
    do_more_things()

if __name__ == '__main__':
    main()

Which is to say;

  • get rid of the shebang; you never need it in python!
  • use the absolute_import feature to get the module named foo.bar.foo to be able to import foo instead of only foo.bar.foo (you can still import foo.bar.foo as either from foo.bar import foo or import .foo). __future__ imports must appear first in the source file, before any other non-comment lines (including other imports)
  • most importantly; wrap import time side effects in a function, and only invoke those side effects if this is the "main script"

then change your setup.py around from

setup(
    scripts=['standardiser/bin/standardiser.py'],
    ...)

to

setup(
    entry_points={
        'console_scripts': [
            'standardiser=standardiser.bin.standardiser:main']},
    ...)

which is to say:

  • use an entry point; setuptools knows how to get your installed package on sys.path correctly in this case, and it knows how to connect to the proper python interpreter, the one that was used to run setup.py. This matters when there are multiple versions of python, or when running in a virtualenv. this is why you never need a shebang.
  • remove the '.py' from the installed executable name. this shouldn't ever be there for scripts that are to be on your executable path.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top