When trying to start 'nserve' installed by mwlib (distutils.eclass based), I get: This Python implementation (python2.7) is not supported by the script. Downgrading to bottle-0.11.3 (also distutils.eclass based) makes it work again.
there are strange things going on with our python-exec solution anyway (concerning bottle): cat test.py #!/usr/bin/python2.7 from bottle import request tiziano@storm ~/tmp $ ipython test.py This Python implementation (python2.7) is not supported by the script (/home/tiziano/tmp/test.py). An exception has occurred, use %tb to see the full traceback. SystemExit: 127 tiziano@storm ~/tmp $ ln -s test.py test.py-python2.7 tiziano@storm ~/tmp $ ipython test.py --------------------------------------------------------------------------- ImportError Traceback (most recent call last) /usr/lib64/python2.7/site-packages/IPython/utils/py3compat.py in execfile(fname, *where) 176 else: 177 filename = fname --> 178 __builtin__.execfile(filename, *where) /home/tiziano/tmpc/test.py in <module>() 1 #!/usr/bin/python2.7 2 ----> 3 from bottle import request /usr/bin/bottle.py in <module>() 51 52 sys.argv[0] = __file__ ---> 53 exec(data) <string> in <module>() ImportError: cannot import name request So, the problem here seems that a) the script gets re-executed somehow (for both mwlib and ipython) and b) that "from bottle import request" somehow ends up using /usr/bin/bottle.py which is now our wrapper which does not have the "request" object of course.
When rewriting the mwlib ebuild (and the remaining deps) to distutils-r1 one gets this when running the tests (I extended python-exec a bit to show argv[0] in brackets): ==================================== ERRORS ==================================== ___________________ ERROR collecting sandbox/test_nserve.py ____________________ sandbox/test_nserve.py:4: in <module> > import pytest, gevent, urllib, urllib2, bottle /usr/bin/bottle.py:48: in <module> > sys.exit(127) E SystemExit: 127 ------------------------------- Captured stderr -------------------------------- This Python implementation (python2.7) is not supported by the script (/usr/bin/py.test-python2.7). ========== 696 passed, 1 skipped, 9 xfailed, 1 error in 4.55 seconds =========== So it seems that a certain environment makes bottle call itself again with the already replaced argv[0], looking for py.test-python2.7-python2.7 which doesn't exist of course.
The problem here is that when executing /usr/bin/nserve (or /usr/bin/ipython) the path /usr/bin gets added to sys.path (thanks to floppym for the reminder). So, when mwlib does "import bottle" our python-exec symlink /usr/bin/bottle.py gets imported resulting in another "exec(...)". The same happens when using ipython for example. There are a number of solutions while the easiest one being to rename /usr/bin/bottle.py to /usr/bin/bottle Besides that, bottle installs the same file 2*$(number of python implementations) times: * /usr/bin/bottle.py-pythonX.Y * /usr/lib*/pythonX.Y/site-packages/bottle.py while we can't share the files between different versions of python, we can instead use a symlink for the copy in /usr/bin.
ok a month has passed. Has this lead to a final solution? I think not. I have changed bottle to install the script renamed to bottle and this doesn't resolve. dev-python/mwlib $ qlist bottle | grep bin /usr/bin/bottle-pypy-c2.0 etc etc mwlib $ PYTHON_TARGETS=python2_7 ebuild mwlib-0.15.10.ebuild clean test yields tests/test_nserve.py:4: in <module> > import pytest, gevent, urllib, urllib2, bottle /usr/bin/bottle.py:48: in <module> > sys.exit(127) E SystemExit: 127 -------------------------------------------------------------------- Captured stderr --------------------------------------------------------------------- This Python implementation (python2.7) is not supported by the script. =============================================== 702 passed, 1 skipped, 9 xfailed, 1 error in 5.85 seconds ================================================ What I want to know is how does import bottle become import from /usr/bin/bottle.py which now is mow no longer. Both cases lead to a test failure. Is there some remnant in the installed bottle that still 'thinks' the bottle.py is replicated as a script in /usr/bin/. Given /usr/lib64/python2.7/site-packages/bottle-0.11.6-py2.7.egg-info frankly I can't see how.
> Downgrading to bottle-0.11.3 (also distutils.eclass based) makes it work > again. dev-python/mwlib $ eix bottle [U] dev-python/bottle Available versions: (~)0.10.9 (~)0.11.3 (~)0.11.6 {PYTHON_TARGETS="pypy1_9 pypy2_0 python2_6 python2_7 python3_2 python3_3"} Installed versions: 0.11.3(20:36:25 26/07/13) /dev-python/mwlib $ PYTHON_TARGETS=python2_7 ebuild mwlib-0.15.8-r1.ebuild clean test sandbox/test_nserve.py:4: in <module> > import pytest, gevent, urllib, urllib2, bottle /usr/bin/bottle.py:85: in <module> > sys.exit(1) E SystemExit: 1 -------------------------------------------------------------------- Captured stderr --------------------------------------------------------------------- /usr/bin/py.test-python2.7: No target script exists for '/usr/bin/py.test-python2.7' So downgrading to bottle 0.11.3 did nothing. (In reply to Tiziano Müller from comment #0) < So it seems that a certain environment makes bottle call itself again with the already replaced argv[0], looking for py.test-python2.7-python2.7 which doesn't exist of course.(In reply to Tiziano Müller from comment #0) > The upstream maintainer gives us it passes fine for him using bottle 0.11.3 and 0.11.6. This leads me to assert that this is a gentoo contrived error. Please fix
Do we break something by renaming bottle.py->bottle in /usr/bin?
no, made no difference. test_nserve was equally lost
(In reply to Michał Górny from comment #6) > Do we break something by renaming bottle.py->bottle in /usr/bin? We're just surprising our users since they probably expect the binary to be bottle.py But yes, that would fix it for stuff that uses bottle.
(In reply to Ian Delaney from comment #7) > no, made no difference. test_nserve was equally lost The logs above show that /usr/bin/bottle.py is still used even though you said you changed it.
(In reply to Tiziano Müller from comment #8) > (In reply to Michał Górny from comment #6) > > Do we break something by renaming bottle.py->bottle in /usr/bin? > > We're just surprising our users since they probably expect the binary to be > bottle.py > But yes, that would fix it for stuff that uses bottle. Can we convince upstream to change their name? Arguments include having no '.py' is better for user-friendly paths ('bottle') and sys.path collisions.
(In reply to Tiziano Müller from comment #9) > (In reply to Ian Delaney from comment #7) > > no, made no difference. test_nserve was equally lost > > The logs above show that /usr/bin/bottle.py is still used even though you > said you changed it. FWIW over the hours I spent working mwlib I had the last version of bottle with the bottle.py script changed to bottle at that one point. Seeing it didn't work I then downgraded which reverted to /usr/bin/bottle.py, however it seems that is but milk long since spilt. Does this beckon 'someone' to file @ upstream bottle (not mwlib) and ask please do the bright thing and rename script bottle.py to bottle???
I will commit the following tomorrow as -r1 if there are no objections. --- bottle-0.11.6.ebuild 2013-08-13 09:14:09.000000000 +0200 +++ bottle-0.11.6-r1.ebuild 2013-08-31 22:08:55.000000000 +0200 @@ -17,4 +17,16 @@ IUSE="" DEPEND="" -RDEPEND="${DEPEND}" +RDEPEND="" + +python_prepare_all() { + sed -i -e '/scripts/d' setup.py || die +} + +pkg_postinst() { + elog "Due to problems with bottle.py being in /usr/bin (see bug #474874)" + elog "we do as most other distros and do not install the script anymore." + elog "If you do want/have to call it directly rather than through your app," + elog "please use the following instead:" + elog ' `python -m bottle`' +} If someone thinks we really need a /usr/bin/bottle (/usr/bin/bottle.py is not possible), we could provide it as something like this: #!/bin/sh exec python -m bottle $@
committed.