Skip to content

Implement rwt as pip run #3979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed

Implement rwt as pip run #3979

wants to merge 8 commits into from

Conversation

jaraco
Copy link
Member

@jaraco jaraco commented Sep 18, 2016

This PR quite simply vendors rwt and invokes it as pip run. As you can see, the hook is rather minimal (mostly boilerplate).

One thing I'd like to do before accepting this is to stop re-writing sys.argv and instead have rwt.run take the args directly, but that'll take an update to rwt (which I will do later).

I also welcome other feedback. Do you want a changelog entry? Should docs be updated somewhere?


This change is Reviewable

@jaraco
Copy link
Member Author

jaraco commented Sep 18, 2016

I should have mentioned #3971 where this discussion originated.

@RonnyPfannschmidt
Copy link
Contributor

@jaraco btw, what about putting the cached wheels onto python-path for any non-binary wheel file

@jaraco
Copy link
Member Author

jaraco commented Sep 18, 2016

@RonnyPfannschmidt Perhaps. How is that preferable to invoking pip install? Does pip provide a command to get cached wheel files?

@RonnyPfannschmidt
Copy link
Contributor

@it removes the need to make a tmpdir

So for all pure python packages it would remove the nerd to manage

Recent pip is adding commands to interact with cache

@RonnyPfannschmidt
Copy link
Contributor

#3968

@jaraco
Copy link
Member Author

jaraco commented Sep 21, 2016

I actually don't see why the wheels would have to be non-binary wheels. Setuptools creates binary eggs all the time that are loaded as zip packages. Still, I'll leave it up to the packaging ecosystem to decide which formats are viable.

As for linking cached wheels, it's important that there be functionality to resolve a set of requirements to a set of wheels, installed or cached. While attractive, that feature feels a little premature. I'm willing to accept the performance drawbacks until the functionality proves worthwhile.

I believe this PR is ready for review.

@jaraco jaraco changed the title [wip] Implement rwt as pip run Implement rwt as pip run Sep 21, 2016
@RonnyPfannschmidt
Copy link
Contributor

@jaraco binary eggs need unpacking as well,
so just putting the file into pythonpath wont work

@jaraco
Copy link
Member Author

jaraco commented Sep 21, 2016

Not in my experience:

$ python setup.py bdist_egg
Building lxml version 3.5.0b1.
Building without Cython.
Using build configuration of libxslt 1.1.29
Building against libxml2/libxslt in the following directory: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/lib
running bdist_egg
running egg_info
writing src/lxml.egg-info/PKG-INFO
writing dependency_links to src/lxml.egg-info/dependency_links.txt
writing requirements to src/lxml.egg-info/requires.txt
writing top-level names to src/lxml.egg-info/top_level.txt
reading manifest file 'src/lxml.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.html' under directory 'doc'
writing manifest file 'src/lxml.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.6-intel/egg
running install_lib
running build_py
creating build/lib.macosx-10.6-intel-3.6
creating build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/__init__.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/_elementpath.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/builder.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/cssselect.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/doctestcompare.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/ElementInclude.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/pyclasslookup.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/sax.py -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/usedoctest.py -> build/lib.macosx-10.6-intel-3.6/lxml
creating build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/__init__.py -> build/lib.macosx-10.6-intel-3.6/lxml/includes
creating build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/__init__.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/_diffcommand.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/_html5builder.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/_setmixin.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/builder.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/clean.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/defs.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/diff.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/ElementSoup.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/formfill.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/html5parser.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/soupparser.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
copying src/lxml/html/usedoctest.py -> build/lib.macosx-10.6-intel-3.6/lxml/html
creating build/lib.macosx-10.6-intel-3.6/lxml/isoschematron
copying src/lxml/isoschematron/__init__.py -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron
copying src/lxml/lxml.etree.h -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/lxml.etree_api.h -> build/lib.macosx-10.6-intel-3.6/lxml
copying src/lxml/includes/c14n.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/config.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/dtdvalid.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/etreepublic.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/htmlparser.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/relaxng.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/schematron.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/tree.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/uri.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/xinclude.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/xmlerror.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/xmlparser.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/xmlschema.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/xpath.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/xslt.pxd -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/etree_defs.h -> build/lib.macosx-10.6-intel-3.6/lxml/includes
copying src/lxml/includes/lxml-version.h -> build/lib.macosx-10.6-intel-3.6/lxml/includes
creating build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources
creating build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/rng
copying src/lxml/isoschematron/resources/rng/iso-schematron.rng -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/rng
creating build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl
copying src/lxml/isoschematron/resources/xsl/RNG2Schtrn.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl
copying src/lxml/isoschematron/resources/xsl/XSD2Schtrn.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl
creating build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_abstract_expand.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_dsdl_include.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_message.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_skeleton_for_xslt1.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_svrl_for_xslt1.xsl -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying src/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/readme.txt -> build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
running build_ext
building 'lxml.etree' extension
creating build/temp.macosx-10.6-intel-3.6
creating build/temp.macosx-10.6-intel-3.6/src
creating build/temp.macosx-10.6-intel-3.6/src/lxml
/usr/bin/clang -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/opt/openssl/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml2 -Isrc/lxml/includes -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c src/lxml/lxml.etree.c -o build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.etree.o -w -flat_namespace
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g -L/usr/local/opt/openssl/lib -I/usr/local/opt/openssl/include build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.etree.o -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/lib -lxslt -lexslt -lxml2 -lz -lm -o build/lib.macosx-10.6-intel-3.6/lxml/etree.cpython-36m-darwin.so
ld: warning: ignoring file build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.etree.o, file was built for x86_64 which is not the architecture being linked (i386): build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.etree.o
building 'lxml.objectify' extension
/usr/bin/clang -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/opt/openssl/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml2 -Isrc/lxml/includes -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c src/lxml/lxml.objectify.c -o build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.objectify.o -w -flat_namespace
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g -L/usr/local/opt/openssl/lib -I/usr/local/opt/openssl/include build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.objectify.o -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/lib -lxslt -lexslt -lxml2 -lz -lm -o build/lib.macosx-10.6-intel-3.6/lxml/objectify.cpython-36m-darwin.so
ld: warning: ignoring file build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.objectify.o, file was built for x86_64 which is not the architecture being linked (i386): build/temp.macosx-10.6-intel-3.6/src/lxml/lxml.objectify.o
creating build/bdist.macosx-10.6-intel/egg
creating build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/__init__.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/_elementpath.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/builder.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/cssselect.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/doctestcompare.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/ElementInclude.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/etree.cpython-36m-darwin.so -> build/bdist.macosx-10.6-intel/egg/lxml
creating build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/__init__.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/_diffcommand.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/_html5builder.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/_setmixin.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/builder.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/clean.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/defs.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/diff.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/ElementSoup.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/formfill.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/html5parser.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/soupparser.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
copying build/lib.macosx-10.6-intel-3.6/lxml/html/usedoctest.py -> build/bdist.macosx-10.6-intel/egg/lxml/html
creating build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/__init__.py -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/c14n.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/config.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/dtdvalid.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/etree_defs.h -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/etreepublic.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/htmlparser.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/lxml-version.h -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/relaxng.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/schematron.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/tree.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/uri.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/xinclude.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/xmlerror.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/xmlparser.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/xmlschema.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/xpath.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
copying build/lib.macosx-10.6-intel-3.6/lxml/includes/xslt.pxd -> build/bdist.macosx-10.6-intel/egg/lxml/includes
creating build/bdist.macosx-10.6-intel/egg/lxml/isoschematron
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/__init__.py -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron
creating build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources
creating build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/rng
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/rng/iso-schematron.rng -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/rng
creating build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl
creating build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_abstract_expand.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_dsdl_include.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_message.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_schematron_skeleton_for_xslt1.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/iso_svrl_for_xslt1.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/iso-schematron-xslt1/readme.txt -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl/iso-schematron-xslt1
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/RNG2Schtrn.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl
copying build/lib.macosx-10.6-intel-3.6/lxml/isoschematron/resources/xsl/XSD2Schtrn.xsl -> build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/resources/xsl
copying build/lib.macosx-10.6-intel-3.6/lxml/lxml.etree.h -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/lxml.etree_api.h -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/objectify.cpython-36m-darwin.so -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/pyclasslookup.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/sax.py -> build/bdist.macosx-10.6-intel/egg/lxml
copying build/lib.macosx-10.6-intel-3.6/lxml/usedoctest.py -> build/bdist.macosx-10.6-intel/egg/lxml
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/__init__.py to __init__.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/_elementpath.py to _elementpath.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/builder.py to builder.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/cssselect.py to cssselect.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/doctestcompare.py to doctestcompare.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/ElementInclude.py to ElementInclude.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/__init__.py to __init__.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/_diffcommand.py to _diffcommand.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/_html5builder.py to _html5builder.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/_setmixin.py to _setmixin.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/builder.py to builder.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/clean.py to clean.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/defs.py to defs.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/diff.py to diff.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/ElementSoup.py to ElementSoup.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/formfill.py to formfill.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/html5parser.py to html5parser.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/soupparser.py to soupparser.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/html/usedoctest.py to usedoctest.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/includes/__init__.py to __init__.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/isoschematron/__init__.py to __init__.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/pyclasslookup.py to pyclasslookup.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/sax.py to sax.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/usedoctest.py to usedoctest.cpython-36.pyc
creating stub loader for lxml/etree.cpython-36m-darwin.so
creating stub loader for lxml/objectify.cpython-36m-darwin.so
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/etree.py to etree.cpython-36.pyc
byte-compiling build/bdist.macosx-10.6-intel/egg/lxml/objectify.py to objectify.cpython-36.pyc
creating build/bdist.macosx-10.6-intel/egg/EGG-INFO
copying src/lxml.egg-info/PKG-INFO -> build/bdist.macosx-10.6-intel/egg/EGG-INFO
copying src/lxml.egg-info/SOURCES.txt -> build/bdist.macosx-10.6-intel/egg/EGG-INFO
copying src/lxml.egg-info/dependency_links.txt -> build/bdist.macosx-10.6-intel/egg/EGG-INFO
copying src/lxml.egg-info/not-zip-safe -> build/bdist.macosx-10.6-intel/egg/EGG-INFO
copying src/lxml.egg-info/requires.txt -> build/bdist.macosx-10.6-intel/egg/EGG-INFO
copying src/lxml.egg-info/top_level.txt -> build/bdist.macosx-10.6-intel/egg/EGG-INFO
writing build/bdist.macosx-10.6-intel/egg/EGG-INFO/native_libs.txt
creating 'dist/lxml-3.5.0b1-py3.6-macosx-10.6-intel.egg' and adding 'build/bdist.macosx-10.6-intel/egg' to it
removing 'build/bdist.macosx-10.6-intel/egg' (and everything under it)
$ ls -la dist
total 11320
drwxr-xr-x@  4 jaraco  staff      136 Sep 21 13:35 .
drwxr-xr-x@ 40 jaraco  staff     1360 Nov 19  2015 ..
-rw-r--r--@  1 jaraco  staff  4762172 Nov 12  2015 lxml-3.5.0b1-py3.5-macosx-10.6-intel.egg
-rw-r--r--@  1 jaraco  staff  1031481 Sep 21 13:35 lxml-3.5.0b1-py3.6-macosx-10.6-intel.egg
$ python -c "import lxml"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'lxml'
$ PYTHONPATH=dist/lxml-3.5.0b1-py3.6-macosx-10.6-intel.egg python -c "import lxml"
$

So that's at least one case of a binary package with extensions that's built into a zipped egg, added to PYTHONPATH, and then imported. Based on my past experience, I'd expect that library to be fully functional as well.

Can you share what you find doesn't work?

@dholth
Copy link
Member

dholth commented Sep 21, 2016

setuptools does have support for eggs with shared objects where it unpacks those parts somewhere dlopen-able automatically at runtime. I've heard that internally at Google they have patched Linux to be able to dlopen an uncompressed shared object stored inside e.g. a zip file.

@pfmoore
Copy link
Member

pfmoore commented Sep 21, 2016

@jaraco is the key point here

creating stub loader for lxml/etree.cpython-36m-darwin.so

It's typically an OS restriction that you can't load shared libraries from a zipfile. Does the egg format have stub files that do something clever like extract the shared library at runtime to a temporary directory, load it from there, and redirect calls into it? I have a vague recollection that something like that exists.

On the other hand, wheels don't have that sort of stub, because they explicitly don't take special measures to support "import direct from a wheel" as a use case.

@dstufft
Copy link
Member

dstufft commented Sep 21, 2016

I am -1 on using the wheel cache for this, I don't think we should bake into pip any sort of assumption that wheels are importable if you add them to sys.path (they sometimes are, sometimes aren't but it's largely an implementation detail).

Copy link
Member

@pfmoore pfmoore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not 100% convinced this belongs as a pip subcommand, but I could be swayed.

If it is to be merged, though, there should probably be some tests added to the pip test suite. I know rwt has its own tests, and that pip run simply forwards to rwt but at a minimum we need some tests to confirm that the integration as pip run works correctly.



class RunCommand(Command):
"""Show help for commands"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That docstring looks incomplete.

More generally, does this patch include suitable documentation for pip run? I know a lot of the docs are auto-generated, but given that this command just defers all its processing to rwt, I guess the auto-generation won't work. Can you add some documentation so that the full syntax for the command (and some examples) show up in the pip documentation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. This docstring is a copy-paste artifact (I used pip help command as a template). I'll correct that. This patch does include the docs for the rwt command, and in fact the tests ensure that pip help run outputs the same as pip run --help.

class RunCommand(Command):
"""Show help for commands"""
name = 'run'
usage = rwt.commands.help_doc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly this does enough to generate docs, but can you check locally? I'll try to double-check by downloading a local copy of the PR myself, but I don't have the time to do that right now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did confirm, and the tests validate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the rwt tests? So they test the pip integration as well? Then they definitely should be added to the pip test suite, rather than being external.

We might be talking at cross purposes, though. The other pip subcommands have their own pages (docs/reference/pip_list.rst for example). I was expecting a pip_run.rst alongside these.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, not the rwt tests, but the pip tests check all commands to ensure that they have a viable docstring. I need to look into the docs situation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed a new commit with docs for the pip run command. I've tested that these docs render properly and without warnings and provide a suitable background within the pip docs. I feel good about the documentation story now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To test-build the docs, I ran this command: rwt sphinx -- -m sphinx docs out. I didn't have to set up any virtualenv and I don't have anything to clean up after (except the out dir).


signal.signal(signal.SIGINT, null_handler)
cmd = [sys.executable] + params
subprocess.Popen(cmd, env=_setup_env(target)).wait()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this is an issue with rwt rather than with the vendoring or pip run, but this doesn't pass the exit code of the script back to the caller of rwt. It probably should.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I've filed jaraco/pip-run#10

@dstufft
Copy link
Member

dstufft commented Sep 21, 2016

I am also not 100% convinced that this should be added (I'm bouncing between -0 and +0) but I think if we do add it, we should probably actually implement it inside of pip itself instead of just wrapping rwt. That alleviates the need to do a subprocess to call into pip because we can just call the appropriate APIs since it's part of pip. It also makes it easier to pass options and such for things like what index are we downloading these things from (which this currently doesn't appear to support, and it needs to support that prior to being able to be landed).

@pfmoore
Copy link
Member

pfmoore commented Sep 21, 2016

I agree with @dstufft. We should not use the wheel cache directly. Two reasons:

  1. As an external program, rwt has no right to know the internals of the wheel cache. If pip run were written as pure pip code, then things might be different (not really, see below) but a vendored program cannot do that.
  2. Not all modules are zip-safe. Even ignoring binaries, some modules expect to access package data via filesystem calls. Whether that's right or wrong, it's a reality and we do not want unexpected failures caused by modules that can't run from a wheel. (Even eggs had to implement a "not zip safe" flag to cover this).

@dholth
Copy link
Member

dholth commented Sep 21, 2016

I'm not convinced this is quite as bad as the old egg problem. The rwt user is more likely to have tested their published script against the zipped dependencies than the classic egg user, who may have developed everything on the filesystem only to be greeted with the unpleasant surprise of zipped deployment.

@pfmoore
Copy link
Member

pfmoore commented Sep 21, 2016

But unlike the egg problem, there's no way to say "you have to unpack this wheel to use it". So any such dependencies are straight-up unusable. (And it's way worse because unlike eggs, there's no support in wheels for binaries).

Just to note, by the way, I'm perfectly happy with the idea of rwt as a standalone utility. It's only incorporating it into pip that I'm unsure about.

@jaraco
Copy link
Member Author

jaraco commented Sep 21, 2016

It also makes it easier to pass options

Options are passed directly through to pip install. The help could be more explicit about that, but it is possible to run for example:

$ pip run -i https://devpi.net/ requests

That does mean that passing -t or --prefix would cause errors, but you could also pass --no-deps or possibly others.

That alleviates the need to do a subprocess to call into pip

I'm considering adding a call that invokes pip.main() or similar with the relevant argv.

implement it inside of pip itself

I see value in keeping rwt decoupled.

  1. pip and rwt can iterate independently. Users can grab a newer version of pip or rwt to suit their specific needs.
  2. Enforces a loose coupling. By enforcing the separation, rwt uses the advertised public API of pip and serves as an example of how other applications could use pip.
  3. Allows for separate maintenance (and access).
  4. Facilitates potential for replacement by a better implementation.
  5. Issues like command line handling don't have to interact with assumptions about command-line parsing in the pip library (other than the advertised "pass through" to install), like use of OptionParser.
  6. It would be substantially more work to restructure the functionality to suit pip invocation (than to vendor it).
  7. rwt offers functionality (and might offer more) that pip wouldn't want to support (through pip run) but which shares much of the same code.

I do see advantages of incorporating it natively:

  1. It would feel more like a first-class feature of pip and would be maintained by the same team.
  2. Supported install options would be explicitly (and separately) maintained, and possibly linked.

Overall it seems like vendoring is the better approach, but I'm open to native incorporation. May I suggest provisionally accepting the command using the vendored library and defer the potential native incorporation as a subsequent change as demand dictates?

It's only incorporating it into pip that I'm unsure about.

I'd be just as happy with pip requiring rwt rather than vendoring it. I see a small advantage to pip run (the clarity in the name), but a big advantage to solving the bootstrapping challenge.

@pfmoore
Copy link
Member

pfmoore commented Sep 21, 2016

I'd be just as happy with pip requiring rwt rather than vendoring it. I see a small advantage to pip run (the clarity in the name), but a big advantage to solving the bootstrapping challenge.

You misunderstood me. by "Incorporating into pip" I meant "having a pip run command that invokes rwt (whether vendored or native)". I'm not too convinced by the bootstrapping argument - having to one-off do pip install rwt isn't exactly a hardship - and I still see rwt as more akin to virtualenv than to pip.

I think we need some more compelling justifications as to why this command needs to be spelled pip run rather than rwt. So far, all I see is "it'll be available by default in all Python installs", and I'm uncomfortable with setting a precedent that getting made into a pip subcommand is a shortcut to being distributed with Python. After all, the whole point of pip is to remove the need for things to be bundled with Python.

@jaraco
Copy link
Member Author

jaraco commented Sep 21, 2016

You misunderstood me.

That's how I understood you. I do see the corollary to virtualenv. The biggest difference is that rwt is meant to be a bootstrapping end-user tool, whereas virtualenv is more of a developer tool. The target audience for rwt has a lot less experience with Python, maybe none, but it gives users like myself the ability to give a one-liner to run this script or that command that an experienced user can just run, without the concerns about privileges and environments and pre-requisites. By making pip install rwt a pre-requisite, it brings back all of the potential ways that could fail, so raises the usability bar.

@xavfernandez xavfernandez added the type: enhancement Improvements to functionality label Oct 12, 2016
@anthrotype
Copy link

What is the status of this? I'd love one day to see rwt integrated into pip as pip run.

@jaraco
Copy link
Member Author

jaraco commented Jan 22, 2017

Expanding on what I wrote last, about raising the usability bar, often a user finds himself in an access-limited scenario, where he/she has access to Python/pip but not much more. Installing packages, even rwt, is problemmatic as it's not always obvious where to install. The only real option is --user, which has its own complications (where are scripts installed varies quite a bit by platform). Providing pip run gives users a straightforward way to invoke a specialized invocation of pip install for transient needs.

@jaraco
Copy link
Member Author

jaraco commented Feb 1, 2017

Here's another case where @dstufft might have used pip run. In the recent TLS 1.2 announcement, he gives instructions on how to check TLS versions. The instructions require requests to run. So the instructions are given:

Python 2:

python2 -m pip install --upgrade requests
python2 -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

Or Python 3:

python3 -m pip install --upgrade requests
python3 -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

In these instructions, we're asking end-users to not only install, but possibly update the version of requests in their system site packages (or maybe implicit user site packages) and not giving any instructions on how to undo the change. In practice, this won't be a huge issue, but how much nicer would it be to give a more concise, single-line command that doesn't mutate the system state:

Python 2: 

python2 -m pip run requests -- -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

Or Python 3:

python3 -m pip run requests -- -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

If pip run were something that were generally available, it would enable these one-off, non-invasive usages.

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Apr 1, 2017
@jaraco
Copy link
Member Author

jaraco commented Apr 3, 2017

As much as I'd like to see the behavior added, it seems others don't see the value, so I'm going to drop it.

@jaraco jaraco closed this Apr 3, 2017
@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Jun 3, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jun 3, 2019
@chrahunt
Copy link
Member

Revived in #7925.

@pradyunsg pradyunsg removed the needs rebase or merge PR has conflicts with current master label Apr 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation type: enhancement Improvements to functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants