Compare commits

..

70 Commits

Author SHA1 Message Date
Kenneth Reitz 5645a433dc Merge remote-tracking branch 'origin/master' 2014-02-19 11:59:07 -05:00
Kenneth Reitz 715ab8b96a Update to Setuptools 2.1 and Pip 1.5.2
So seamless.
2014-02-19 11:59:02 -05:00
kennethreitz b7f1157693 Merge pull request #118 from uniphil/master
fix url to testing buildpack
2014-02-14 13:58:49 -05:00
Phil Schleihauf ae7b6fc715 fix url to testing buildpack 2014-02-14 13:56:49 -05:00
Kenneth Reitz e0c3b72950 update runtime docs, thanks @uniphil!
#117
2014-02-14 13:41:34 -05:00
Kenneth Reitz 566f7f4555 new buildpack env standard 2014-01-21 17:47:05 -05:00
Kenneth Reitz 4ff62b2b41 sticky python versions bugfix 2014-01-17 17:06:54 -08:00
Kenneth Reitz d47970fd81 sticky runtimes 2014-01-17 16:47:55 -08:00
Kenneth Reitz 69bdca063f fix sub-env for when env file is not present 2013-12-20 17:15:24 -05:00
Kenneth Reitz 63cea99415 chmod +x 2013-12-20 16:48:34 -05:00
Kenneth Reitz 5ecd27e3b8 chmod +x 2013-12-13 16:03:39 -08:00
Kenneth Reitz 206a2dbc04 third argument support for envs in compile 2013-12-13 15:48:39 -08:00
kennethreitz 2a083791b6 Merge pull request #113 from zyegfryed/patch-3
Fixed Python runtime according to the official Heroku doc
2013-11-14 19:59:56 -08:00
kennethreitz d5b2b0b464 Merge pull request #114 from catsby/update_default_postgresql
Update Heroku Postgresql default add-on to hobby-dev
2013-11-14 19:59:40 -08:00
Clint Shryock 2eab1ad845 Update Heroku Postgresql default add-on to hobby-dev 2013-11-12 14:10:52 -06:00
Sébastien Fievet 2b16420d41 Fixed Python runtime according to the official Heroku doc
See https://devcenter.heroku.com/articles/python-runtimes#supported-runtimes
2013-11-04 09:24:36 +01:00
kennethreitz 9fa0889499 Update bpwatch 2013-10-17 15:43:51 -04:00
kennethreitz 99b17fabeb Merge pull request #105 from bacongobbler/patch-1
update shebang to use python2 for bpwatch
2013-10-17 11:37:00 -07:00
kennethreitz 933d3014d7 Merge pull request #103 from grosskur/library-path-fix
Make vendored libraries available at compile time (fixes #57)
2013-10-17 11:36:34 -07:00
Kenneth Reitz 018e0f31de Merge remote-tracking branch 'origin/master' 2013-09-01 06:27:46 +05:30
Kenneth Reitz cf1647e937 no --use-mirrors 2013-09-01 06:27:18 +05:30
Matthew Fisher b9f154bf38 update shebang to use python2 for bpwatch 2013-08-27 16:49:55 -07:00
Kenneth Reitz 4cc18ce0af Merge pull request #104 from zyegfryed/patch-1
Typo
2013-08-27 09:12:23 -07:00
Sébastien Fievet f5ea1c24a3 Typo 2013-08-25 18:41:46 +02:00
Kenneth Reitz 952b0bb735 v28 2013-08-14 22:02:11 -04:00
Kenneth Reitz 8b7edad8a2 bugfix for bpwatch 2013-08-14 22:01:16 -04:00
Kenneth Reitz 02787ac910 update bpwatch.zip for request_id 2013-08-14 21:19:12 -04:00
Alan Grosskurth bcc3ba09ca Make vendored libraries available at compile time (fixes #57)
When building, BUILD_DIR is set to a temporary directory. Vendored
libraries (e.g., pylibmc) are downloaded and unpacked in
$BUILD_DIR/.heroku/vendor/lib, but this is not currently in
LIBRARY_PATH or LD_LIBRARY_PATH.

Fix this by doing the following:

* Add $BUILD_DIR/.heroku/vendor/lib to LIBRARY_PATH/LD_LIBRARY_PATH

* Add $BUILD_DIR/.heroku/vendor/include to
  C_INCLUDE_PATH/CPLUS_INCLUDE_PATH

* Add $BUILD_DIR/.heroku/vendor/bin to PATH, so vendored commands can
  be used at compile time (e.g., curl-config)

* Add $BUILD_DIR/.heroku/vendor/lib/pkg-config to PKG_CONFIG_PATH, so
  vendored packages can be found with pkg-config
2013-08-14 16:59:31 -07:00
Kenneth Reitz 31e65dc58b new bpwatch 2013-07-17 17:04:37 -04:00
Kenneth Reitz 9a227e6c73 v24 2013-07-17 08:38:47 -04:00
Kenneth Reitz ddc9c24d34 deep-rm for normal builds 2013-07-17 08:34:14 -04:00
Kenneth Reitz 42488a2be7 deep-rm 2013-07-17 08:33:36 -04:00
Kenneth Reitz 839486c25b make things pretty, skip anvil build for normal runs 2013-07-17 08:25:17 -04:00
Kenneth Reitz 5d56200179 bugfix for legacy apps + usr_env_compile 2013-07-16 16:54:33 -04:00
Kenneth Reitz fef1d4f7c0 instrumentation 2013-07-16 15:10:49 -04:00
Kenneth Reitz 43defcc17e Revert "skip anvil steps that slow things down"
This reverts commit f78460e2a7.
2013-07-16 00:30:00 -04:00
Kenneth Reitz f78460e2a7 skip anvil steps that slow things down 2013-06-26 14:00:13 -04:00
Kenneth Reitz 3448923b69 collectstatic logic improvements 2013-06-26 13:58:00 -04:00
Kenneth Reitz 58a13bc268 Merge pull request #93 from bacongobbler/master
Add Django v1.5 testing support with Heroku
2013-06-05 13:09:42 -07:00
bacongobbler c18038f986 added Django v1.5 tests 2013-05-22 17:50:52 -07:00
bacongobbler d4356a1f4c added requirements.txt with django v1.5 2013-05-22 17:41:34 -07:00
bacongobbler 3c8f478b65 added django 1.5 skeleton for testing 2013-05-22 17:37:12 -07:00
Kenneth Reitz 23493302e6 Update Readme.md 2013-04-30 13:31:53 -03:00
Kenneth Reitz 35ceaf728d Merge pull request #90 from buildingenergy/master
Store changes made in post_compile in the cache.
2013-04-27 17:59:46 -07:00
Steven Skoczen 5c9412fc33 moves cache storage until after the post_compile hook. 2013-04-26 16:27:00 -07:00
Kenneth Reitz 825c9329eb Merge pull request #89 from gregburek/use-pg-dev-db
Remove shared db from release and add heroku-postgresql dev db
2013-04-23 23:53:21 -07:00
gregburek 9ebb990716 Remove shared db and add heroku-postgresql dev db 2013-04-23 23:50:54 -07:00
Kenneth Reitz f964209589 Merge remote-tracking branch 'origin/master' 2013-04-10 08:01:34 -07:00
Kenneth Reitz 2e699d392e Merge pull request #86 from manojlds/master
Fixing the compile hook scripts paths
2013-04-10 07:54:51 -07:00
manojlds 431ecee509 Using the bin path at root of pwd
The compile script is run with the root of the git repo of the project
being pushed as the working directory.

$BIN_DIR is pointing to the bin directory of the buildpack which is not
where you would want to put the pre and post compile hooks.

Changing back to the old convention of looking for the hooks from the
bin directory at the root of the project.
2013-04-10 15:06:51 +05:30
Kenneth Reitz 90696215ae python-2.7.4 default version 2013-04-09 15:03:27 -07:00
Kenneth Reitz 5b55261700 Merge pull request #73 from incuna/hooks-fix
Use $BIN_DIR in hooks.
2013-04-09 10:25:13 -07:00
Kenneth Reitz 727ff90acf Merge pull request #83 from aljosa/distribute_version_upgrade
upgraded distribute to v0.6.36.
2013-04-08 15:10:22 -07:00
Aljosa Mohorovic 0060fdacd8 upgraded distribute to v0.6.36.
fixes pip v1.3.1 installation issue
2013-04-08 18:00:53 +02:00
Kenneth Reitz 85ad1fa988 Merge pull request #78 from streeter/master
Allow pylibmc to be commented out in the requirements file
2013-03-21 00:53:49 -07:00
Kenneth Reitz 56c022ca41 remove bunk files 2013-03-20 03:44:19 -07:00
Chris Streeter f68e0989ea Allow pylibmc to be disabled. 2013-03-12 22:24:08 -07:00
Kenneth Reitz 7381117bb8 working dir fix 2013-03-07 23:11:06 -05:00
Kenneth Reitz c9209ebb3d fixes and cleanups 2013-03-07 21:10:46 -05:00
Kenneth Reitz 35345d11f5 run hash after install 2013-03-07 21:05:59 -05:00
Kenneth Reitz 6ee17b4c26 debug 2013-03-07 21:02:54 -05:00
Kenneth Reitz 86267f93a1 hash -r 2013-03-07 21:01:09 -05:00
Kenneth Reitz 50642e7069 check for fresh python before we try to run pip 2013-03-07 21:00:01 -05:00
Kenneth Reitz 8349f291d2 print updated pip version at install time 2013-03-07 20:52:36 -05:00
Kenneth Reitz 1aad21382e update pip if it is out of date 2013-03-07 20:50:51 -05:00
Kenneth Reitz 686ee087a5 use new pip/distribute 2013-03-07 20:40:32 -05:00
Kenneth Reitz f137ba213a sanity check 2013-03-07 20:38:06 -05:00
Kenneth Reitz 5ae51010cc update pip to v0.3.1 2013-03-07 20:37:40 -05:00
Kenneth Reitz 29d8e7f670 update distribute to v0.6.35 2013-03-07 20:36:03 -05:00
Marc Tamlyn 5be3e0ce52 Use $BIN_DIR in hooks. 2013-01-11 10:54:05 +00:00
521 changed files with 79897 additions and 24913 deletions
-21
View File
@@ -1,21 +0,0 @@
tests:
./bin/test
docs:
mkdir -p site
shocco -t 'Python Buildpack Compiler' ./bin/compile > site/index.html
shocco -t 'Django Buildpack Compiler' ./bin/steps/django > site/django.html
shocco -t 'Python Buildpack Detector' ./bin/detect > site/detect.html
shocco -t 'Pylibmc Buildpack Compiler' ./bin/steps/pylibmc > site/pylibmc.html
shocco -t 'Python Buildpack Changelog' ./Changelog.md > site/changelog.html
site: docs
cd site && git add -A && git commit -m 'update' && git push heroku master
pip:
git clone git@github.com:kennethreitz/pip.git --branch heroku --depth 1
rm -fr vendor/virtualenv-1.8.4/virtualenv_support/pip-1.2.1.tar.gz
rm -fr pip/.git
tar -pczf vendor/virtualenv-1.8.4/virtualenv_support/pip-1.2.1.tar.gz pip
rm -fr pip
+13 -11
View File
@@ -19,11 +19,11 @@ Example usage:
...
-----> Fetching custom git buildpack... done
-----> Python app detected
-----> No runtime.txt provided; assuming python-2.7.3.
-----> Preparing Python runtime (python-2.7.3)
-----> Installing Distribute (0.6.34)
-----> Installing Pip (1.2.1)
-----> Installing dependencies using Pip (1.2.1)
-----> No runtime.txt provided; assuming python-2.7.6.
-----> Preparing Python runtime (python-2.7.6)
-----> Installing Setuptools (2.1)
-----> Installing Pip (1.5.2)
-----> Installing dependencies using Pip (1.5.2)
Downloading/unpacking Flask==0.7.2 (from -r requirements.txt (line 1))
Downloading/unpacking Werkzeug>=0.6.1 (from Flask==0.7.2->-r requirements.txt (line 1))
Downloading/unpacking Jinja2>=2.4 (from Flask==0.7.2->-r requirements.txt (line 1))
@@ -35,9 +35,9 @@ You can also add it to upcoming builds of an existing application:
$ heroku config:add BUILDPACK_URL=git://github.com/heroku/heroku-buildpack-python.git
The buildpack will detect your app as Python if it has the file `requirements.txt` in the root.
The buildpack will detect your app as Python if it has the file `requirements.txt` in the root.
It will use Pip to install your dependencies, vendoring a copy of the Python runtime into your slug.
It will use Pip to install your dependencies, vendoring a copy of the Python runtime into your slug.
Specify a Runtime
-----------------
@@ -45,10 +45,12 @@ Specify a Runtime
You can also provide arbitrary releases Python with a `runtime.txt` file.
$ cat runtime.txt
python-3.3.0
python-3.3.3
Runtime options include:
- python-2.7.3
- python-3.3.0
- python-2.7.6
- python-3.3.3
- pypy-1.9 (experimental)
Other [unsupported runtimes](https://github.com/kennethreitz/python-versions/tree/master/formula) are available as well.
+136 -52
View File
@@ -2,8 +2,7 @@
# Usage:
#
# $ bin/compile <build-dir> <cache-dir>
# $ bin/compile <build-dir> <cache-dir> <env-path>
# Fail fast and fail hard.
set -eo pipefail
@@ -16,6 +15,8 @@ BIN_DIR=$(cd $(dirname $0); pwd) # absolute path
ROOT_DIR=$(dirname $BIN_DIR)
BUILD_DIR=$1
CACHE_DIR=$2
ENV_DIR=$3
CACHED_DIRS=".heroku"
@@ -24,13 +25,30 @@ VIRTUALENV_LOC=".heroku/venv"
LEGACY_TRIGGER="lib/python2.7"
PROFILE_PATH="$BUILD_DIR/.profile.d/python.sh"
# Python version. This will be used in the future to specify custom Pythons.
DEFAULT_PYTHON_VERSION="python-2.7.3"
DEFAULT_PYTHON_VERSION="python-2.7.6"
PYTHON_EXE="/app/.heroku/python/bin/python"
PIP_VERSION="1.5.2"
SETUPTOOLS_VERSION="2.1"
# Setup bpwatch
export PATH=$PATH:$ROOT_DIR/vendor/bpwatch
LOGPLEX_KEY="t.b396af7f-ad75-4643-8b9e-ebb288acc624"
export BPWATCH_STORE_PATH=$CACHE_DIR/bpwatch.json
BUILDPACK_VERSION=v28
# Support Anvil Build_IDs
[ ! "$REQUEST_ID" ] && REQUEST_ID=$SLUG_ID
# Sanitizing environment variables.
unset GIT_DIR PYTHONHOME PYTHONPATH LD_LIBRARY_PATH LIBRARY_PATH
bpwatch init $LOGPLEX_KEY
bpwatch build python $BUILDPACK_VERSION $REQUEST_ID
TMP_APP_DIR=$CACHE_DIR/tmp_app_dir
bpwatch start compile
# We'll need to send these statics to other scripts we `source`.
export BUILD_DIR CACHE_DIR BIN_DIR PROFILE_PATH
@@ -42,28 +60,41 @@ APP_DIR='/app'
TMP_APP_DIR=$CACHE_DIR/tmp_app_dir
# Copy Anvil app dir to temporary storage...
mkdir -p $TMP_APP_DIR
deep-mv $APP_DIR $TMP_APP_DIR
bpwatch start anvil_appdir_stage
if [ "$SLUG_ID" ]; then
mkdir -p $TMP_APP_DIR
deep-mv $APP_DIR $TMP_APP_DIR
else
deep-rm $APP_DIR
fi
bpwatch stop anvil_appdir_stage
# Copy Application code in.
deep-mv $BUILD_DIR $APP_DIR
bpwatch start appdir_stage
deep-mv $BUILD_DIR $APP_DIR
bpwatch stop appdir_stage
# Set new context.
ORIG_BUILD_DIR=$BUILD_DIR
BUILD_DIR=$APP_DIR
# Prepend proper path buildpack use.
export PATH=$BUILD_DIR/.heroku/python/bin:$PATH
export PATH=$BUILD_DIR/.heroku/python/bin:$BUILD_DIR/.heroku/vendor/bin:$PATH
export PYTHONUNBUFFERED=1
export LANG=en_US.UTF-8
export LIBRARY_PATH=/app/.heroku/vendor/lib
export LD_LIBRARY_PATH=/app/.heroku/vendor/lib
export C_INCLUDE_PATH=/app/.heroku/vendor/include:$BUILD_DIR/.heroku/vendor/include
export CPLUS_INCLUDE_PATH=/app/.heroku/vendor/include:$BUILD_DIR/.heroku/vendor/include
export LIBRARY_PATH=/app/.heroku/vendor/lib:$BUILD_DIR/.heroku/vendor/lib
export LD_LIBRARY_PATH=/app/.heroku/vendor/lib:$BUILD_DIR/.heroku/vendor/lib
export PKG_CONFIG_PATH=/app/.heroku/vendor/lib/pkg-config:$BUILD_DIR/.heroku/vendor/lib/pkg-config
# Switch to the repo's context.
cd $BUILD_DIR
# Experimental pre_compile hook.
source $BIN_DIR/steps/hooks/pre_compile
bpwatch start pre_compile
source $BIN_DIR/steps/hooks/pre_compile
bpwatch stop pre_compile
# If no requirements given, assume `setup.py develop`.
if [ ! -f requirements.txt ]; then
@@ -71,6 +102,11 @@ if [ ! -f requirements.txt ]; then
echo "-e ." > requirements.txt
fi
# Sticky runtimes.
if [ -f $CACHE_DIR/.heroku/python-version ]; then
DEFAULT_PYTHON_VERSION=$(cat $CACHE_DIR/.heroku/python-version)
fi
# If no runtime given, assume default version.
if [ ! -f runtime.txt ]; then
puts-step "No runtime.txt provided; assuming $DEFAULT_PYTHON_VERSION."
@@ -81,13 +117,17 @@ fi
mkdir -p $CACHE_DIR
# Purge "old-style" virtualenvs.
[ -d $CACHE_DIR/$LEGACY_TRIGGER ] && rm -fr $CACHE_DIR/.heroku/bin $CACHE_DIR/.heroku/lib $CACHE_DIR/.heroku/include
[ -d $CACHE_DIR/$VIRTUALENV_LOC ] && rm -fr $CACHE_DIR/.heroku/venv $CACHE_DIR/.heroku/src
bpwatch start clear_old_venvs
[ -d $CACHE_DIR/$LEGACY_TRIGGER ] && rm -fr $CACHE_DIR/.heroku/bin $CACHE_DIR/.heroku/lib $CACHE_DIR/.heroku/include
[ -d $CACHE_DIR/$VIRTUALENV_LOC ] && rm -fr $CACHE_DIR/.heroku/venv $CACHE_DIR/.heroku/src
bpwatch stop clear_old_venvs
# Restore old artifacts from the cache.
for dir in $CACHED_DIRS; do
cp -R $CACHE_DIR/$dir . &> /dev/null || true
done
bpwatch start restore_cache
for dir in $CACHED_DIRS; do
cp -R $CACHE_DIR/$dir . &> /dev/null || true
done
bpwatch stop restore_cache
set +e
# Create set-aside `.heroku` folder.
@@ -102,8 +142,10 @@ PYTHON_VERSION=$(cat runtime.txt)
# Install Python.
if [ -f .heroku/python-version ]; then
if [ ! $(cat .heroku/python-version) = $PYTHON_VERSION ]; then
puts-step "Found $(cat .heroku/python-version), removing."
rm -fr .heroku/python
bpwatch start uninstall_python
puts-step "Found $(cat .heroku/python-version), removing."
rm -fr .heroku/python
bpwatch stop uninstall_python
else
SKIP_INSTALL=1
fi
@@ -111,62 +153,86 @@ fi
if [ ! "$SKIP_INSTALL" ]; then
puts-step "Preparing Python runtime ($PYTHON_VERSION)"
curl http://envy-versions.s3.amazonaws.com/$PYTHON_VERSION.tar.bz2 -s | tar jx &> /dev/null
if [[ $? != 0 ]] ; then
puts-warn "Requested runtime ($PYTHON_VERSION) was not found."
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
exit 1
fi
mv python .heroku/python
bpwatch start install_python
puts-step "Preparing Python runtime ($PYTHON_VERSION)"
curl http://envy-versions.s3.amazonaws.com/$PYTHON_VERSION.tar.bz2 -s | tar jx &> /dev/null
if [[ $? != 0 ]] ; then
puts-warn "Requested runtime ($PYTHON_VERSION) was not found."
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
exit 1
fi
mv python .heroku/python
bpwatch stop install_python
# Record for future reference.
echo $PYTHON_VERSION > .heroku/python-version
WORKING_DIR=$(pwd)
# Prepare it for the real world
puts-step "Installing Distribute (0.6.34)"
cd $ROOT_DIR/vendor/distribute-0.6.34/
python setup.py install &> /dev/null
cd $WORKING_DIR
puts-step "Installing Pip (1.2.1)"
cd $ROOT_DIR/vendor/pip-1.2.1/
python setup.py install &> /dev/null
cd $WORKING_DIR
FRESH_PYTHON=true
hash -r
else
puts-step "Using Python runtime ($PYTHON_VERSION)"
fi
# If Pip isn't up to date:
if [ "$FRESH_PYTHON" ] || [[ ! $(pip --version) == *$PIP_VERSION* ]]; then
WORKING_DIR=$(pwd)
bpwatch start prepare_environment
bpwatch start install_setuptools
# Prepare it for the real world
puts-step "Installing Setuptools ($SETUPTOOLS_VERSION)"
cd $ROOT_DIR/vendor/setuptools-$SETUPTOOLS_VERSION/
python setup.py install &> /dev/null
cd $WORKING_DIR
bpwatch stop install_setuptoools
bpwatch start install_pip
puts-step "Installing Pip ($PIP_VERSION)"
cd $ROOT_DIR/vendor/pip-$PIP_VERSION/
python setup.py install &> /dev/null
cd $WORKING_DIR
bpwatch stop install_pip
bpwatch stop prepare_environment
fi
set -e
hash -r
# Pylibmc support.
# See [`bin/steps/pylibmc`](pylibmc.html).
source $BIN_DIR/steps/pylibmc
bpwatch start pylibmc_install
source $BIN_DIR/steps/pylibmc
bpwatch stop pylibmc_install
# Install Mercurial if it appears to be required.
if (grep -Fiq "hg+" requirements.txt) then
pip install --use-mirrors mercurial | cleanup | indent
bpwatch start mercurial_install
/app/.heroku/python/bin/pip install mercurial | cleanup | indent
bpwatch stop mercurial_install
fi
# Install dependencies with Pip.
puts-step "Installing dependencies using Pip (1.2.1)"
pip install --use-mirrors -r requirements.txt --exists-action=w --src=./.heroku/src | cleanup | indent
puts-step "Installing dependencies using Pip ($PIP_VERSION)"
[ ! "$FRESH_PYTHON" ] && bpwatch start pip_install
[ "$FRESH_PYTHON" ] && bpwatch start pip_install_first
/app/.heroku/python/bin/pip install -r requirements.txt --exists-action=w --src=./.heroku/src | cleanup | indent
[ ! "$FRESH_PYTHON" ] && bpwatch stop pip_install
[ "$FRESH_PYTHON" ] && bpwatch stop pip_install_first
# Django collectstatic support.
source $BIN_DIR/steps/collectstatic
bpwatch start collectstatic
sub-env $BIN_DIR/steps/collectstatic
bpwatch stop collectstatic
# ### Finalize
#
# Store new artifacts in cache.
for dir in $CACHED_DIRS; do
rm -rf $CACHE_DIR/$dir
cp -R $dir $CACHE_DIR/
done
# Set context environment variables.
set-env PATH '$HOME/.heroku/python/bin:$PATH'
set-env PYTHONUNBUFFERED true
@@ -179,9 +245,27 @@ set-default-env PYTHONPATH /app/
# Experimental post_compile hook.
source $BIN_DIR/steps/hooks/post_compile
bpwatch start post_compile
source $BIN_DIR/steps/hooks/post_compile
bpwatch stop post_compile
# Store new artifacts in cache.
bpwatch start dump_cache
for dir in $CACHED_DIRS; do
rm -rf $CACHE_DIR/$dir
cp -R $dir $CACHE_DIR/
done
bpwatch stop dump_cache
# ### Fin.
bpwatch start appdir_commit
deep-mv $BUILD_DIR $ORIG_BUILD_DIR
bpwatch stop appdir_commit
deep-mv $BUILD_DIR $ORIG_BUILD_DIR
deep-mv $TMP_APP_DIR $APP_DIR
bpwatch start anvil_appdir_commit
if [ "$SLUG_ID" ]; then
deep-mv $TMP_APP_DIR $APP_DIR
fi
bpwatch stop anvil_appdir_commit
bpwatch stop compile
+2 -2
View File
@@ -18,6 +18,6 @@ if [[ $MANAGE_FILE ]]; then
cat <<EOF
addons:
shared-database:5mb
heroku-postgresql:hobby-dev
EOF
fi
fi
Regular → Executable
+3 -5
View File
@@ -7,13 +7,11 @@ indent() {
}
MANAGE_FILE=$(find . -maxdepth 3 -type f -name 'manage.py' | head -1)
MANAGE_FILE=${MANAGE_FILE:2}
MANAGE_FILE=${MANAGE_FILE:-fakepath}
if [ -f .heroku/collectstatic_disabled ]; then
DISABLE_COLLECTSTATIC=1
fi
[ -f .heroku/collectstatic_disabled ] && DISABLE_COLLECTSTATIC=1
if [ ! "$DISABLE_COLLECTSTATIC" ]; then
if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ]; then
set +e
# Check if collectstatic is configured properly.
Regular → Executable
+1 -1
View File
@@ -3,5 +3,5 @@
if [ -f bin/post_compile ]; then
echo "-----> Running post-compile hook"
chmod +x bin/post_compile
bin/post_compile
sub-env bin/post_compile
fi
Regular → Executable
+1 -1
View File
@@ -3,5 +3,5 @@
if [ -f bin/pre_compile ]; then
echo "-----> Running pre-compile hook"
chmod +x bin/pre_compile
bin/pre_compile
sub-env bin/pre_compile
fi
+1 -1
View File
@@ -16,7 +16,7 @@ VENDORED_MEMCACHED="http://cl.ly/0a191R3K160t1w1P0N25/vendor-libmemcached.tar.gz
source $BIN_DIR/utils
# If pylibmc exists within requirements, use vendored libmemcached.
if (grep -Fiq "pylibmc" requirements.txt) then
if (grep -Eiq "^\s*pylibmc" requirements.txt) then
echo "-----> Noticed pylibmc. Bootstrapping libmemcached."
cd .heroku
+7 -1
View File
@@ -2,7 +2,7 @@
#
# Create a Heroku app with the following buildpack:
# https://github.com/ddollar/buildpack-tet
# https://github.com/ddollar/buildpack-test
#
# Push this Python buildpack to that Heroku app to
# run the tests.
@@ -20,6 +20,12 @@ testDetectWithEmptyReqs() {
assertCapturedSuccess
}
testDetectDjango15() {
detect "django-1.5-skeleton"
assertCapturedEquals "Python"
assertCapturedSuccess
}
testDetectDjango14() {
detect "django-1.4-skeleton"
assertCapturedEquals "Python"
-3
View File
@@ -1,3 +0,0 @@
Script started on Wed Dec 19 22:40:46 2012
%
+26
View File
@@ -52,3 +52,29 @@ function deep-mv (){
rm -fr $1/!(tmp)
find -H $1 -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec rm -fr '{}' \;
}
# Does some serious deleting.
function deep-rm (){
rm -fr $1/!(tmp)
find -H $1 -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec rm -fr '{}' \;
}
sub-env() {
WHITELIST=${2:-''}
BLACKLIST=${3:-'^(GIT_DIR|PYTHONHOME|PYTHONPATH|LD_LIBRARY_PATH|LIBRARY_PATH|PATH)$'}
(
if [ -d "$ENV_DIR" ]; then
for e in $(ls $ENV_DIR); do
echo "$e" | grep -E "$WHITELIST" | grep -qvE "$BLACKLIST" &&
export "$e=$(cat $ENV_DIR/$e)"
:
done
fi
$1
)
}
@@ -0,0 +1,156 @@
# Django settings for haystack project.
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '', # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': '',
'PASSWORD': '',
'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
}
}
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = '@w-1$9#jh05!qvbh#1k)c4=w9llcq116f$5(4&s_c)n4@%n=pc'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'haystack.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'haystack.wsgi.application'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
+17
View File
@@ -0,0 +1,17 @@
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'haystack.views.home', name='home'),
# url(r'^haystack/', include('haystack.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# url(r'^admin/', include(admin.site.urls)),
)
+32
View File
@@ -0,0 +1,32 @@
"""
WSGI config for haystack project.
This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.
Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.
"""
import os
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
# if running multiple sites in the same mod_wsgi process. To fix this, use
# mod_wsgi daemon mode with each site in its own daemon process, or use
# os.environ["DJANGO_SETTINGS_MODULE"] = "haystack.settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "haystack.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "haystack.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
@@ -0,0 +1 @@
django==1.5
+2 -1
View File
@@ -1 +1,2 @@
httpbin
requests
distribute==0.6.49
+1 -1
View File
@@ -1 +1 @@
python-2.7.3
python-3.3.2
Vendored Executable
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env python2
import os
import sys
DEFAULT_PATH = '{0}.zip'.format(os.path.abspath(__file__))
BPWATCH_DISTRO_PATH = os.environ.get('BPWATCH_DISTRO_PATH', DEFAULT_PATH)
sys.path.insert(0, BPWATCH_DISTRO_PATH)
import bp_cli
bp_cli.main()
BIN
View File
Binary file not shown.
-487
View File
@@ -1,487 +0,0 @@
=======
CHANGES
=======
----------
Unreleased
----------
+ Issue #341: 0.6.33 fails to build under python 2.4
------
0.6.33
------
* Fix 2 errors with Jython 2.5.
* Fix 1 failure with Jython 2.5 and 2.7.
* Disable workaround for Jython scripts on Linux systems.
* Issue #336: `setup.py` no longer masks failure exit code when tests fail.
* Fix issue in pkg_resources where try/except around a platform-dependent
import would trigger hook load failures on Mercurial. See pull request 32
for details.
* Issue #341: Fix a ResourceWarning.
------
0.6.32
------
* Fix test suite with Python 2.6.
* Fix some DeprecationWarnings and ResourceWarnings.
* Issue #335: Backed out `setup_requires` superceding installed requirements
until regression can be addressed.
------
0.6.31
------
* Issue #303: Make sure the manifest only ever contains UTF-8 in Python 3.
* Issue #329: Properly close files created by tests for compatibility with
Jython.
* Work around Jython bugs `#1980 <http://bugs.jython.org/issue1980>`_ and
`#1981 <http://bugs.jython.org/issue1981>`_.
* Issue #334: Provide workaround for packages that reference `sys.__stdout__`
such as numpy does. This change should address
`virtualenv #359 <https://github.com/pypa/virtualenv/issues/359>`_ as long
as the system encoding is UTF-8 or the IO encoding is specified in the
environment, i.e.::
PYTHONIOENCODING=utf8 pip install numpy
* Fix for encoding issue when installing from Windows executable on Python 3.
* Issue #323: Allow `setup_requires` requirements to supercede installed
requirements. Added some new keyword arguments to existing pkg_resources
methods. Also had to updated how __path__ is handled for namespace packages
to ensure that when a new egg distribution containing a namespace package is
placed on sys.path, the entries in __path__ are found in the same order they
would have been in had that egg been on the path when pkg_resources was
first imported.
------
0.6.30
------
* Issue #328: Clean up temporary directories in distribute_setup.py.
* Fix fatal bug in distribute_setup.py.
------
0.6.29
------
* Pull Request #14: Honor file permissions in zip files.
* Issue #327: Merged pull request #24 to fix a dependency problem with pip.
* Merged pull request #23 to fix https://github.com/pypa/virtualenv/issues/301.
* If Sphinx is installed, the `upload_docs` command now runs `build_sphinx`
to produce uploadable documentation.
* Issue #326: `upload_docs` provided mangled auth credentials under Python 3.
* Issue #320: Fix check for "createable" in distribute_setup.py.
* Issue #305: Remove a warning that was triggered during normal operations.
* Issue #311: Print metadata in UTF-8 independent of platform.
* Issue #303: Read manifest file with UTF-8 encoding under Python 3.
* Issue #301: Allow to run tests of namespace packages when using 2to3.
* Issue #304: Prevent import loop in site.py under Python 3.3.
* Issue #283: Reenable scanning of `*.pyc` / `*.pyo` files on Python 3.3.
* Issue #299: The develop command didn't work on Python 3, when using 2to3,
as the egg link would go to the Python 2 source. Linking to the 2to3'd code
in build/lib makes it work, although you will have to rebuild the module
before testing it.
* Issue #306: Even if 2to3 is used, we build in-place under Python 2.
* Issue #307: Prints the full path when .svn/entries is broken.
* Issue #313: Support for sdist subcommands (Python 2.7)
* Issue #314: test_local_index() would fail an OS X.
* Issue #310: Non-ascii characters in a namespace __init__.py causes errors.
* Issue #218: Improved documentation on behavior of `package_data` and
`include_package_data`. Files indicated by `package_data` are now included
in the manifest.
* `distribute_setup.py` now allows a `--download-base` argument for retrieving
distribute from a specified location.
------
0.6.28
------
* Issue #294: setup.py can now be invoked from any directory.
* Scripts are now installed honoring the umask.
* Added support for .dist-info directories.
* Issue #283: Fix and disable scanning of `*.pyc` / `*.pyo` files on
Python 3.3.
------
0.6.27
------
* Support current snapshots of CPython 3.3.
* Distribute now recognizes README.rst as a standard, default readme file.
* Exclude 'encodings' modules when removing modules from sys.modules.
Workaround for #285.
* Issue #231: Don't fiddle with system python when used with buildout
(bootstrap.py)
------
0.6.26
------
* Issue #183: Symlinked files are now extracted from source distributions.
* Issue #227: Easy_install fetch parameters are now passed during the
installation of a source distribution; now fulfillment of setup_requires
dependencies will honor the parameters passed to easy_install.
------
0.6.25
------
* Issue #258: Workaround a cache issue
* Issue #260: distribute_setup.py now accepts the --user parameter for
Python 2.6 and later.
* Issue #262: package_index.open_with_auth no longer throws LookupError
on Python 3.
* Issue #269: AttributeError when an exception occurs reading Manifest.in
on late releases of Python.
* Issue #272: Prevent TypeError when namespace package names are unicode
and single-install-externally-managed is used. Also fixes PIP issue
449.
* Issue #273: Legacy script launchers now install with Python2/3 support.
------
0.6.24
------
* Issue #249: Added options to exclude 2to3 fixers
------
0.6.23
------
* Issue #244: Fixed a test
* Issue #243: Fixed a test
* Issue #239: Fixed a test
* Issue #240: Fixed a test
* Issue #241: Fixed a test
* Issue #237: Fixed a test
* Issue #238: easy_install now uses 64bit executable wrappers on 64bit Python
* Issue #208: Fixed parsed_versions, it now honors post-releases as noted in the documentation
* Issue #207: Windows cli and gui wrappers pass CTRL-C to child python process
* Issue #227: easy_install now passes its arguments to setup.py bdist_egg
* Issue #225: Fixed a NameError on Python 2.5, 2.4
------
0.6.21
------
* Issue #225: FIxed a regression on py2.4
------
0.6.20
------
* Issue #135: Include url in warning when processing URLs in package_index.
* Issue #212: Fix issue where easy_instal fails on Python 3 on windows installer.
* Issue #213: Fix typo in documentation.
------
0.6.19
------
* Issue 206: AttributeError: 'HTTPMessage' object has no attribute 'getheaders'
------
0.6.18
------
* Issue 210: Fixed a regression introduced by Issue 204 fix.
------
0.6.17
------
* Support 'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT' environment
variable to allow to disable installation of easy_install-${version} script.
* Support Python >=3.1.4 and >=3.2.1.
* Issue 204: Don't try to import the parent of a namespace package in
declare_namespace
* Issue 196: Tolerate responses with multiple Content-Length headers
* Issue 205: Sandboxing doesn't preserve working_set. Leads to setup_requires
problems.
------
0.6.16
------
* Builds sdist gztar even on Windows (avoiding Issue 193).
* Issue 192: Fixed metadata omitted on Windows when package_dir
specified with forward-slash.
* Issue 195: Cython build support.
* Issue 200: Issues with recognizing 64-bit packages on Windows.
------
0.6.15
------
* Fixed typo in bdist_egg
* Several issues under Python 3 has been solved.
* Issue 146: Fixed missing DLL files after easy_install of windows exe package.
------
0.6.14
------
* Issue 170: Fixed unittest failure. Thanks to Toshio.
* Issue 171: Fixed race condition in unittests cause deadlocks in test suite.
* Issue 143: Fixed a lookup issue with easy_install.
Thanks to David and Zooko.
* Issue 174: Fixed the edit mode when its used with setuptools itself
------
0.6.13
------
* Issue 160: 2.7 gives ValueError("Invalid IPv6 URL")
* Issue 150: Fixed using ~/.local even in a --no-site-packages virtualenv
* Issue 163: scan index links before external links, and don't use the md5 when
comparing two distributions
------
0.6.12
------
* Issue 149: Fixed various failures on 2.3/2.4
------
0.6.11
------
* Found another case of SandboxViolation - fixed
* Issue 15 and 48: Introduced a socket timeout of 15 seconds on url openings
* Added indexsidebar.html into MANIFEST.in
* Issue 108: Fixed TypeError with Python3.1
* Issue 121: Fixed --help install command trying to actually install.
* Issue 112: Added an os.makedirs so that Tarek's solution will work.
* Issue 133: Added --no-find-links to easy_install
* Added easy_install --user
* Issue 100: Fixed develop --user not taking '.' in PYTHONPATH into account
* Issue 134: removed spurious UserWarnings. Patch by VanLindberg
* Issue 138: cant_write_to_target error when setup_requires is used.
* Issue 147: respect the sys.dont_write_bytecode flag
------
0.6.10
------
* Reverted change made for the DistributionNotFound exception because
zc.buildout uses the exception message to get the name of the
distribution.
-----
0.6.9
-----
* Issue 90: unknown setuptools version can be added in the working set
* Issue 87: setupt.py doesn't try to convert distribute_setup.py anymore
Initial Patch by arfrever.
* Issue 89: added a side bar with a download link to the doc.
* Issue 86: fixed missing sentence in pkg_resources doc.
* Added a nicer error message when a DistributionNotFound is raised.
* Issue 80: test_develop now works with Python 3.1
* Issue 93: upload_docs now works if there is an empty sub-directory.
* Issue 70: exec bit on non-exec files
* Issue 99: now the standalone easy_install command doesn't uses a
"setup.cfg" if any exists in the working directory. It will use it
only if triggered by ``install_requires`` from a setup.py call
(install, develop, etc).
* Issue 101: Allowing ``os.devnull`` in Sandbox
* Issue 92: Fixed the "no eggs" found error with MacPort
(platform.mac_ver() fails)
* Issue 103: test_get_script_header_jython_workaround not run
anymore under py3 with C or POSIX local. Contributed by Arfrever.
* Issue 104: remvoved the assertion when the installation fails,
with a nicer message for the end user.
* Issue 100: making sure there's no SandboxViolation when
the setup script patches setuptools.
-----
0.6.8
-----
* Added "check_packages" in dist. (added in Setuptools 0.6c11)
* Fixed the DONT_PATCH_SETUPTOOLS state.
-----
0.6.7
-----
* Issue 58: Added --user support to the develop command
* Issue 11: Generated scripts now wrap their call to the script entry point
in the standard "if name == 'main'"
* Added the 'DONT_PATCH_SETUPTOOLS' environment variable, so virtualenv
can drive an installation that doesn't patch a global setuptools.
* Reviewed unladen-swallow specific change from
http://code.google.com/p/unladen-swallow/source/detail?spec=svn875&r=719
and determined that it no longer applies. Distribute should work fine with
Unladen Swallow 2009Q3.
* Issue 21: Allow PackageIndex.open_url to gracefully handle all cases of a
httplib.HTTPException instead of just InvalidURL and BadStatusLine.
* Removed virtual-python.py from this distribution and updated documentation
to point to the actively maintained virtualenv instead.
* Issue 64: use_setuptools no longer rebuilds the distribute egg every
time it is run
* use_setuptools now properly respects the requested version
* use_setuptools will no longer try to import a distribute egg for the
wrong Python version
* Issue 74: no_fake should be True by default.
* Issue 72: avoid a bootstrapping issue with easy_install -U
-----
0.6.6
-----
* Unified the bootstrap file so it works on both py2.x and py3k without 2to3
(patch by Holger Krekel)
-----
0.6.5
-----
* Issue 65: cli.exe and gui.exe are now generated at build time,
depending on the platform in use.
* Issue 67: Fixed doc typo (PEP 381/382)
* Distribute no longer shadows setuptools if we require a 0.7-series
setuptools. And an error is raised when installing a 0.7 setuptools with
distribute.
* When run from within buildout, no attempt is made to modify an existing
setuptools egg, whether in a shared egg directory or a system setuptools.
* Fixed a hole in sandboxing allowing builtin file to write outside of
the sandbox.
-----
0.6.4
-----
* Added the generation of `distribute_setup_3k.py` during the release.
This closes issue #52.
* Added an upload_docs command to easily upload project documentation to
PyPI's http://packages.python.org. This close issue #56.
* Fixed a bootstrap bug on the use_setuptools() API.
-----
0.6.3
-----
setuptools
==========
* Fixed a bunch of calls to file() that caused crashes on Python 3.
bootstrapping
=============
* Fixed a bug in sorting that caused bootstrap to fail on Python 3.
-----
0.6.2
-----
setuptools
==========
* Added Python 3 support; see docs/python3.txt.
This closes http://bugs.python.org/setuptools/issue39.
* Added option to run 2to3 automatically when installing on Python 3.
This closes issue #31.
* Fixed invalid usage of requirement.parse, that broke develop -d.
This closes http://bugs.python.org/setuptools/issue44.
* Fixed script launcher for 64-bit Windows.
This closes http://bugs.python.org/setuptools/issue2.
* KeyError when compiling extensions.
This closes http://bugs.python.org/setuptools/issue41.
bootstrapping
=============
* Fixed bootstrap not working on Windows. This closes issue #49.
* Fixed 2.6 dependencies. This closes issue #50.
* Make sure setuptools is patched when running through easy_install
This closes http://bugs.python.org/setuptools/issue40.
-----
0.6.1
-----
setuptools
==========
* package_index.urlopen now catches BadStatusLine and malformed url errors.
This closes issue #16 and issue #18.
* zip_ok is now False by default. This closes
http://bugs.python.org/setuptools/issue33.
* Fixed invalid URL error catching. http://bugs.python.org/setuptools/issue20.
* Fixed invalid bootstraping with easy_install installation (issue #40).
Thanks to Florian Schulze for the help.
* Removed buildout/bootstrap.py. A new repository will create a specific
bootstrap.py script.
bootstrapping
=============
* The boostrap process leave setuptools alone if detected in the system
and --root or --prefix is provided, but is not in the same location.
This closes issue #10.
---
0.6
---
setuptools
==========
* Packages required at build time where not fully present at install time.
This closes issue #12.
* Protected against failures in tarfile extraction. This closes issue #10.
* Made Jython api_tests.txt doctest compatible. This closes issue #7.
* sandbox.py replaced builtin type file with builtin function open. This
closes issue #6.
* Immediately close all file handles. This closes issue #3.
* Added compatibility with Subversion 1.6. This references issue #1.
pkg_resources
=============
* Avoid a call to /usr/bin/sw_vers on OSX and use the official platform API
instead. Based on a patch from ronaldoussoren. This closes issue #5.
* Fixed a SandboxViolation for mkdir that could occur in certain cases.
This closes issue #13.
* Allow to find_on_path on systems with tight permissions to fail gracefully.
This closes issue #9.
* Corrected inconsistency between documentation and code of add_entry.
This closes issue #8.
* Immediately close all file handles. This closes issue #3.
easy_install
============
* Immediately close all file handles. This closes issue #3.
-868
View File
@@ -1,868 +0,0 @@
Metadata-Version: 1.1
Name: distribute
Version: 0.6.34
Summary: Easily download, build, install, upgrade, and uninstall Python packages
Home-page: http://packages.python.org/distribute
Author: The fellowship of the packaging
Author-email: distutils-sig@python.org
License: PSF or ZPL
Description: ===============================
Installing and Using Distribute
===============================
.. contents:: **Table of Contents**
-----------
Disclaimers
-----------
About the fork
==============
`Distribute` is a fork of the `Setuptools` project.
Distribute is intended to replace Setuptools as the standard method
for working with Python module distributions.
The fork has two goals:
- Providing a backward compatible version to replace Setuptools
and make all distributions that depend on Setuptools work as
before, but with less bugs and behaviorial issues.
This work is done in the 0.6.x series.
Starting with version 0.6.2, Distribute supports Python 3.
Installing and using distribute for Python 3 code works exactly
the same as for Python 2 code, but Distribute also helps you to support
Python 2 and Python 3 from the same source code by letting you run 2to3
on the code as a part of the build process, by setting the keyword parameter
``use_2to3`` to True. See http://packages.python.org/distribute for more
information.
- Refactoring the code, and releasing it in several distributions.
This work is being done in the 0.7.x series but not yet released.
The roadmap is still evolving, and the page that is up-to-date is
located at : `http://packages.python.org/distribute/roadmap`.
If you install `Distribute` and want to switch back for any reason to
`Setuptools`, get to the `Uninstallation instructions`_ section.
More documentation
==================
You can get more information in the Sphinx-based documentation, located
at http://packages.python.org/distribute. This documentation includes the old
Setuptools documentation that is slowly replaced, and brand new content.
About the installation process
==============================
The `Distribute` installer modifies your installation by de-activating an
existing installation of `Setuptools` in a bootstrap process. This process
has been tested in various installation schemes and contexts but in case of a
bug during this process your Python installation might be left in a broken
state. Since all modified files and directories are copied before the
installation starts, you will be able to get back to a normal state by reading
the instructions in the `Uninstallation instructions`_ section.
In any case, it is recommended to save you `site-packages` directory before
you start the installation of `Distribute`.
-------------------------
Installation Instructions
-------------------------
Distribute is only released as a source distribution.
It can be installed using pip, and can be done so with the source tarball,
or by using the ``distribute_setup.py`` script provided online.
``distribute_setup.py`` is the simplest and preferred way on all systems.
distribute_setup.py
===================
Download
`distribute_setup.py <http://python-distribute.org/distribute_setup.py>`_
and execute it, using the Python interpreter of your choice.
If your shell has the ``curl`` program you can do::
$ curl -O http://python-distribute.org/distribute_setup.py
$ python distribute_setup.py
Notice this file is also provided in the source release.
pip
===
Run easy_install or pip::
$ pip install distribute
Source installation
===================
Download the source tarball, uncompress it, then run the install command::
$ curl -O http://pypi.python.org/packages/source/d/distribute/distribute-0.6.34.tar.gz
$ tar -xzvf distribute-0.6.34.tar.gz
$ cd distribute-0.6.34
$ python setup.py install
---------------------------
Uninstallation Instructions
---------------------------
Like other distutils-based distributions, Distribute doesn't provide an
uninstaller yet. It's all done manually! We are all waiting for PEP 376
support in Python.
Distribute is installed in three steps:
1. it gets out of the way an existing installation of Setuptools
2. it installs a `fake` setuptools installation
3. it installs distribute
Distribute can be removed like this:
- remove the ``distribute*.egg`` file located in your site-packages directory
- remove the ``setuptools.pth`` file located in you site-packages directory
- remove the easy_install script located in you ``sys.prefix/bin`` directory
- remove the ``setuptools*.egg`` directory located in your site-packages directory,
if any.
If you want to get back to setuptools:
- reinstall setuptools using its instruction.
Lastly:
- remove the *.OLD.* directory located in your site-packages directory if any,
**once you have checked everything was working correctly again**.
-------------------------
Quick help for developers
-------------------------
To create an egg which is compatible with Distribute, use the same
practice as with Setuptools, e.g.::
from setuptools import setup
setup(...
)
To use `pkg_resources` to access data files in the egg, you should
require the Setuptools distribution explicitly::
from setuptools import setup
setup(...
install_requires=['setuptools']
)
Only if you need Distribute-specific functionality should you depend
on it explicitly. In this case, replace the Setuptools dependency::
from setuptools import setup
setup(...
install_requires=['distribute']
)
-----------
Install FAQ
-----------
- **Why is Distribute wrapping my Setuptools installation?**
Since Distribute is a fork, and since it provides the same package
and modules, it renames the existing Setuptools egg and inserts a
new one which merely wraps the Distribute code. This way, full
backwards compatibility is kept for packages which rely on the
Setuptools modules.
At the same time, packages can meet their dependency on Setuptools
without actually installing it (which would disable Distribute).
- **How does Distribute interact with virtualenv?**
Everytime you create a virtualenv it will install setuptools by default.
You either need to re-install Distribute in it right after or pass the
``--distribute`` option when creating it.
Once installed, your virtualenv will use Distribute transparently.
Although, if you have Setuptools installed in your system-wide Python,
and if the virtualenv you are in was generated without the `--no-site-packages`
option, the Distribute installation will stop.
You need in this case to build a virtualenv with the `--no-site-packages`
option or to install `Distribute` globally.
- **How does Distribute interacts with zc.buildout?**
You can use Distribute in your zc.buildout, with the --distribute option,
starting at zc.buildout 1.4.2::
$ python bootstrap.py --distribute
For previous zc.buildout versions, *the only thing* you need to do
is use the bootstrap at `http://python-distribute.org/bootstrap.py`. Run
that bootstrap and ``bin/buildout`` (and all other buildout-generated
scripts) will transparently use distribute instead of setuptools. You do
not need a specific buildout release.
A shared eggs directory is no problem (since 0.6.6): the setuptools egg is
left in place unmodified. So other buildouts that do not yet use the new
bootstrap continue to work just fine. And there is no need to list
``distribute`` somewhere in your eggs: using the bootstrap is enough.
The source code for the bootstrap script is located at
`http://bitbucket.org/tarek/buildout-distribute`.
-----------------------------
Feedback and getting involved
-----------------------------
- Mailing list: http://mail.python.org/mailman/listinfo/distutils-sig
- Issue tracker: http://bitbucket.org/tarek/distribute/issues/
- Code Repository: http://bitbucket.org/tarek/distribute
=======
CHANGES
=======
----------
Unreleased
----------
+ `Issue #341`_: 0.6.33 fails to build under python 2.4
------
0.6.33
------
* Fix 2 errors with Jython 2.5.
* Fix 1 failure with Jython 2.5 and 2.7.
* Disable workaround for Jython scripts on Linux systems.
* `Issue #336`_: `setup.py` no longer masks failure exit code when tests fail.
* Fix issue in pkg_resources where try/except around a platform-dependent
import would trigger hook load failures on Mercurial. See pull request 32
for details.
* `Issue #341`_: Fix a ResourceWarning.
------
0.6.32
------
* Fix test suite with Python 2.6.
* Fix some DeprecationWarnings and ResourceWarnings.
* `Issue #335`_: Backed out `setup_requires` superceding installed requirements
until regression can be addressed.
------
0.6.31
------
* `Issue #303`_: Make sure the manifest only ever contains UTF-8 in Python 3.
* `Issue #329`_: Properly close files created by tests for compatibility with
Jython.
* Work around Jython bugs `#1980 <http://bugs.jython.org/`issue1980`_>`_ and
`#1981 <http://bugs.jython.org/`issue1981`_>`_.
* `Issue #334`_: Provide workaround for packages that reference `sys.__stdout__`
such as numpy does. This change should address
`virtualenv #359 <https://github.com/pypa/virtualenv/issues/359>`_ as long
as the system encoding is UTF-8 or the IO encoding is specified in the
environment, i.e.::
PYTHONIOENCODING=utf8 pip install numpy
* Fix for encoding issue when installing from Windows executable on Python 3.
* `Issue #323`_: Allow `setup_requires` requirements to supercede installed
requirements. Added some new keyword arguments to existing pkg_resources
methods. Also had to updated how __path__ is handled for namespace packages
to ensure that when a new egg distribution containing a namespace package is
placed on sys.path, the entries in __path__ are found in the same order they
would have been in had that egg been on the path when pkg_resources was
first imported.
------
0.6.30
------
* `Issue #328`_: Clean up temporary directories in distribute_setup.py.
* Fix fatal bug in distribute_setup.py.
------
0.6.29
------
* Pull Request #14: Honor file permissions in zip files.
* `Issue #327`_: Merged pull request #24 to fix a dependency problem with pip.
* Merged pull request #23 to fix https://github.com/pypa/virtualenv/issues/301.
* If Sphinx is installed, the `upload_docs` command now runs `build_sphinx`
to produce uploadable documentation.
* `Issue #326`_: `upload_docs` provided mangled auth credentials under Python 3.
* `Issue #320`_: Fix check for "createable" in distribute_setup.py.
* `Issue #305`_: Remove a warning that was triggered during normal operations.
* `Issue #311`_: Print metadata in UTF-8 independent of platform.
* `Issue #303`_: Read manifest file with UTF-8 encoding under Python 3.
* `Issue #301`_: Allow to run tests of namespace packages when using 2to3.
* `Issue #304`_: Prevent import loop in site.py under Python 3.3.
* `Issue #283`_: Reenable scanning of `*.pyc` / `*.pyo` files on Python 3.3.
* `Issue #299`_: The develop command didn't work on Python 3, when using 2to3,
as the egg link would go to the Python 2 source. Linking to the 2to3'd code
in build/lib makes it work, although you will have to rebuild the module
before testing it.
* `Issue #306`_: Even if 2to3 is used, we build in-place under Python 2.
* `Issue #307`_: Prints the full path when .svn/entries is broken.
* `Issue #313`_: Support for sdist subcommands (Python 2.7)
* `Issue #314`_: test_local_index() would fail an OS X.
* `Issue #310`_: Non-ascii characters in a namespace __init__.py causes errors.
* `Issue #218`_: Improved documentation on behavior of `package_data` and
`include_package_data`. Files indicated by `package_data` are now included
in the manifest.
* `distribute_setup.py` now allows a `--download-base` argument for retrieving
distribute from a specified location.
------
0.6.28
------
* `Issue #294`_: setup.py can now be invoked from any directory.
* Scripts are now installed honoring the umask.
* Added support for .dist-info directories.
* `Issue #283`_: Fix and disable scanning of `*.pyc` / `*.pyo` files on
Python 3.3.
------
0.6.27
------
* Support current snapshots of CPython 3.3.
* Distribute now recognizes README.rst as a standard, default readme file.
* Exclude 'encodings' modules when removing modules from sys.modules.
Workaround for #285.
* `Issue #231`_: Don't fiddle with system python when used with buildout
(bootstrap.py)
------
0.6.26
------
* `Issue #183`_: Symlinked files are now extracted from source distributions.
* `Issue #227`_: Easy_install fetch parameters are now passed during the
installation of a source distribution; now fulfillment of setup_requires
dependencies will honor the parameters passed to easy_install.
------
0.6.25
------
* `Issue #258`_: Workaround a cache issue
* `Issue #260`_: distribute_setup.py now accepts the --user parameter for
Python 2.6 and later.
* `Issue #262`_: package_index.open_with_auth no longer throws LookupError
on Python 3.
* `Issue #269`_: AttributeError when an exception occurs reading Manifest.in
on late releases of Python.
* `Issue #272`_: Prevent TypeError when namespace package names are unicode
and single-install-externally-managed is used. Also fixes PIP `issue
449`_.
* `Issue #273`_: Legacy script launchers now install with Python2/3 support.
------
0.6.24
------
* `Issue #249`_: Added options to exclude 2to3 fixers
------
0.6.23
------
* `Issue #244`_: Fixed a test
* `Issue #243`_: Fixed a test
* `Issue #239`_: Fixed a test
* `Issue #240`_: Fixed a test
* `Issue #241`_: Fixed a test
* `Issue #237`_: Fixed a test
* `Issue #238`_: easy_install now uses 64bit executable wrappers on 64bit Python
* `Issue #208`_: Fixed parsed_versions, it now honors post-releases as noted in the documentation
* `Issue #207`_: Windows cli and gui wrappers pass CTRL-C to child python process
* `Issue #227`_: easy_install now passes its arguments to setup.py bdist_egg
* `Issue #225`_: Fixed a NameError on Python 2.5, 2.4
------
0.6.21
------
* `Issue #225`_: FIxed a regression on py2.4
------
0.6.20
------
* `Issue #135`_: Include url in warning when processing URLs in package_index.
* `Issue #212`_: Fix issue where easy_instal fails on Python 3 on windows installer.
* `Issue #213`_: Fix typo in documentation.
------
0.6.19
------
* `Issue 206`_: AttributeError: 'HTTPMessage' object has no attribute 'getheaders'
------
0.6.18
------
* `Issue 210`_: Fixed a regression introduced by `Issue 204`_ fix.
------
0.6.17
------
* Support 'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT' environment
variable to allow to disable installation of easy_install-${version} script.
* Support Python >=3.1.4 and >=3.2.1.
* `Issue 204`_: Don't try to import the parent of a namespace package in
declare_namespace
* `Issue 196`_: Tolerate responses with multiple Content-Length headers
* `Issue 205`_: Sandboxing doesn't preserve working_set. Leads to setup_requires
problems.
------
0.6.16
------
* Builds sdist gztar even on Windows (avoiding `Issue 193`_).
* `Issue 192`_: Fixed metadata omitted on Windows when package_dir
specified with forward-slash.
* `Issue 195`_: Cython build support.
* `Issue 200`_: Issues with recognizing 64-bit packages on Windows.
------
0.6.15
------
* Fixed typo in bdist_egg
* Several issues under Python 3 has been solved.
* `Issue 146`_: Fixed missing DLL files after easy_install of windows exe package.
------
0.6.14
------
* `Issue 170`_: Fixed unittest failure. Thanks to Toshio.
* `Issue 171`_: Fixed race condition in unittests cause deadlocks in test suite.
* `Issue 143`_: Fixed a lookup issue with easy_install.
Thanks to David and Zooko.
* `Issue 174`_: Fixed the edit mode when its used with setuptools itself
------
0.6.13
------
* `Issue 160`_: 2.7 gives ValueError("Invalid IPv6 URL")
* `Issue 150`_: Fixed using ~/.local even in a --no-site-packages virtualenv
* `Issue 163`_: scan index links before external links, and don't use the md5 when
comparing two distributions
------
0.6.12
------
* `Issue 149`_: Fixed various failures on 2.3/2.4
------
0.6.11
------
* Found another case of SandboxViolation - fixed
* `Issue 15`_ and 48: Introduced a socket timeout of 15 seconds on url openings
* Added indexsidebar.html into MANIFEST.in
* `Issue 108`_: Fixed TypeError with Python3.1
* `Issue 121`_: Fixed --help install command trying to actually install.
* `Issue 112`_: Added an os.makedirs so that Tarek's solution will work.
* `Issue 133`_: Added --no-find-links to easy_install
* Added easy_install --user
* `Issue 100`_: Fixed develop --user not taking '.' in PYTHONPATH into account
* `Issue 134`_: removed spurious UserWarnings. Patch by VanLindberg
* `Issue 138`_: cant_write_to_target error when setup_requires is used.
* `Issue 147`_: respect the sys.dont_write_bytecode flag
------
0.6.10
------
* Reverted change made for the DistributionNotFound exception because
zc.buildout uses the exception message to get the name of the
distribution.
-----
0.6.9
-----
* `Issue 90`_: unknown setuptools version can be added in the working set
* `Issue 87`_: setupt.py doesn't try to convert distribute_setup.py anymore
Initial Patch by arfrever.
* `Issue 89`_: added a side bar with a download link to the doc.
* `Issue 86`_: fixed missing sentence in pkg_resources doc.
* Added a nicer error message when a DistributionNotFound is raised.
* `Issue 80`_: test_develop now works with Python 3.1
* `Issue 93`_: upload_docs now works if there is an empty sub-directory.
* `Issue 70`_: exec bit on non-exec files
* `Issue 99`_: now the standalone easy_install command doesn't uses a
"setup.cfg" if any exists in the working directory. It will use it
only if triggered by ``install_requires`` from a setup.py call
(install, develop, etc).
* `Issue 101`_: Allowing ``os.devnull`` in Sandbox
* `Issue 92`_: Fixed the "no eggs" found error with MacPort
(platform.mac_ver() fails)
* `Issue 103`_: test_get_script_header_jython_workaround not run
anymore under py3 with C or POSIX local. Contributed by Arfrever.
* `Issue 104`_: remvoved the assertion when the installation fails,
with a nicer message for the end user.
* `Issue 100`_: making sure there's no SandboxViolation when
the setup script patches setuptools.
-----
0.6.8
-----
* Added "check_packages" in dist. (added in Setuptools 0.6c11)
* Fixed the DONT_PATCH_SETUPTOOLS state.
-----
0.6.7
-----
* `Issue 58`_: Added --user support to the develop command
* `Issue 11`_: Generated scripts now wrap their call to the script entry point
in the standard "if name == 'main'"
* Added the 'DONT_PATCH_SETUPTOOLS' environment variable, so virtualenv
can drive an installation that doesn't patch a global setuptools.
* Reviewed unladen-swallow specific change from
http://code.google.com/p/unladen-swallow/source/detail?spec=svn875&r=719
and determined that it no longer applies. Distribute should work fine with
Unladen Swallow 2009Q3.
* `Issue 21`_: Allow PackageIndex.open_url to gracefully handle all cases of a
httplib.HTTPException instead of just InvalidURL and BadStatusLine.
* Removed virtual-python.py from this distribution and updated documentation
to point to the actively maintained virtualenv instead.
* `Issue 64`_: use_setuptools no longer rebuilds the distribute egg every
time it is run
* use_setuptools now properly respects the requested version
* use_setuptools will no longer try to import a distribute egg for the
wrong Python version
* `Issue 74`_: no_fake should be True by default.
* `Issue 72`_: avoid a bootstrapping issue with easy_install -U
-----
0.6.6
-----
* Unified the bootstrap file so it works on both py2.x and py3k without 2to3
(patch by Holger Krekel)
-----
0.6.5
-----
* `Issue 65`_: cli.exe and gui.exe are now generated at build time,
depending on the platform in use.
* `Issue 67`_: Fixed doc typo (PEP 381/382)
* Distribute no longer shadows setuptools if we require a 0.7-series
setuptools. And an error is raised when installing a 0.7 setuptools with
distribute.
* When run from within buildout, no attempt is made to modify an existing
setuptools egg, whether in a shared egg directory or a system setuptools.
* Fixed a hole in sandboxing allowing builtin file to write outside of
the sandbox.
-----
0.6.4
-----
* Added the generation of `distribute_setup_3k.py` during the release.
This closes `issue #52`_.
* Added an upload_docs command to easily upload project documentation to
PyPI's http://packages.python.org. This close `issue #56`_.
* Fixed a bootstrap bug on the use_setuptools() API.
-----
0.6.3
-----
setuptools
==========
* Fixed a bunch of calls to file() that caused crashes on Python 3.
bootstrapping
=============
* Fixed a bug in sorting that caused bootstrap to fail on Python 3.
-----
0.6.2
-----
setuptools
==========
* Added Python 3 support; see docs/python3.txt.
This closes http://bugs.python.org/setuptools/`issue39`_.
* Added option to run 2to3 automatically when installing on Python 3.
This closes `issue #31`_.
* Fixed invalid usage of requirement.parse, that broke develop -d.
This closes http://bugs.python.org/setuptools/`issue44`_.
* Fixed script launcher for 64-bit Windows.
This closes http://bugs.python.org/setuptools/`issue2`_.
* KeyError when compiling extensions.
This closes http://bugs.python.org/setuptools/`issue41`_.
bootstrapping
=============
* Fixed bootstrap not working on Windows. This closes `issue #49`_.
* Fixed 2.6 dependencies. This closes `issue #50`_.
* Make sure setuptools is patched when running through easy_install
This closes http://bugs.python.org/setuptools/`issue40`_.
-----
0.6.1
-----
setuptools
==========
* package_index.urlopen now catches BadStatusLine and malformed url errors.
This closes `issue #16`_ and `issue #18`_.
* zip_ok is now False by default. This closes
http://bugs.python.org/setuptools/`issue33`_.
* Fixed invalid URL error catching. http://bugs.python.org/setuptools/`issue20`_.
* Fixed invalid bootstraping with easy_install installation (`issue #40`_).
Thanks to Florian Schulze for the help.
* Removed buildout/bootstrap.py. A new repository will create a specific
bootstrap.py script.
bootstrapping
=============
* The boostrap process leave setuptools alone if detected in the system
and --root or --prefix is provided, but is not in the same location.
This closes `issue #10`_.
---
0.6
---
setuptools
==========
* Packages required at build time where not fully present at install time.
This closes `issue #12`_.
* Protected against failures in tarfile extraction. This closes `issue #10`_.
* Made Jython api_tests.txt doctest compatible. This closes `issue #7`_.
* sandbox.py replaced builtin type file with builtin function open. This
closes `issue #6`_.
* Immediately close all file handles. This closes `issue #3`_.
* Added compatibility with Subversion 1.6. This references `issue #1`_.
pkg_resources
=============
* Avoid a call to /usr/bin/sw_vers on OSX and use the official platform API
instead. Based on a patch from ronaldoussoren. This closes `issue #5`_.
* Fixed a SandboxViolation for mkdir that could occur in certain cases.
This closes `issue #13`_.
* Allow to find_on_path on systems with tight permissions to fail gracefully.
This closes `issue #9`_.
* Corrected inconsistency between documentation and code of add_entry.
This closes `issue #8`_.
* Immediately close all file handles. This closes `issue #3`_.
easy_install
============
* Immediately close all file handles. This closes `issue #3`_.
.. _`Issue #135`: http://bitbucket.org/tarek/distribute/issue/135
.. _`Issue #183`: http://bitbucket.org/tarek/distribute/issue/183
.. _`Issue #207`: http://bitbucket.org/tarek/distribute/issue/207
.. _`Issue #208`: http://bitbucket.org/tarek/distribute/issue/208
.. _`Issue #212`: http://bitbucket.org/tarek/distribute/issue/212
.. _`Issue #213`: http://bitbucket.org/tarek/distribute/issue/213
.. _`Issue #218`: http://bitbucket.org/tarek/distribute/issue/218
.. _`Issue #225`: http://bitbucket.org/tarek/distribute/issue/225
.. _`Issue #227`: http://bitbucket.org/tarek/distribute/issue/227
.. _`Issue #231`: http://bitbucket.org/tarek/distribute/issue/231
.. _`Issue #237`: http://bitbucket.org/tarek/distribute/issue/237
.. _`Issue #238`: http://bitbucket.org/tarek/distribute/issue/238
.. _`Issue #239`: http://bitbucket.org/tarek/distribute/issue/239
.. _`Issue #240`: http://bitbucket.org/tarek/distribute/issue/240
.. _`Issue #241`: http://bitbucket.org/tarek/distribute/issue/241
.. _`Issue #243`: http://bitbucket.org/tarek/distribute/issue/243
.. _`Issue #244`: http://bitbucket.org/tarek/distribute/issue/244
.. _`Issue #249`: http://bitbucket.org/tarek/distribute/issue/249
.. _`Issue #258`: http://bitbucket.org/tarek/distribute/issue/258
.. _`Issue #260`: http://bitbucket.org/tarek/distribute/issue/260
.. _`Issue #262`: http://bitbucket.org/tarek/distribute/issue/262
.. _`Issue #269`: http://bitbucket.org/tarek/distribute/issue/269
.. _`Issue #272`: http://bitbucket.org/tarek/distribute/issue/272
.. _`Issue #273`: http://bitbucket.org/tarek/distribute/issue/273
.. _`Issue #283`: http://bitbucket.org/tarek/distribute/issue/283
.. _`Issue #294`: http://bitbucket.org/tarek/distribute/issue/294
.. _`Issue #299`: http://bitbucket.org/tarek/distribute/issue/299
.. _`Issue #301`: http://bitbucket.org/tarek/distribute/issue/301
.. _`Issue #303`: http://bitbucket.org/tarek/distribute/issue/303
.. _`Issue #304`: http://bitbucket.org/tarek/distribute/issue/304
.. _`Issue #305`: http://bitbucket.org/tarek/distribute/issue/305
.. _`Issue #306`: http://bitbucket.org/tarek/distribute/issue/306
.. _`Issue #307`: http://bitbucket.org/tarek/distribute/issue/307
.. _`Issue #310`: http://bitbucket.org/tarek/distribute/issue/310
.. _`Issue #311`: http://bitbucket.org/tarek/distribute/issue/311
.. _`Issue #313`: http://bitbucket.org/tarek/distribute/issue/313
.. _`Issue #314`: http://bitbucket.org/tarek/distribute/issue/314
.. _`Issue #320`: http://bitbucket.org/tarek/distribute/issue/320
.. _`Issue #323`: http://bitbucket.org/tarek/distribute/issue/323
.. _`Issue #326`: http://bitbucket.org/tarek/distribute/issue/326
.. _`Issue #327`: http://bitbucket.org/tarek/distribute/issue/327
.. _`Issue #328`: http://bitbucket.org/tarek/distribute/issue/328
.. _`Issue #329`: http://bitbucket.org/tarek/distribute/issue/329
.. _`Issue #334`: http://bitbucket.org/tarek/distribute/issue/334
.. _`Issue #335`: http://bitbucket.org/tarek/distribute/issue/335
.. _`Issue #336`: http://bitbucket.org/tarek/distribute/issue/336
.. _`Issue #341`: http://bitbucket.org/tarek/distribute/issue/341
.. _`Issue 100`: http://bitbucket.org/tarek/distribute/issue/100
.. _`Issue 101`: http://bitbucket.org/tarek/distribute/issue/101
.. _`Issue 103`: http://bitbucket.org/tarek/distribute/issue/103
.. _`Issue 104`: http://bitbucket.org/tarek/distribute/issue/104
.. _`Issue 108`: http://bitbucket.org/tarek/distribute/issue/108
.. _`Issue 11`: http://bitbucket.org/tarek/distribute/issue/11
.. _`Issue 112`: http://bitbucket.org/tarek/distribute/issue/112
.. _`Issue 121`: http://bitbucket.org/tarek/distribute/issue/121
.. _`Issue 133`: http://bitbucket.org/tarek/distribute/issue/133
.. _`Issue 134`: http://bitbucket.org/tarek/distribute/issue/134
.. _`Issue 138`: http://bitbucket.org/tarek/distribute/issue/138
.. _`Issue 143`: http://bitbucket.org/tarek/distribute/issue/143
.. _`Issue 146`: http://bitbucket.org/tarek/distribute/issue/146
.. _`Issue 147`: http://bitbucket.org/tarek/distribute/issue/147
.. _`Issue 149`: http://bitbucket.org/tarek/distribute/issue/149
.. _`Issue 15`: http://bitbucket.org/tarek/distribute/issue/15
.. _`Issue 150`: http://bitbucket.org/tarek/distribute/issue/150
.. _`Issue 160`: http://bitbucket.org/tarek/distribute/issue/160
.. _`Issue 163`: http://bitbucket.org/tarek/distribute/issue/163
.. _`Issue 170`: http://bitbucket.org/tarek/distribute/issue/170
.. _`Issue 171`: http://bitbucket.org/tarek/distribute/issue/171
.. _`Issue 174`: http://bitbucket.org/tarek/distribute/issue/174
.. _`Issue 192`: http://bitbucket.org/tarek/distribute/issue/192
.. _`Issue 193`: http://bitbucket.org/tarek/distribute/issue/193
.. _`Issue 195`: http://bitbucket.org/tarek/distribute/issue/195
.. _`Issue 196`: http://bitbucket.org/tarek/distribute/issue/196
.. _`Issue 200`: http://bitbucket.org/tarek/distribute/issue/200
.. _`Issue 204`: http://bitbucket.org/tarek/distribute/issue/204
.. _`Issue 205`: http://bitbucket.org/tarek/distribute/issue/205
.. _`Issue 206`: http://bitbucket.org/tarek/distribute/issue/206
.. _`Issue 21`: http://bitbucket.org/tarek/distribute/issue/21
.. _`Issue 210`: http://bitbucket.org/tarek/distribute/issue/210
.. _`Issue 58`: http://bitbucket.org/tarek/distribute/issue/58
.. _`Issue 64`: http://bitbucket.org/tarek/distribute/issue/64
.. _`Issue 65`: http://bitbucket.org/tarek/distribute/issue/65
.. _`Issue 67`: http://bitbucket.org/tarek/distribute/issue/67
.. _`Issue 70`: http://bitbucket.org/tarek/distribute/issue/70
.. _`Issue 72`: http://bitbucket.org/tarek/distribute/issue/72
.. _`Issue 74`: http://bitbucket.org/tarek/distribute/issue/74
.. _`Issue 80`: http://bitbucket.org/tarek/distribute/issue/80
.. _`Issue 86`: http://bitbucket.org/tarek/distribute/issue/86
.. _`Issue 87`: http://bitbucket.org/tarek/distribute/issue/87
.. _`Issue 89`: http://bitbucket.org/tarek/distribute/issue/89
.. _`Issue 90`: http://bitbucket.org/tarek/distribute/issue/90
.. _`Issue 92`: http://bitbucket.org/tarek/distribute/issue/92
.. _`Issue 93`: http://bitbucket.org/tarek/distribute/issue/93
.. _`Issue 99`: http://bitbucket.org/tarek/distribute/issue/99
.. _`issue
449`: http://bitbucket.org/tarek/distribute/issue/449
.. _`issue #1`: http://bitbucket.org/tarek/distribute/issue/1
.. _`issue #10`: http://bitbucket.org/tarek/distribute/issue/10
.. _`issue #12`: http://bitbucket.org/tarek/distribute/issue/12
.. _`issue #13`: http://bitbucket.org/tarek/distribute/issue/13
.. _`issue #16`: http://bitbucket.org/tarek/distribute/issue/16
.. _`issue #18`: http://bitbucket.org/tarek/distribute/issue/18
.. _`issue #3`: http://bitbucket.org/tarek/distribute/issue/3
.. _`issue #31`: http://bitbucket.org/tarek/distribute/issue/31
.. _`issue #40`: http://bitbucket.org/tarek/distribute/issue/40
.. _`issue #49`: http://bitbucket.org/tarek/distribute/issue/49
.. _`issue #5`: http://bitbucket.org/tarek/distribute/issue/5
.. _`issue #50`: http://bitbucket.org/tarek/distribute/issue/50
.. _`issue #52`: http://bitbucket.org/tarek/distribute/issue/52
.. _`issue #56`: http://bitbucket.org/tarek/distribute/issue/56
.. _`issue #6`: http://bitbucket.org/tarek/distribute/issue/6
.. _`issue #7`: http://bitbucket.org/tarek/distribute/issue/7
.. _`issue #8`: http://bitbucket.org/tarek/distribute/issue/8
.. _`issue #9`: http://bitbucket.org/tarek/distribute/issue/9
.. _`issue1980`: http://bitbucket.org/tarek/distribute/issue/1980
.. _`issue1981`: http://bitbucket.org/tarek/distribute/issue/1981
.. _`issue2`: http://bitbucket.org/tarek/distribute/issue/2
.. _`issue20`: http://bitbucket.org/tarek/distribute/issue/20
.. _`issue33`: http://bitbucket.org/tarek/distribute/issue/33
.. _`issue39`: http://bitbucket.org/tarek/distribute/issue/39
.. _`issue40`: http://bitbucket.org/tarek/distribute/issue/40
.. _`issue41`: http://bitbucket.org/tarek/distribute/issue/41
.. _`issue44`: http://bitbucket.org/tarek/distribute/issue/44
Keywords: CPAN PyPI distutils eggs package management
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Python Software Foundation License
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2.4
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Archiving :: Packaging
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
-228
View File
@@ -1,228 +0,0 @@
===============================
Installing and Using Distribute
===============================
.. contents:: **Table of Contents**
-----------
Disclaimers
-----------
About the fork
==============
`Distribute` is a fork of the `Setuptools` project.
Distribute is intended to replace Setuptools as the standard method
for working with Python module distributions.
The fork has two goals:
- Providing a backward compatible version to replace Setuptools
and make all distributions that depend on Setuptools work as
before, but with less bugs and behaviorial issues.
This work is done in the 0.6.x series.
Starting with version 0.6.2, Distribute supports Python 3.
Installing and using distribute for Python 3 code works exactly
the same as for Python 2 code, but Distribute also helps you to support
Python 2 and Python 3 from the same source code by letting you run 2to3
on the code as a part of the build process, by setting the keyword parameter
``use_2to3`` to True. See http://packages.python.org/distribute for more
information.
- Refactoring the code, and releasing it in several distributions.
This work is being done in the 0.7.x series but not yet released.
The roadmap is still evolving, and the page that is up-to-date is
located at : `http://packages.python.org/distribute/roadmap`.
If you install `Distribute` and want to switch back for any reason to
`Setuptools`, get to the `Uninstallation instructions`_ section.
More documentation
==================
You can get more information in the Sphinx-based documentation, located
at http://packages.python.org/distribute. This documentation includes the old
Setuptools documentation that is slowly replaced, and brand new content.
About the installation process
==============================
The `Distribute` installer modifies your installation by de-activating an
existing installation of `Setuptools` in a bootstrap process. This process
has been tested in various installation schemes and contexts but in case of a
bug during this process your Python installation might be left in a broken
state. Since all modified files and directories are copied before the
installation starts, you will be able to get back to a normal state by reading
the instructions in the `Uninstallation instructions`_ section.
In any case, it is recommended to save you `site-packages` directory before
you start the installation of `Distribute`.
-------------------------
Installation Instructions
-------------------------
Distribute is only released as a source distribution.
It can be installed using pip, and can be done so with the source tarball,
or by using the ``distribute_setup.py`` script provided online.
``distribute_setup.py`` is the simplest and preferred way on all systems.
distribute_setup.py
===================
Download
`distribute_setup.py <http://python-distribute.org/distribute_setup.py>`_
and execute it, using the Python interpreter of your choice.
If your shell has the ``curl`` program you can do::
$ curl -O http://python-distribute.org/distribute_setup.py
$ python distribute_setup.py
Notice this file is also provided in the source release.
pip
===
Run easy_install or pip::
$ pip install distribute
Source installation
===================
Download the source tarball, uncompress it, then run the install command::
$ curl -O http://pypi.python.org/packages/source/d/distribute/distribute-0.6.34.tar.gz
$ tar -xzvf distribute-0.6.34.tar.gz
$ cd distribute-0.6.34
$ python setup.py install
---------------------------
Uninstallation Instructions
---------------------------
Like other distutils-based distributions, Distribute doesn't provide an
uninstaller yet. It's all done manually! We are all waiting for PEP 376
support in Python.
Distribute is installed in three steps:
1. it gets out of the way an existing installation of Setuptools
2. it installs a `fake` setuptools installation
3. it installs distribute
Distribute can be removed like this:
- remove the ``distribute*.egg`` file located in your site-packages directory
- remove the ``setuptools.pth`` file located in you site-packages directory
- remove the easy_install script located in you ``sys.prefix/bin`` directory
- remove the ``setuptools*.egg`` directory located in your site-packages directory,
if any.
If you want to get back to setuptools:
- reinstall setuptools using its instruction.
Lastly:
- remove the *.OLD.* directory located in your site-packages directory if any,
**once you have checked everything was working correctly again**.
-------------------------
Quick help for developers
-------------------------
To create an egg which is compatible with Distribute, use the same
practice as with Setuptools, e.g.::
from setuptools import setup
setup(...
)
To use `pkg_resources` to access data files in the egg, you should
require the Setuptools distribution explicitly::
from setuptools import setup
setup(...
install_requires=['setuptools']
)
Only if you need Distribute-specific functionality should you depend
on it explicitly. In this case, replace the Setuptools dependency::
from setuptools import setup
setup(...
install_requires=['distribute']
)
-----------
Install FAQ
-----------
- **Why is Distribute wrapping my Setuptools installation?**
Since Distribute is a fork, and since it provides the same package
and modules, it renames the existing Setuptools egg and inserts a
new one which merely wraps the Distribute code. This way, full
backwards compatibility is kept for packages which rely on the
Setuptools modules.
At the same time, packages can meet their dependency on Setuptools
without actually installing it (which would disable Distribute).
- **How does Distribute interact with virtualenv?**
Everytime you create a virtualenv it will install setuptools by default.
You either need to re-install Distribute in it right after or pass the
``--distribute`` option when creating it.
Once installed, your virtualenv will use Distribute transparently.
Although, if you have Setuptools installed in your system-wide Python,
and if the virtualenv you are in was generated without the `--no-site-packages`
option, the Distribute installation will stop.
You need in this case to build a virtualenv with the `--no-site-packages`
option or to install `Distribute` globally.
- **How does Distribute interacts with zc.buildout?**
You can use Distribute in your zc.buildout, with the --distribute option,
starting at zc.buildout 1.4.2::
$ python bootstrap.py --distribute
For previous zc.buildout versions, *the only thing* you need to do
is use the bootstrap at `http://python-distribute.org/bootstrap.py`. Run
that bootstrap and ``bin/buildout`` (and all other buildout-generated
scripts) will transparently use distribute instead of setuptools. You do
not need a specific buildout release.
A shared eggs directory is no problem (since 0.6.6): the setuptools egg is
left in place unmodified. So other buildouts that do not yet use the new
bootstrap continue to work just fine. And there is no need to list
``distribute`` somewhere in your eggs: using the bootstrap is enough.
The source code for the bootstrap script is located at
`http://bitbucket.org/tarek/buildout-distribute`.
-----------------------------
Feedback and getting involved
-----------------------------
- Mailing list: http://mail.python.org/mailman/listinfo/distutils-sig
- Issue tracker: http://bitbucket.org/tarek/distribute/issues/
- Code Repository: http://bitbucket.org/tarek/distribute
-868
View File
@@ -1,868 +0,0 @@
Metadata-Version: 1.1
Name: distribute
Version: 0.6.34
Summary: Easily download, build, install, upgrade, and uninstall Python packages
Home-page: http://packages.python.org/distribute
Author: The fellowship of the packaging
Author-email: distutils-sig@python.org
License: PSF or ZPL
Description: ===============================
Installing and Using Distribute
===============================
.. contents:: **Table of Contents**
-----------
Disclaimers
-----------
About the fork
==============
`Distribute` is a fork of the `Setuptools` project.
Distribute is intended to replace Setuptools as the standard method
for working with Python module distributions.
The fork has two goals:
- Providing a backward compatible version to replace Setuptools
and make all distributions that depend on Setuptools work as
before, but with less bugs and behaviorial issues.
This work is done in the 0.6.x series.
Starting with version 0.6.2, Distribute supports Python 3.
Installing and using distribute for Python 3 code works exactly
the same as for Python 2 code, but Distribute also helps you to support
Python 2 and Python 3 from the same source code by letting you run 2to3
on the code as a part of the build process, by setting the keyword parameter
``use_2to3`` to True. See http://packages.python.org/distribute for more
information.
- Refactoring the code, and releasing it in several distributions.
This work is being done in the 0.7.x series but not yet released.
The roadmap is still evolving, and the page that is up-to-date is
located at : `http://packages.python.org/distribute/roadmap`.
If you install `Distribute` and want to switch back for any reason to
`Setuptools`, get to the `Uninstallation instructions`_ section.
More documentation
==================
You can get more information in the Sphinx-based documentation, located
at http://packages.python.org/distribute. This documentation includes the old
Setuptools documentation that is slowly replaced, and brand new content.
About the installation process
==============================
The `Distribute` installer modifies your installation by de-activating an
existing installation of `Setuptools` in a bootstrap process. This process
has been tested in various installation schemes and contexts but in case of a
bug during this process your Python installation might be left in a broken
state. Since all modified files and directories are copied before the
installation starts, you will be able to get back to a normal state by reading
the instructions in the `Uninstallation instructions`_ section.
In any case, it is recommended to save you `site-packages` directory before
you start the installation of `Distribute`.
-------------------------
Installation Instructions
-------------------------
Distribute is only released as a source distribution.
It can be installed using pip, and can be done so with the source tarball,
or by using the ``distribute_setup.py`` script provided online.
``distribute_setup.py`` is the simplest and preferred way on all systems.
distribute_setup.py
===================
Download
`distribute_setup.py <http://python-distribute.org/distribute_setup.py>`_
and execute it, using the Python interpreter of your choice.
If your shell has the ``curl`` program you can do::
$ curl -O http://python-distribute.org/distribute_setup.py
$ python distribute_setup.py
Notice this file is also provided in the source release.
pip
===
Run easy_install or pip::
$ pip install distribute
Source installation
===================
Download the source tarball, uncompress it, then run the install command::
$ curl -O http://pypi.python.org/packages/source/d/distribute/distribute-0.6.34.tar.gz
$ tar -xzvf distribute-0.6.34.tar.gz
$ cd distribute-0.6.34
$ python setup.py install
---------------------------
Uninstallation Instructions
---------------------------
Like other distutils-based distributions, Distribute doesn't provide an
uninstaller yet. It's all done manually! We are all waiting for PEP 376
support in Python.
Distribute is installed in three steps:
1. it gets out of the way an existing installation of Setuptools
2. it installs a `fake` setuptools installation
3. it installs distribute
Distribute can be removed like this:
- remove the ``distribute*.egg`` file located in your site-packages directory
- remove the ``setuptools.pth`` file located in you site-packages directory
- remove the easy_install script located in you ``sys.prefix/bin`` directory
- remove the ``setuptools*.egg`` directory located in your site-packages directory,
if any.
If you want to get back to setuptools:
- reinstall setuptools using its instruction.
Lastly:
- remove the *.OLD.* directory located in your site-packages directory if any,
**once you have checked everything was working correctly again**.
-------------------------
Quick help for developers
-------------------------
To create an egg which is compatible with Distribute, use the same
practice as with Setuptools, e.g.::
from setuptools import setup
setup(...
)
To use `pkg_resources` to access data files in the egg, you should
require the Setuptools distribution explicitly::
from setuptools import setup
setup(...
install_requires=['setuptools']
)
Only if you need Distribute-specific functionality should you depend
on it explicitly. In this case, replace the Setuptools dependency::
from setuptools import setup
setup(...
install_requires=['distribute']
)
-----------
Install FAQ
-----------
- **Why is Distribute wrapping my Setuptools installation?**
Since Distribute is a fork, and since it provides the same package
and modules, it renames the existing Setuptools egg and inserts a
new one which merely wraps the Distribute code. This way, full
backwards compatibility is kept for packages which rely on the
Setuptools modules.
At the same time, packages can meet their dependency on Setuptools
without actually installing it (which would disable Distribute).
- **How does Distribute interact with virtualenv?**
Everytime you create a virtualenv it will install setuptools by default.
You either need to re-install Distribute in it right after or pass the
``--distribute`` option when creating it.
Once installed, your virtualenv will use Distribute transparently.
Although, if you have Setuptools installed in your system-wide Python,
and if the virtualenv you are in was generated without the `--no-site-packages`
option, the Distribute installation will stop.
You need in this case to build a virtualenv with the `--no-site-packages`
option or to install `Distribute` globally.
- **How does Distribute interacts with zc.buildout?**
You can use Distribute in your zc.buildout, with the --distribute option,
starting at zc.buildout 1.4.2::
$ python bootstrap.py --distribute
For previous zc.buildout versions, *the only thing* you need to do
is use the bootstrap at `http://python-distribute.org/bootstrap.py`. Run
that bootstrap and ``bin/buildout`` (and all other buildout-generated
scripts) will transparently use distribute instead of setuptools. You do
not need a specific buildout release.
A shared eggs directory is no problem (since 0.6.6): the setuptools egg is
left in place unmodified. So other buildouts that do not yet use the new
bootstrap continue to work just fine. And there is no need to list
``distribute`` somewhere in your eggs: using the bootstrap is enough.
The source code for the bootstrap script is located at
`http://bitbucket.org/tarek/buildout-distribute`.
-----------------------------
Feedback and getting involved
-----------------------------
- Mailing list: http://mail.python.org/mailman/listinfo/distutils-sig
- Issue tracker: http://bitbucket.org/tarek/distribute/issues/
- Code Repository: http://bitbucket.org/tarek/distribute
=======
CHANGES
=======
----------
Unreleased
----------
+ `Issue #341`_: 0.6.33 fails to build under python 2.4
------
0.6.33
------
* Fix 2 errors with Jython 2.5.
* Fix 1 failure with Jython 2.5 and 2.7.
* Disable workaround for Jython scripts on Linux systems.
* `Issue #336`_: `setup.py` no longer masks failure exit code when tests fail.
* Fix issue in pkg_resources where try/except around a platform-dependent
import would trigger hook load failures on Mercurial. See pull request 32
for details.
* `Issue #341`_: Fix a ResourceWarning.
------
0.6.32
------
* Fix test suite with Python 2.6.
* Fix some DeprecationWarnings and ResourceWarnings.
* `Issue #335`_: Backed out `setup_requires` superceding installed requirements
until regression can be addressed.
------
0.6.31
------
* `Issue #303`_: Make sure the manifest only ever contains UTF-8 in Python 3.
* `Issue #329`_: Properly close files created by tests for compatibility with
Jython.
* Work around Jython bugs `#1980 <http://bugs.jython.org/`issue1980`_>`_ and
`#1981 <http://bugs.jython.org/`issue1981`_>`_.
* `Issue #334`_: Provide workaround for packages that reference `sys.__stdout__`
such as numpy does. This change should address
`virtualenv #359 <https://github.com/pypa/virtualenv/issues/359>`_ as long
as the system encoding is UTF-8 or the IO encoding is specified in the
environment, i.e.::
PYTHONIOENCODING=utf8 pip install numpy
* Fix for encoding issue when installing from Windows executable on Python 3.
* `Issue #323`_: Allow `setup_requires` requirements to supercede installed
requirements. Added some new keyword arguments to existing pkg_resources
methods. Also had to updated how __path__ is handled for namespace packages
to ensure that when a new egg distribution containing a namespace package is
placed on sys.path, the entries in __path__ are found in the same order they
would have been in had that egg been on the path when pkg_resources was
first imported.
------
0.6.30
------
* `Issue #328`_: Clean up temporary directories in distribute_setup.py.
* Fix fatal bug in distribute_setup.py.
------
0.6.29
------
* Pull Request #14: Honor file permissions in zip files.
* `Issue #327`_: Merged pull request #24 to fix a dependency problem with pip.
* Merged pull request #23 to fix https://github.com/pypa/virtualenv/issues/301.
* If Sphinx is installed, the `upload_docs` command now runs `build_sphinx`
to produce uploadable documentation.
* `Issue #326`_: `upload_docs` provided mangled auth credentials under Python 3.
* `Issue #320`_: Fix check for "createable" in distribute_setup.py.
* `Issue #305`_: Remove a warning that was triggered during normal operations.
* `Issue #311`_: Print metadata in UTF-8 independent of platform.
* `Issue #303`_: Read manifest file with UTF-8 encoding under Python 3.
* `Issue #301`_: Allow to run tests of namespace packages when using 2to3.
* `Issue #304`_: Prevent import loop in site.py under Python 3.3.
* `Issue #283`_: Reenable scanning of `*.pyc` / `*.pyo` files on Python 3.3.
* `Issue #299`_: The develop command didn't work on Python 3, when using 2to3,
as the egg link would go to the Python 2 source. Linking to the 2to3'd code
in build/lib makes it work, although you will have to rebuild the module
before testing it.
* `Issue #306`_: Even if 2to3 is used, we build in-place under Python 2.
* `Issue #307`_: Prints the full path when .svn/entries is broken.
* `Issue #313`_: Support for sdist subcommands (Python 2.7)
* `Issue #314`_: test_local_index() would fail an OS X.
* `Issue #310`_: Non-ascii characters in a namespace __init__.py causes errors.
* `Issue #218`_: Improved documentation on behavior of `package_data` and
`include_package_data`. Files indicated by `package_data` are now included
in the manifest.
* `distribute_setup.py` now allows a `--download-base` argument for retrieving
distribute from a specified location.
------
0.6.28
------
* `Issue #294`_: setup.py can now be invoked from any directory.
* Scripts are now installed honoring the umask.
* Added support for .dist-info directories.
* `Issue #283`_: Fix and disable scanning of `*.pyc` / `*.pyo` files on
Python 3.3.
------
0.6.27
------
* Support current snapshots of CPython 3.3.
* Distribute now recognizes README.rst as a standard, default readme file.
* Exclude 'encodings' modules when removing modules from sys.modules.
Workaround for #285.
* `Issue #231`_: Don't fiddle with system python when used with buildout
(bootstrap.py)
------
0.6.26
------
* `Issue #183`_: Symlinked files are now extracted from source distributions.
* `Issue #227`_: Easy_install fetch parameters are now passed during the
installation of a source distribution; now fulfillment of setup_requires
dependencies will honor the parameters passed to easy_install.
------
0.6.25
------
* `Issue #258`_: Workaround a cache issue
* `Issue #260`_: distribute_setup.py now accepts the --user parameter for
Python 2.6 and later.
* `Issue #262`_: package_index.open_with_auth no longer throws LookupError
on Python 3.
* `Issue #269`_: AttributeError when an exception occurs reading Manifest.in
on late releases of Python.
* `Issue #272`_: Prevent TypeError when namespace package names are unicode
and single-install-externally-managed is used. Also fixes PIP `issue
449`_.
* `Issue #273`_: Legacy script launchers now install with Python2/3 support.
------
0.6.24
------
* `Issue #249`_: Added options to exclude 2to3 fixers
------
0.6.23
------
* `Issue #244`_: Fixed a test
* `Issue #243`_: Fixed a test
* `Issue #239`_: Fixed a test
* `Issue #240`_: Fixed a test
* `Issue #241`_: Fixed a test
* `Issue #237`_: Fixed a test
* `Issue #238`_: easy_install now uses 64bit executable wrappers on 64bit Python
* `Issue #208`_: Fixed parsed_versions, it now honors post-releases as noted in the documentation
* `Issue #207`_: Windows cli and gui wrappers pass CTRL-C to child python process
* `Issue #227`_: easy_install now passes its arguments to setup.py bdist_egg
* `Issue #225`_: Fixed a NameError on Python 2.5, 2.4
------
0.6.21
------
* `Issue #225`_: FIxed a regression on py2.4
------
0.6.20
------
* `Issue #135`_: Include url in warning when processing URLs in package_index.
* `Issue #212`_: Fix issue where easy_instal fails on Python 3 on windows installer.
* `Issue #213`_: Fix typo in documentation.
------
0.6.19
------
* `Issue 206`_: AttributeError: 'HTTPMessage' object has no attribute 'getheaders'
------
0.6.18
------
* `Issue 210`_: Fixed a regression introduced by `Issue 204`_ fix.
------
0.6.17
------
* Support 'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT' environment
variable to allow to disable installation of easy_install-${version} script.
* Support Python >=3.1.4 and >=3.2.1.
* `Issue 204`_: Don't try to import the parent of a namespace package in
declare_namespace
* `Issue 196`_: Tolerate responses with multiple Content-Length headers
* `Issue 205`_: Sandboxing doesn't preserve working_set. Leads to setup_requires
problems.
------
0.6.16
------
* Builds sdist gztar even on Windows (avoiding `Issue 193`_).
* `Issue 192`_: Fixed metadata omitted on Windows when package_dir
specified with forward-slash.
* `Issue 195`_: Cython build support.
* `Issue 200`_: Issues with recognizing 64-bit packages on Windows.
------
0.6.15
------
* Fixed typo in bdist_egg
* Several issues under Python 3 has been solved.
* `Issue 146`_: Fixed missing DLL files after easy_install of windows exe package.
------
0.6.14
------
* `Issue 170`_: Fixed unittest failure. Thanks to Toshio.
* `Issue 171`_: Fixed race condition in unittests cause deadlocks in test suite.
* `Issue 143`_: Fixed a lookup issue with easy_install.
Thanks to David and Zooko.
* `Issue 174`_: Fixed the edit mode when its used with setuptools itself
------
0.6.13
------
* `Issue 160`_: 2.7 gives ValueError("Invalid IPv6 URL")
* `Issue 150`_: Fixed using ~/.local even in a --no-site-packages virtualenv
* `Issue 163`_: scan index links before external links, and don't use the md5 when
comparing two distributions
------
0.6.12
------
* `Issue 149`_: Fixed various failures on 2.3/2.4
------
0.6.11
------
* Found another case of SandboxViolation - fixed
* `Issue 15`_ and 48: Introduced a socket timeout of 15 seconds on url openings
* Added indexsidebar.html into MANIFEST.in
* `Issue 108`_: Fixed TypeError with Python3.1
* `Issue 121`_: Fixed --help install command trying to actually install.
* `Issue 112`_: Added an os.makedirs so that Tarek's solution will work.
* `Issue 133`_: Added --no-find-links to easy_install
* Added easy_install --user
* `Issue 100`_: Fixed develop --user not taking '.' in PYTHONPATH into account
* `Issue 134`_: removed spurious UserWarnings. Patch by VanLindberg
* `Issue 138`_: cant_write_to_target error when setup_requires is used.
* `Issue 147`_: respect the sys.dont_write_bytecode flag
------
0.6.10
------
* Reverted change made for the DistributionNotFound exception because
zc.buildout uses the exception message to get the name of the
distribution.
-----
0.6.9
-----
* `Issue 90`_: unknown setuptools version can be added in the working set
* `Issue 87`_: setupt.py doesn't try to convert distribute_setup.py anymore
Initial Patch by arfrever.
* `Issue 89`_: added a side bar with a download link to the doc.
* `Issue 86`_: fixed missing sentence in pkg_resources doc.
* Added a nicer error message when a DistributionNotFound is raised.
* `Issue 80`_: test_develop now works with Python 3.1
* `Issue 93`_: upload_docs now works if there is an empty sub-directory.
* `Issue 70`_: exec bit on non-exec files
* `Issue 99`_: now the standalone easy_install command doesn't uses a
"setup.cfg" if any exists in the working directory. It will use it
only if triggered by ``install_requires`` from a setup.py call
(install, develop, etc).
* `Issue 101`_: Allowing ``os.devnull`` in Sandbox
* `Issue 92`_: Fixed the "no eggs" found error with MacPort
(platform.mac_ver() fails)
* `Issue 103`_: test_get_script_header_jython_workaround not run
anymore under py3 with C or POSIX local. Contributed by Arfrever.
* `Issue 104`_: remvoved the assertion when the installation fails,
with a nicer message for the end user.
* `Issue 100`_: making sure there's no SandboxViolation when
the setup script patches setuptools.
-----
0.6.8
-----
* Added "check_packages" in dist. (added in Setuptools 0.6c11)
* Fixed the DONT_PATCH_SETUPTOOLS state.
-----
0.6.7
-----
* `Issue 58`_: Added --user support to the develop command
* `Issue 11`_: Generated scripts now wrap their call to the script entry point
in the standard "if name == 'main'"
* Added the 'DONT_PATCH_SETUPTOOLS' environment variable, so virtualenv
can drive an installation that doesn't patch a global setuptools.
* Reviewed unladen-swallow specific change from
http://code.google.com/p/unladen-swallow/source/detail?spec=svn875&r=719
and determined that it no longer applies. Distribute should work fine with
Unladen Swallow 2009Q3.
* `Issue 21`_: Allow PackageIndex.open_url to gracefully handle all cases of a
httplib.HTTPException instead of just InvalidURL and BadStatusLine.
* Removed virtual-python.py from this distribution and updated documentation
to point to the actively maintained virtualenv instead.
* `Issue 64`_: use_setuptools no longer rebuilds the distribute egg every
time it is run
* use_setuptools now properly respects the requested version
* use_setuptools will no longer try to import a distribute egg for the
wrong Python version
* `Issue 74`_: no_fake should be True by default.
* `Issue 72`_: avoid a bootstrapping issue with easy_install -U
-----
0.6.6
-----
* Unified the bootstrap file so it works on both py2.x and py3k without 2to3
(patch by Holger Krekel)
-----
0.6.5
-----
* `Issue 65`_: cli.exe and gui.exe are now generated at build time,
depending on the platform in use.
* `Issue 67`_: Fixed doc typo (PEP 381/382)
* Distribute no longer shadows setuptools if we require a 0.7-series
setuptools. And an error is raised when installing a 0.7 setuptools with
distribute.
* When run from within buildout, no attempt is made to modify an existing
setuptools egg, whether in a shared egg directory or a system setuptools.
* Fixed a hole in sandboxing allowing builtin file to write outside of
the sandbox.
-----
0.6.4
-----
* Added the generation of `distribute_setup_3k.py` during the release.
This closes `issue #52`_.
* Added an upload_docs command to easily upload project documentation to
PyPI's http://packages.python.org. This close `issue #56`_.
* Fixed a bootstrap bug on the use_setuptools() API.
-----
0.6.3
-----
setuptools
==========
* Fixed a bunch of calls to file() that caused crashes on Python 3.
bootstrapping
=============
* Fixed a bug in sorting that caused bootstrap to fail on Python 3.
-----
0.6.2
-----
setuptools
==========
* Added Python 3 support; see docs/python3.txt.
This closes http://bugs.python.org/setuptools/`issue39`_.
* Added option to run 2to3 automatically when installing on Python 3.
This closes `issue #31`_.
* Fixed invalid usage of requirement.parse, that broke develop -d.
This closes http://bugs.python.org/setuptools/`issue44`_.
* Fixed script launcher for 64-bit Windows.
This closes http://bugs.python.org/setuptools/`issue2`_.
* KeyError when compiling extensions.
This closes http://bugs.python.org/setuptools/`issue41`_.
bootstrapping
=============
* Fixed bootstrap not working on Windows. This closes `issue #49`_.
* Fixed 2.6 dependencies. This closes `issue #50`_.
* Make sure setuptools is patched when running through easy_install
This closes http://bugs.python.org/setuptools/`issue40`_.
-----
0.6.1
-----
setuptools
==========
* package_index.urlopen now catches BadStatusLine and malformed url errors.
This closes `issue #16`_ and `issue #18`_.
* zip_ok is now False by default. This closes
http://bugs.python.org/setuptools/`issue33`_.
* Fixed invalid URL error catching. http://bugs.python.org/setuptools/`issue20`_.
* Fixed invalid bootstraping with easy_install installation (`issue #40`_).
Thanks to Florian Schulze for the help.
* Removed buildout/bootstrap.py. A new repository will create a specific
bootstrap.py script.
bootstrapping
=============
* The boostrap process leave setuptools alone if detected in the system
and --root or --prefix is provided, but is not in the same location.
This closes `issue #10`_.
---
0.6
---
setuptools
==========
* Packages required at build time where not fully present at install time.
This closes `issue #12`_.
* Protected against failures in tarfile extraction. This closes `issue #10`_.
* Made Jython api_tests.txt doctest compatible. This closes `issue #7`_.
* sandbox.py replaced builtin type file with builtin function open. This
closes `issue #6`_.
* Immediately close all file handles. This closes `issue #3`_.
* Added compatibility with Subversion 1.6. This references `issue #1`_.
pkg_resources
=============
* Avoid a call to /usr/bin/sw_vers on OSX and use the official platform API
instead. Based on a patch from ronaldoussoren. This closes `issue #5`_.
* Fixed a SandboxViolation for mkdir that could occur in certain cases.
This closes `issue #13`_.
* Allow to find_on_path on systems with tight permissions to fail gracefully.
This closes `issue #9`_.
* Corrected inconsistency between documentation and code of add_entry.
This closes `issue #8`_.
* Immediately close all file handles. This closes `issue #3`_.
easy_install
============
* Immediately close all file handles. This closes `issue #3`_.
.. _`Issue #135`: http://bitbucket.org/tarek/distribute/issue/135
.. _`Issue #183`: http://bitbucket.org/tarek/distribute/issue/183
.. _`Issue #207`: http://bitbucket.org/tarek/distribute/issue/207
.. _`Issue #208`: http://bitbucket.org/tarek/distribute/issue/208
.. _`Issue #212`: http://bitbucket.org/tarek/distribute/issue/212
.. _`Issue #213`: http://bitbucket.org/tarek/distribute/issue/213
.. _`Issue #218`: http://bitbucket.org/tarek/distribute/issue/218
.. _`Issue #225`: http://bitbucket.org/tarek/distribute/issue/225
.. _`Issue #227`: http://bitbucket.org/tarek/distribute/issue/227
.. _`Issue #231`: http://bitbucket.org/tarek/distribute/issue/231
.. _`Issue #237`: http://bitbucket.org/tarek/distribute/issue/237
.. _`Issue #238`: http://bitbucket.org/tarek/distribute/issue/238
.. _`Issue #239`: http://bitbucket.org/tarek/distribute/issue/239
.. _`Issue #240`: http://bitbucket.org/tarek/distribute/issue/240
.. _`Issue #241`: http://bitbucket.org/tarek/distribute/issue/241
.. _`Issue #243`: http://bitbucket.org/tarek/distribute/issue/243
.. _`Issue #244`: http://bitbucket.org/tarek/distribute/issue/244
.. _`Issue #249`: http://bitbucket.org/tarek/distribute/issue/249
.. _`Issue #258`: http://bitbucket.org/tarek/distribute/issue/258
.. _`Issue #260`: http://bitbucket.org/tarek/distribute/issue/260
.. _`Issue #262`: http://bitbucket.org/tarek/distribute/issue/262
.. _`Issue #269`: http://bitbucket.org/tarek/distribute/issue/269
.. _`Issue #272`: http://bitbucket.org/tarek/distribute/issue/272
.. _`Issue #273`: http://bitbucket.org/tarek/distribute/issue/273
.. _`Issue #283`: http://bitbucket.org/tarek/distribute/issue/283
.. _`Issue #294`: http://bitbucket.org/tarek/distribute/issue/294
.. _`Issue #299`: http://bitbucket.org/tarek/distribute/issue/299
.. _`Issue #301`: http://bitbucket.org/tarek/distribute/issue/301
.. _`Issue #303`: http://bitbucket.org/tarek/distribute/issue/303
.. _`Issue #304`: http://bitbucket.org/tarek/distribute/issue/304
.. _`Issue #305`: http://bitbucket.org/tarek/distribute/issue/305
.. _`Issue #306`: http://bitbucket.org/tarek/distribute/issue/306
.. _`Issue #307`: http://bitbucket.org/tarek/distribute/issue/307
.. _`Issue #310`: http://bitbucket.org/tarek/distribute/issue/310
.. _`Issue #311`: http://bitbucket.org/tarek/distribute/issue/311
.. _`Issue #313`: http://bitbucket.org/tarek/distribute/issue/313
.. _`Issue #314`: http://bitbucket.org/tarek/distribute/issue/314
.. _`Issue #320`: http://bitbucket.org/tarek/distribute/issue/320
.. _`Issue #323`: http://bitbucket.org/tarek/distribute/issue/323
.. _`Issue #326`: http://bitbucket.org/tarek/distribute/issue/326
.. _`Issue #327`: http://bitbucket.org/tarek/distribute/issue/327
.. _`Issue #328`: http://bitbucket.org/tarek/distribute/issue/328
.. _`Issue #329`: http://bitbucket.org/tarek/distribute/issue/329
.. _`Issue #334`: http://bitbucket.org/tarek/distribute/issue/334
.. _`Issue #335`: http://bitbucket.org/tarek/distribute/issue/335
.. _`Issue #336`: http://bitbucket.org/tarek/distribute/issue/336
.. _`Issue #341`: http://bitbucket.org/tarek/distribute/issue/341
.. _`Issue 100`: http://bitbucket.org/tarek/distribute/issue/100
.. _`Issue 101`: http://bitbucket.org/tarek/distribute/issue/101
.. _`Issue 103`: http://bitbucket.org/tarek/distribute/issue/103
.. _`Issue 104`: http://bitbucket.org/tarek/distribute/issue/104
.. _`Issue 108`: http://bitbucket.org/tarek/distribute/issue/108
.. _`Issue 11`: http://bitbucket.org/tarek/distribute/issue/11
.. _`Issue 112`: http://bitbucket.org/tarek/distribute/issue/112
.. _`Issue 121`: http://bitbucket.org/tarek/distribute/issue/121
.. _`Issue 133`: http://bitbucket.org/tarek/distribute/issue/133
.. _`Issue 134`: http://bitbucket.org/tarek/distribute/issue/134
.. _`Issue 138`: http://bitbucket.org/tarek/distribute/issue/138
.. _`Issue 143`: http://bitbucket.org/tarek/distribute/issue/143
.. _`Issue 146`: http://bitbucket.org/tarek/distribute/issue/146
.. _`Issue 147`: http://bitbucket.org/tarek/distribute/issue/147
.. _`Issue 149`: http://bitbucket.org/tarek/distribute/issue/149
.. _`Issue 15`: http://bitbucket.org/tarek/distribute/issue/15
.. _`Issue 150`: http://bitbucket.org/tarek/distribute/issue/150
.. _`Issue 160`: http://bitbucket.org/tarek/distribute/issue/160
.. _`Issue 163`: http://bitbucket.org/tarek/distribute/issue/163
.. _`Issue 170`: http://bitbucket.org/tarek/distribute/issue/170
.. _`Issue 171`: http://bitbucket.org/tarek/distribute/issue/171
.. _`Issue 174`: http://bitbucket.org/tarek/distribute/issue/174
.. _`Issue 192`: http://bitbucket.org/tarek/distribute/issue/192
.. _`Issue 193`: http://bitbucket.org/tarek/distribute/issue/193
.. _`Issue 195`: http://bitbucket.org/tarek/distribute/issue/195
.. _`Issue 196`: http://bitbucket.org/tarek/distribute/issue/196
.. _`Issue 200`: http://bitbucket.org/tarek/distribute/issue/200
.. _`Issue 204`: http://bitbucket.org/tarek/distribute/issue/204
.. _`Issue 205`: http://bitbucket.org/tarek/distribute/issue/205
.. _`Issue 206`: http://bitbucket.org/tarek/distribute/issue/206
.. _`Issue 21`: http://bitbucket.org/tarek/distribute/issue/21
.. _`Issue 210`: http://bitbucket.org/tarek/distribute/issue/210
.. _`Issue 58`: http://bitbucket.org/tarek/distribute/issue/58
.. _`Issue 64`: http://bitbucket.org/tarek/distribute/issue/64
.. _`Issue 65`: http://bitbucket.org/tarek/distribute/issue/65
.. _`Issue 67`: http://bitbucket.org/tarek/distribute/issue/67
.. _`Issue 70`: http://bitbucket.org/tarek/distribute/issue/70
.. _`Issue 72`: http://bitbucket.org/tarek/distribute/issue/72
.. _`Issue 74`: http://bitbucket.org/tarek/distribute/issue/74
.. _`Issue 80`: http://bitbucket.org/tarek/distribute/issue/80
.. _`Issue 86`: http://bitbucket.org/tarek/distribute/issue/86
.. _`Issue 87`: http://bitbucket.org/tarek/distribute/issue/87
.. _`Issue 89`: http://bitbucket.org/tarek/distribute/issue/89
.. _`Issue 90`: http://bitbucket.org/tarek/distribute/issue/90
.. _`Issue 92`: http://bitbucket.org/tarek/distribute/issue/92
.. _`Issue 93`: http://bitbucket.org/tarek/distribute/issue/93
.. _`Issue 99`: http://bitbucket.org/tarek/distribute/issue/99
.. _`issue
449`: http://bitbucket.org/tarek/distribute/issue/449
.. _`issue #1`: http://bitbucket.org/tarek/distribute/issue/1
.. _`issue #10`: http://bitbucket.org/tarek/distribute/issue/10
.. _`issue #12`: http://bitbucket.org/tarek/distribute/issue/12
.. _`issue #13`: http://bitbucket.org/tarek/distribute/issue/13
.. _`issue #16`: http://bitbucket.org/tarek/distribute/issue/16
.. _`issue #18`: http://bitbucket.org/tarek/distribute/issue/18
.. _`issue #3`: http://bitbucket.org/tarek/distribute/issue/3
.. _`issue #31`: http://bitbucket.org/tarek/distribute/issue/31
.. _`issue #40`: http://bitbucket.org/tarek/distribute/issue/40
.. _`issue #49`: http://bitbucket.org/tarek/distribute/issue/49
.. _`issue #5`: http://bitbucket.org/tarek/distribute/issue/5
.. _`issue #50`: http://bitbucket.org/tarek/distribute/issue/50
.. _`issue #52`: http://bitbucket.org/tarek/distribute/issue/52
.. _`issue #56`: http://bitbucket.org/tarek/distribute/issue/56
.. _`issue #6`: http://bitbucket.org/tarek/distribute/issue/6
.. _`issue #7`: http://bitbucket.org/tarek/distribute/issue/7
.. _`issue #8`: http://bitbucket.org/tarek/distribute/issue/8
.. _`issue #9`: http://bitbucket.org/tarek/distribute/issue/9
.. _`issue1980`: http://bitbucket.org/tarek/distribute/issue/1980
.. _`issue1981`: http://bitbucket.org/tarek/distribute/issue/1981
.. _`issue2`: http://bitbucket.org/tarek/distribute/issue/2
.. _`issue20`: http://bitbucket.org/tarek/distribute/issue/20
.. _`issue33`: http://bitbucket.org/tarek/distribute/issue/33
.. _`issue39`: http://bitbucket.org/tarek/distribute/issue/39
.. _`issue40`: http://bitbucket.org/tarek/distribute/issue/40
.. _`issue41`: http://bitbucket.org/tarek/distribute/issue/41
.. _`issue44`: http://bitbucket.org/tarek/distribute/issue/44
Keywords: CPAN PyPI distutils eggs package management
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Python Software Foundation License
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2.4
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Archiving :: Packaging
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
-546
View File
@@ -1,546 +0,0 @@
#!python
"""Bootstrap distribute installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from distribute_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import os
import shutil
import sys
import time
import fnmatch
import tempfile
import tarfile
import optparse
from distutils import log
try:
from site import USER_SITE
except ImportError:
USER_SITE = None
try:
import subprocess
def _python_cmd(*args):
args = (sys.executable,) + args
return subprocess.call(args) == 0
except ImportError:
# will be used for python 2.3
def _python_cmd(*args):
args = (sys.executable,) + args
# quoting arguments if windows
if sys.platform == 'win32':
def quote(arg):
if ' ' in arg:
return '"%s"' % arg
return arg
args = [quote(arg) for arg in args]
return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
DEFAULT_VERSION = "0.6.34"
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
SETUPTOOLS_FAKED_VERSION = "0.6c11"
SETUPTOOLS_PKG_INFO = """\
Metadata-Version: 1.0
Name: setuptools
Version: %s
Summary: xxxx
Home-page: xxx
Author: xxx
Author-email: xxx
License: xxx
Description: xxx
""" % SETUPTOOLS_FAKED_VERSION
def _install(tarball, install_args=()):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
old_wd = os.getcwd()
try:
os.chdir(tmpdir)
tar = tarfile.open(tarball)
_extractall(tar)
tar.close()
# going in the directory
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
os.chdir(subdir)
log.warn('Now working in %s', subdir)
# installing
log.warn('Installing Distribute')
if not _python_cmd('setup.py', 'install', *install_args):
log.warn('Something went wrong during the installation.')
log.warn('See the error message above.')
# exitcode will be 2
return 2
finally:
os.chdir(old_wd)
shutil.rmtree(tmpdir)
def _build_egg(egg, tarball, to_dir):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
old_wd = os.getcwd()
try:
os.chdir(tmpdir)
tar = tarfile.open(tarball)
_extractall(tar)
tar.close()
# going in the directory
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
os.chdir(subdir)
log.warn('Now working in %s', subdir)
# building an egg
log.warn('Building a Distribute egg in %s', to_dir)
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
finally:
os.chdir(old_wd)
shutil.rmtree(tmpdir)
# returning the result
log.warn(egg)
if not os.path.exists(egg):
raise IOError('Could not build the egg.')
def _do_download(version, download_base, to_dir, download_delay):
egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
% (version, sys.version_info[0], sys.version_info[1]))
if not os.path.exists(egg):
tarball = download_setuptools(version, download_base,
to_dir, download_delay)
_build_egg(egg, tarball, to_dir)
sys.path.insert(0, egg)
import setuptools
setuptools.bootstrap_install_from = egg
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, download_delay=15, no_fake=True):
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
was_imported = 'pkg_resources' in sys.modules or \
'setuptools' in sys.modules
try:
try:
import pkg_resources
if not hasattr(pkg_resources, '_distribute'):
if not no_fake:
_fake_setuptools()
raise ImportError
except ImportError:
return _do_download(version, download_base, to_dir, download_delay)
try:
pkg_resources.require("distribute>=" + version)
return
except pkg_resources.VersionConflict:
e = sys.exc_info()[1]
if was_imported:
sys.stderr.write(
"The required version of distribute (>=%s) is not available,\n"
"and can't be installed while this script is running. Please\n"
"install a more recent version first, using\n"
"'easy_install -U distribute'."
"\n\n(Currently using %r)\n" % (version, e.args[0]))
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return _do_download(version, download_base, to_dir,
download_delay)
except pkg_resources.DistributionNotFound:
return _do_download(version, download_base, to_dir,
download_delay)
finally:
if not no_fake:
_create_fake_setuptools_pkg_info(to_dir)
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15):
"""Download distribute from a specified location and return its filename
`version` should be a valid distribute version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download
attempt.
"""
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
tgz_name = "distribute-%s.tar.gz" % version
url = download_base + tgz_name
saveto = os.path.join(to_dir, tgz_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
log.warn("Downloading %s", url)
src = urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = src.read()
dst = open(saveto, "wb")
dst.write(data)
finally:
if src:
src.close()
if dst:
dst.close()
return os.path.realpath(saveto)
def _no_sandbox(function):
def __no_sandbox(*args, **kw):
try:
from setuptools.sandbox import DirectorySandbox
if not hasattr(DirectorySandbox, '_old'):
def violation(*args):
pass
DirectorySandbox._old = DirectorySandbox._violation
DirectorySandbox._violation = violation
patched = True
else:
patched = False
except ImportError:
patched = False
try:
return function(*args, **kw)
finally:
if patched:
DirectorySandbox._violation = DirectorySandbox._old
del DirectorySandbox._old
return __no_sandbox
def _patch_file(path, content):
"""Will backup the file then patch it"""
f = open(path)
existing_content = f.read()
f.close()
if existing_content == content:
# already patched
log.warn('Already patched.')
return False
log.warn('Patching...')
_rename_path(path)
f = open(path, 'w')
try:
f.write(content)
finally:
f.close()
return True
_patch_file = _no_sandbox(_patch_file)
def _same_content(path, content):
f = open(path)
existing_content = f.read()
f.close()
return existing_content == content
def _rename_path(path):
new_name = path + '.OLD.%s' % time.time()
log.warn('Renaming %s to %s', path, new_name)
os.rename(path, new_name)
return new_name
def _remove_flat_installation(placeholder):
if not os.path.isdir(placeholder):
log.warn('Unkown installation at %s', placeholder)
return False
found = False
for file in os.listdir(placeholder):
if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
found = True
break
if not found:
log.warn('Could not locate setuptools*.egg-info')
return
log.warn('Moving elements out of the way...')
pkg_info = os.path.join(placeholder, file)
if os.path.isdir(pkg_info):
patched = _patch_egg_dir(pkg_info)
else:
patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
if not patched:
log.warn('%s already patched.', pkg_info)
return False
# now let's move the files out of the way
for element in ('setuptools', 'pkg_resources.py', 'site.py'):
element = os.path.join(placeholder, element)
if os.path.exists(element):
_rename_path(element)
else:
log.warn('Could not find the %s element of the '
'Setuptools distribution', element)
return True
_remove_flat_installation = _no_sandbox(_remove_flat_installation)
def _after_install(dist):
log.warn('After install bootstrap.')
placeholder = dist.get_command_obj('install').install_purelib
_create_fake_setuptools_pkg_info(placeholder)
def _create_fake_setuptools_pkg_info(placeholder):
if not placeholder or not os.path.exists(placeholder):
log.warn('Could not find the install location')
return
pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
setuptools_file = 'setuptools-%s-py%s.egg-info' % \
(SETUPTOOLS_FAKED_VERSION, pyver)
pkg_info = os.path.join(placeholder, setuptools_file)
if os.path.exists(pkg_info):
log.warn('%s already exists', pkg_info)
return
log.warn('Creating %s', pkg_info)
try:
f = open(pkg_info, 'w')
except EnvironmentError:
log.warn("Don't have permissions to write %s, skipping", pkg_info)
return
try:
f.write(SETUPTOOLS_PKG_INFO)
finally:
f.close()
pth_file = os.path.join(placeholder, 'setuptools.pth')
log.warn('Creating %s', pth_file)
f = open(pth_file, 'w')
try:
f.write(os.path.join(os.curdir, setuptools_file))
finally:
f.close()
_create_fake_setuptools_pkg_info = _no_sandbox(
_create_fake_setuptools_pkg_info
)
def _patch_egg_dir(path):
# let's check if it's already patched
pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
if os.path.exists(pkg_info):
if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
log.warn('%s already patched.', pkg_info)
return False
_rename_path(path)
os.mkdir(path)
os.mkdir(os.path.join(path, 'EGG-INFO'))
pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
f = open(pkg_info, 'w')
try:
f.write(SETUPTOOLS_PKG_INFO)
finally:
f.close()
return True
_patch_egg_dir = _no_sandbox(_patch_egg_dir)
def _before_install():
log.warn('Before install bootstrap.')
_fake_setuptools()
def _under_prefix(location):
if 'install' not in sys.argv:
return True
args = sys.argv[sys.argv.index('install') + 1:]
for index, arg in enumerate(args):
for option in ('--root', '--prefix'):
if arg.startswith('%s=' % option):
top_dir = arg.split('root=')[-1]
return location.startswith(top_dir)
elif arg == option:
if len(args) > index:
top_dir = args[index + 1]
return location.startswith(top_dir)
if arg == '--user' and USER_SITE is not None:
return location.startswith(USER_SITE)
return True
def _fake_setuptools():
log.warn('Scanning installed packages')
try:
import pkg_resources
except ImportError:
# we're cool
log.warn('Setuptools or Distribute does not seem to be installed.')
return
ws = pkg_resources.working_set
try:
setuptools_dist = ws.find(
pkg_resources.Requirement.parse('setuptools', replacement=False)
)
except TypeError:
# old distribute API
setuptools_dist = ws.find(
pkg_resources.Requirement.parse('setuptools')
)
if setuptools_dist is None:
log.warn('No setuptools distribution found')
return
# detecting if it was already faked
setuptools_location = setuptools_dist.location
log.warn('Setuptools installation detected at %s', setuptools_location)
# if --root or --preix was provided, and if
# setuptools is not located in them, we don't patch it
if not _under_prefix(setuptools_location):
log.warn('Not patching, --root or --prefix is installing Distribute'
' in another location')
return
# let's see if its an egg
if not setuptools_location.endswith('.egg'):
log.warn('Non-egg installation')
res = _remove_flat_installation(setuptools_location)
if not res:
return
else:
log.warn('Egg installation')
pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
if (os.path.exists(pkg_info) and
_same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
log.warn('Already patched.')
return
log.warn('Patching...')
# let's create a fake egg replacing setuptools one
res = _patch_egg_dir(setuptools_location)
if not res:
return
log.warn('Patching complete.')
_relaunch()
def _relaunch():
log.warn('Relaunching...')
# we have to relaunch the process
# pip marker to avoid a relaunch bug
_cmd1 = ['-c', 'install', '--single-version-externally-managed']
_cmd2 = ['-c', 'install', '--record']
if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2:
sys.argv[0] = 'setup.py'
args = [sys.executable] + sys.argv
sys.exit(subprocess.call(args))
def _extractall(self, path=".", members=None):
"""Extract all members from the archive to the current working
directory and set owner, modification time and permissions on
directories afterwards. `path' specifies a different directory
to extract to. `members' is optional and must be a subset of the
list returned by getmembers().
"""
import copy
import operator
from tarfile import ExtractError
directories = []
if members is None:
members = self
for tarinfo in members:
if tarinfo.isdir():
# Extract directories with a safe mode.
directories.append(tarinfo)
tarinfo = copy.copy(tarinfo)
tarinfo.mode = 448 # decimal for oct 0700
self.extract(tarinfo, path)
# Reverse sort directories.
if sys.version_info < (2, 4):
def sorter(dir1, dir2):
return cmp(dir1.name, dir2.name)
directories.sort(sorter)
directories.reverse()
else:
directories.sort(key=operator.attrgetter('name'), reverse=True)
# Set correct owner, mtime and filemode on directories.
for tarinfo in directories:
dirpath = os.path.join(path, tarinfo.name)
try:
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
except ExtractError:
e = sys.exc_info()[1]
if self.errorlevel > 1:
raise
else:
self._dbg(1, "tarfile: %s" % e)
def _build_install_args(options):
"""
Build the arguments to 'python setup.py install' on the distribute package
"""
install_args = []
if options.user_install:
if sys.version_info < (2, 6):
log.warn("--user requires Python 2.6 or later")
raise SystemExit(1)
install_args.append('--user')
return install_args
def _parse_args():
"""
Parse the command line for options
"""
parser = optparse.OptionParser()
parser.add_option(
'--user', dest='user_install', action='store_true', default=False,
help='install in user site package (requires Python 2.6 or later)')
parser.add_option(
'--download-base', dest='download_base', metavar="URL",
default=DEFAULT_URL,
help='alternative URL from where to download the distribute package')
options, args = parser.parse_args()
# positional arguments are ignored
return options
def main(version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
options = _parse_args()
tarball = download_setuptools(download_base=options.download_base)
return _install(tarball, _build_install_args(options))
if __name__ == '__main__':
sys.exit(main())
@@ -1,8 +0,0 @@
<h3>Download</h3>
<p>Current version: <b>{{ version }}</b></p>
<p>Get Distribute from the <a href="http://pypi.python.org/pypi/distribute"> Python Package Index</a>
<h3>Questions? Suggestions? Contributions?</h3>
<p>Visit the <a href="http://bitbucket.org/tarek/distribute">Distribute project page</a> </p>
File diff suppressed because it is too large Load Diff
@@ -1,36 +0,0 @@
Welcome to Distribute's documentation!
======================================
`Distribute` is a fork of the `Setuptools` project.
Distribute is intended to replace Setuptools as the standard method for
working with Python module distributions.
For those who may wonder why they should switch to Distribute over Setuptools, its quite simple:
- Distribute is a drop-in replacement for Setuptools
- The code is actively maintained, and has over 10 commiters
- Distribute offers Python 3 support !
Documentation content:
.. toctree::
:maxdepth: 2
roadmap
python3
using
setuptools
easy_install
pkg_resources
.. image:: http://python-distribute.org/pip_distribute.png
Design done by Idan Gazit (http://pixane.com) - License: cc-by-3.0
Copy & paste::
curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py
easy_install pip
@@ -1,121 +0,0 @@
=====================================================
Supporting both Python 2 and Python 3 with Distribute
=====================================================
Starting with version 0.6.2, Distribute supports Python 3. Installing and
using distribute for Python 3 code works exactly the same as for Python 2
code, but Distribute also helps you to support Python 2 and Python 3 from
the same source code by letting you run 2to3 on the code as a part of the
build process, by setting the keyword parameter ``use_2to3`` to True.
Distribute as help during porting
=================================
Distribute can make the porting process much easier by automatically running
2to3 as a part of the test running. To do this you need to configure the
setup.py so that you can run the unit tests with ``python setup.py test``.
See :ref:`test` for more information on this.
Once you have the tests running under Python 2, you can add the use_2to3
keyword parameters to setup(), and start running the tests under Python 3.
The test command will now first run the build command during which the code
will be converted with 2to3, and the tests will then be run from the build
directory, as opposed from the source directory as is normally done.
Distribute will convert all Python files, and also all doctests in Python
files. However, if you have doctests located in separate text files, these
will not automatically be converted. By adding them to the
``convert_2to3_doctests`` keyword parameter Distrubute will convert them as
well.
By default, the conversion uses all fixers in the ``lib2to3.fixers`` package.
To use additional fixers, the parameter ``use_2to3_fixers`` can be set
to a list of names of packages containing fixers. To exclude fixers, the
parameter ``use_2to3_exclude_fixers`` can be set to fixer names to be
skipped.
A typical setup.py can look something like this::
from setuptools import setup
setup(
name='your.module',
version = '1.0',
description='This is your awesome module',
author='You',
author_email='your@email',
package_dir = {'': 'src'},
packages = ['your', 'you.module'],
test_suite = 'your.module.tests',
use_2to3 = True,
convert_2to3_doctests = ['src/your/module/README.txt'],
use_2to3_fixers = ['your.fixers'],
use_2to3_exclude_fixers = ['lib2to3.fixes.fix_import'],
)
Differential conversion
-----------------------
Note that a file will only be copied and converted during the build process
if the source file has been changed. If you add a file to the doctests
that should be converted, it will not be converted the next time you run
the tests, since it hasn't been modified. You need to remove it from the
build directory. Also if you run the build, install or test commands before
adding the use_2to3 parameter, you will have to remove the build directory
before you run the test command, as the files otherwise will seem updated,
and no conversion will happen.
In general, if code doesn't seem to be converted, deleting the build directory
and trying again is a good saferguard against the build directory getting
"out of sync" with the source directory.
Distributing Python 3 modules
=============================
You can distribute your modules with Python 3 support in different ways. A
normal source distribution will work, but can be slow in installing, as the
2to3 process will be run during the install. But you can also distribute
the module in binary format, such as a binary egg. That egg will contain the
already converted code, and hence no 2to3 conversion is needed during install.
Advanced features
=================
If you don't want to run the 2to3 conversion on the doctests in Python files,
you can turn that off by setting ``setuptools.use_2to3_on_doctests = False``.
Note on compatibility with setuptools
=====================================
Setuptools do not know about the new keyword parameters to support Python 3.
As a result it will warn about the unknown keyword parameters if you use
setuptools instead of Distribute under Python 2. This is not an error, and
install process will continue as normal, but if you want to get rid of that
error this is easy. Simply conditionally add the new parameters into an extra
dict and pass that dict into setup()::
from setuptools import setup
import sys
extra = {}
if sys.version_info >= (3,):
extra['use_2to3'] = True
extra['convert_2to3_doctests'] = ['src/your/module/README.txt']
extra['use_2to3_fixers'] = ['your.fixers']
setup(
name='your.module',
version = '1.0',
description='This is your awesome module',
author='You',
author_email='your@email',
package_dir = {'': 'src'},
packages = ['your', 'you.module'],
test_suite = 'your.module.tests',
**extra
)
This way the parameters will only be used under Python 3, where you have to
use Distribute.
@@ -1,86 +0,0 @@
=======
Roadmap
=======
Distribute has two branches:
- 0.6.x : provides a Setuptools-0.6cX compatible version
- 0.7.x : will provide a refactoring
0.6.x
=====
Not "much" is going to happen here, we want this branch to be helpful
to the community *today* by addressing the 40-or-so bugs
that were found in Setuptools and never fixed. This is eventually
happen soon because its development is
fast : there are up to 5 commiters that are working on it very often
(and the number grows weekly.)
The biggest issue with this branch is that it is providing the same
packages and modules setuptools does, and this
requires some bootstrapping work where we make sure once Distribute is
installed, all Distribution that requires Setuptools
will continue to work. This is done by faking the metadata of
Setuptools 0.6c9. That's the only way we found to do this.
There's one major thing though: thanks to the work of Lennart, Alex,
Martin, this branch supports Python 3,
which is great to have to speed up Py3 adoption.
The goal of the 0.6.x is to remove as much bugs as we can, and try if
possible to remove the patches done
on Distutils. We will support 0.6.x maintenance for years and we will
promote its usage everywhere instead of
Setuptools.
Some new commands are added there, when they are helpful and don't
interact with the rest. I am thinking
about "upload_docs" that let you upload documentation to PyPI. The
goal is to move it to Distutils
at some point, if the documentation feature of PyPI stays and starts to be used.
0.7.x
=====
We've started to refactor Distribute with this roadmap in mind (and
no, as someone said, it's not vaporware,
we've done a lot already)
- 0.7.x can be installed and used with 0.6.x
- easy_install is going to be deprecated ! use Pip !
- the version system will be deprecated, in favor of the one in Distutils
- no more Distutils monkey-patch that happens once you use the code
(things like 'from distutils import cmd; cmd.Command = CustomCommand')
- no more custom site.py (that is: if something misses in Python's
site.py we'll add it there instead of patching it)
- no more namespaced packages system, if PEP 382 (namespaces package
support) makes it to 2.7
- The code is splitted in many packages and might be distributed under
several distributions.
- distribute.resources: that's the old pkg_resources, but
reorganized in clean, pep-8 modules. This package will
only contain the query APIs and will focus on being PEP 376
compatible. We will promote its usage and see if Pip wants
to use it as a basis.
It will probably shrink a lot though, once the stdlib provides PEP 376 support.
- distribute.entrypoints: that's the old pkg_resources entry points
system, but on its own. it uses distribute.resources
- distribute.index: that's package_index and a few other things.
everything required to interact with PyPI. We will promote
its usage and see if Pip wants to use it as a basis.
- distribute.core (might be renamed to main): that's everything
else, and uses the other packages.
Goal: A first release before (or when) Python 2.7 / 3.2 is out.
@@ -1,21 +0,0 @@
================================
Using Distribute in your project
================================
To use Distribute in your project, the recommended way is to ship
`distribute_setup.py` alongside your `setup.py` script and call
it at the very begining of `setup.py` like this::
from distribute_setup import use_setuptools
use_setuptools()
Another way is to add ``Distribute`` in the ``install_requires`` option::
from setuptools import setup
setup(...
install_requires=['distribute']
)
XXX to be finished
@@ -1,540 +0,0 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 170px;
}
div.sphinxsidebar #searchbox input[type="submit"] {
width: 30px;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}
@@ -1,236 +0,0 @@
/**
* Sphinx stylesheet -- default theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Arial, sans-serif;
font-size: 100%;
background-color: #111111;
color: #555555;
margin: 0;
padding: 0;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 300px;
}
hr{
border: 1px solid #B1B4B6;
}
div.document {
background-color: #fafafa;
}
div.body {
background-color: #ffffff;
color: #3E4349;
padding: 1em 30px 30px 30px;
font-size: 0.9em;
}
div.footer {
color: #555;
width: 100%;
padding: 13px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #444444;
}
div.related {
background-color: #6BA81E;
line-height: 36px;
color: #ffffff;
text-shadow: 0px 1px 0 #444444;
font-size: 1.1em;
}
div.related a {
color: #E2F3CC;
}
div.related .right {
font-size: 0.9em;
}
div.sphinxsidebar {
font-size: 0.9em;
line-height: 1.5em;
width: 300px;
}
div.sphinxsidebarwrapper{
padding: 20px 0;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Arial, sans-serif;
color: #222222;
font-size: 1.2em;
font-weight: bold;
margin: 0;
padding: 5px 10px;
text-shadow: 1px 1px 0 white
}
div.sphinxsidebar h3 a {
color: #444444;
}
div.sphinxsidebar p {
color: #888888;
padding: 5px 20px;
margin: 0.5em 0px;
}
div.sphinxsidebar p.topless {
}
div.sphinxsidebar ul {
margin: 10px 10px 10px 20px;
padding: 0;
color: #000000;
}
div.sphinxsidebar a {
color: #444444;
}
div.sphinxsidebar a:hover {
color: #E32E00;
}
div.sphinxsidebar input {
border: 1px solid #cccccc;
font-family: sans-serif;
font-size: 1.1em;
padding: 0.15em 0.3em;
}
div.sphinxsidebar input[type=text]{
margin-left: 20px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #005B81;
text-decoration: none;
}
a:hover {
color: #E32E00;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: Arial, sans-serif;
font-weight: normal;
color: #212224;
margin: 30px 0px 10px 0px;
padding: 5px 0 5px 0px;
text-shadow: 0px 1px 0 white;
border-bottom: 1px solid #C8D5E3;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 150%; }
div.body h3 { font-size: 120%; }
div.body h4 { font-size: 110%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
line-height: 1.8em;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.highlight{
background-color: white;
}
div.note {
background-color: #eeeeee;
border: 1px solid #cccccc;
}
div.seealso {
background-color: #ffffcc;
border: 1px solid #ffff66;
}
div.topic {
background-color: #fafafa;
border-width: 0;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #ff6666;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 10px;
background-color: #fafafa;
color: #222222;
line-height: 1.5em;
font-size: 1.1em;
margin: 1.5em 0 1.5em 0;
-webkit-box-shadow: 0px 0px 4px #d8d8d8;
-moz-box-shadow: 0px 0px 4px #d8d8d8;
box-shadow: 0px 0px 4px #d8d8d8;
}
tt {
color: #222222;
padding: 1px 2px;
font-size: 1.2em;
font-family: monospace;
}
#table-of-contents ul {
padding-left: 2em;
}
@@ -1,54 +0,0 @@
.c { color: #999988; font-style: italic } /* Comment */
.k { font-weight: bold } /* Keyword */
.o { font-weight: bold } /* Operator */
.cm { color: #999988; font-style: italic } /* Comment.Multiline */
.cp { color: #999999; font-weight: bold } /* Comment.preproc */
.c1 { color: #999988; font-style: italic } /* Comment.Single */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #999999 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #111 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #aaaaaa } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc { font-weight: bold } /* Keyword.Constant */
.kd { font-weight: bold } /* Keyword.Declaration */
.kp { font-weight: bold } /* Keyword.Pseudo */
.kr { font-weight: bold } /* Keyword.Reserved */
.kt { color: #445588; font-weight: bold } /* Keyword.Type */
.m { color: #009999 } /* Literal.Number */
.s { color: #bb8844 } /* Literal.String */
.na { color: #008080 } /* Name.Attribute */
.nb { color: #999999 } /* Name.Builtin */
.nc { color: #445588; font-weight: bold } /* Name.Class */
.no { color: #ff99ff } /* Name.Constant */
.ni { color: #800080 } /* Name.Entity */
.ne { color: #990000; font-weight: bold } /* Name.Exception */
.nf { color: #990000; font-weight: bold } /* Name.Function */
.nn { color: #555555 } /* Name.Namespace */
.nt { color: #000080 } /* Name.Tag */
.nv { color: purple } /* Name.Variable */
.ow { font-weight: bold } /* Operator.Word */
.mf { color: #009999 } /* Literal.Number.Float */
.mh { color: #009999 } /* Literal.Number.Hex */
.mi { color: #009999 } /* Literal.Number.Integer */
.mo { color: #009999 } /* Literal.Number.Oct */
.sb { color: #bb8844 } /* Literal.String.Backtick */
.sc { color: #bb8844 } /* Literal.String.Char */
.sd { color: #bb8844 } /* Literal.String.Doc */
.s2 { color: #bb8844 } /* Literal.String.Double */
.se { color: #bb8844 } /* Literal.String.Escape */
.sh { color: #bb8844 } /* Literal.String.Heredoc */
.si { color: #bb8844 } /* Literal.String.Interpol */
.sx { color: #bb8844 } /* Literal.String.Other */
.sr { color: #808000 } /* Literal.String.Regex */
.s1 { color: #bb8844 } /* Literal.String.Single */
.ss { color: #bb8844 } /* Literal.String.Symbol */
.bp { color: #999999 } /* Name.Builtin.Pseudo */
.vc { color: #ff99ff } /* Name.Variable.Class */
.vg { color: #ff99ff } /* Name.Variable.Global */
.vi { color: #ff99ff } /* Name.Variable.Instance */
.il { color: #009999 } /* Literal.Number.Integer.Long */
-36
View File
@@ -1,36 +0,0 @@
Welcome to Distribute's documentation!
======================================
`Distribute` is a fork of the `Setuptools` project.
Distribute is intended to replace Setuptools as the standard method for
working with Python module distributions.
For those who may wonder why they should switch to Distribute over Setuptools, its quite simple:
- Distribute is a drop-in replacement for Setuptools
- The code is actively maintained, and has over 10 commiters
- Distribute offers Python 3 support !
Documentation content:
.. toctree::
:maxdepth: 2
roadmap
python3
using
setuptools
easy_install
pkg_resources
.. image:: http://python-distribute.org/pip_distribute.png
Design done by Idan Gazit (http://pixane.com) - License: cc-by-3.0
Copy & paste::
curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py
easy_install pip
File diff suppressed because it is too large Load Diff
-86
View File
@@ -1,86 +0,0 @@
=======
Roadmap
=======
Distribute has two branches:
- 0.6.x : provides a Setuptools-0.6cX compatible version
- 0.7.x : will provide a refactoring
0.6.x
=====
Not "much" is going to happen here, we want this branch to be helpful
to the community *today* by addressing the 40-or-so bugs
that were found in Setuptools and never fixed. This is eventually
happen soon because its development is
fast : there are up to 5 commiters that are working on it very often
(and the number grows weekly.)
The biggest issue with this branch is that it is providing the same
packages and modules setuptools does, and this
requires some bootstrapping work where we make sure once Distribute is
installed, all Distribution that requires Setuptools
will continue to work. This is done by faking the metadata of
Setuptools 0.6c9. That's the only way we found to do this.
There's one major thing though: thanks to the work of Lennart, Alex,
Martin, this branch supports Python 3,
which is great to have to speed up Py3 adoption.
The goal of the 0.6.x is to remove as much bugs as we can, and try if
possible to remove the patches done
on Distutils. We will support 0.6.x maintenance for years and we will
promote its usage everywhere instead of
Setuptools.
Some new commands are added there, when they are helpful and don't
interact with the rest. I am thinking
about "upload_docs" that let you upload documentation to PyPI. The
goal is to move it to Distutils
at some point, if the documentation feature of PyPI stays and starts to be used.
0.7.x
=====
We've started to refactor Distribute with this roadmap in mind (and
no, as someone said, it's not vaporware,
we've done a lot already)
- 0.7.x can be installed and used with 0.6.x
- easy_install is going to be deprecated ! use Pip !
- the version system will be deprecated, in favor of the one in Distutils
- no more Distutils monkey-patch that happens once you use the code
(things like 'from distutils import cmd; cmd.Command = CustomCommand')
- no more custom site.py (that is: if something misses in Python's
site.py we'll add it there instead of patching it)
- no more namespaced packages system, if PEP 382 (namespaces package
support) makes it to 2.7
- The code is splitted in many packages and might be distributed under
several distributions.
- distribute.resources: that's the old pkg_resources, but
reorganized in clean, pep-8 modules. This package will
only contain the query APIs and will focus on being PEP 376
compatible. We will promote its usage and see if Pip wants
to use it as a basis.
It will probably shrink a lot though, once the stdlib provides PEP 376 support.
- distribute.entrypoints: that's the old pkg_resources entry points
system, but on its own. it uses distribute.resources
- distribute.index: that's package_index and a few other things.
everything required to interact with PyPI. We will promote
its usage and see if Pip wants to use it as a basis.
- distribute.core (might be renamed to main): that's everything
else, and uses the other packages.
Goal: A first release before (or when) Python 2.7 / 3.2 is out.
File diff suppressed because it is too large Load Diff
-21
View File
@@ -1,21 +0,0 @@
================================
Using Distribute in your project
================================
To use Distribute in your project, the recommended way is to ship
`distribute_setup.py` alongside your `setup.py` script and call
it at the very begining of `setup.py` like this::
from distribute_setup import use_setuptools
use_setuptools()
Another way is to add ``Distribute`` in the ``install_requires`` option::
from setuptools import setup
setup(...
install_requires=['distribute']
)
XXX to be finished
-170
View File
@@ -1,170 +0,0 @@
#!/usr/bin/env python
"""
Script to fully automate the release process. Requires Python 2.6+
with sphinx installed and the 'hg' command on the path.
"""
from __future__ import print_function
import subprocess
import shutil
import os
import sys
import urllib2
import getpass
import collections
try:
import keyring
except Exception:
pass
VERSION = '0.6.34'
def get_next_version():
digits = map(int, VERSION.split('.'))
digits[-1] += 1
return '.'.join(map(str, digits))
NEXT_VERSION = get_next_version()
files_with_versions = ('docs/conf.py', 'setup.py', 'release.py',
'README.txt', 'distribute_setup.py')
def get_repo_name():
"""
Get the repo name from the hgrc default path.
"""
default = subprocess.check_output('hg paths default').strip()
parts = default.split('/')
if parts[-1] == '':
parts.pop()
return '/'.join(parts[-2:])
def get_mercurial_creds(system='https://bitbucket.org', username=None):
"""
Return named tuple of username,password in much the same way that
Mercurial would (from the keyring).
"""
# todo: consider getting this from .hgrc
username = username or getpass.getuser()
keyring_username = '@@'.join((username, system))
system = '@'.join((keyring_username, 'Mercurial'))
password = (
keyring.get_password(system, keyring_username)
if 'keyring' in globals()
else None
)
if not password:
password = getpass.getpass()
Credential = collections.namedtuple('Credential', 'username password')
return Credential(username, password)
def add_milestone_and_version(version=NEXT_VERSION):
auth = 'Basic ' + ':'.join(get_mercurial_creds()).encode('base64').strip()
headers = {
'Authorization': auth,
}
base = 'https://api.bitbucket.org'
for type in 'milestones', 'versions':
url = (base + '/1.0/repositories/{repo}/issues/{type}'
.format(repo = get_repo_name(), type=type))
req = urllib2.Request(url = url, headers = headers,
data='name='+version)
try:
urllib2.urlopen(req)
except urllib2.HTTPError as e:
print(e.fp.read())
def bump_versions():
list(map(bump_version, files_with_versions))
def bump_version(filename):
with open(filename, 'rb') as f:
lines = [line.replace(VERSION, NEXT_VERSION) for line in f]
with open(filename, 'wb') as f:
f.writelines(lines)
def do_release():
assert all(map(os.path.exists, files_with_versions)), (
"Expected file(s) missing")
assert has_sphinx(), "You must have Sphinx installed to release"
res = raw_input('Have you read through the SCM changelog and '
'confirmed the changelog is current for releasing {VERSION}? '
.format(**globals()))
if not res.lower().startswith('y'):
print("Please do that")
raise SystemExit(1)
print("Travis-CI tests: http://travis-ci.org/#!/jaraco/distribute")
res = raw_input('Have you or has someone verified that the tests '
'pass on this revision? ')
if not res.lower().startswith('y'):
print("Please do that")
raise SystemExit(2)
subprocess.check_call(['hg', 'tag', VERSION])
subprocess.check_call(['hg', 'update', VERSION])
has_docs = build_docs()
if os.path.isdir('./dist'):
shutil.rmtree('./dist')
cmd = [sys.executable, 'setup.py', '-q', 'egg_info', '-RD', '-b', '',
'sdist', 'register', 'upload']
if has_docs:
cmd.append('upload_docs')
subprocess.check_call(cmd)
upload_bootstrap_script()
# update to the tip for the next operation
subprocess.check_call(['hg', 'update'])
# we just tagged the current version, bump for the next release.
bump_versions()
subprocess.check_call(['hg', 'ci', '-m',
'Bumped to {NEXT_VERSION} in preparation for next '
'release.'.format(**globals())])
# push the changes
subprocess.check_call(['hg', 'push'])
add_milestone_and_version()
def has_sphinx():
try:
devnull = open(os.path.devnull, 'wb')
subprocess.Popen(['sphinx-build', '--version'], stdout=devnull,
stderr=subprocess.STDOUT).wait()
except Exception:
return False
return True
def build_docs():
if not os.path.isdir('docs'):
return
if os.path.isdir('docs/build'):
shutil.rmtree('docs/build')
subprocess.check_call([
'sphinx-build',
'-b', 'html',
'-d', 'build/doctrees',
'.',
'build/html',
],
cwd='docs')
return True
def upload_bootstrap_script():
scp_command = 'pscp' if sys.platform.startswith('win') else 'scp'
try:
subprocess.check_call([scp_command, 'distribute_setup.py',
'pypi@ziade.org:python-distribute.org/'])
except:
print("Unable to upload bootstrap script. Ask Tarek to do it.")
if __name__ == '__main__':
do_release()
Binary file not shown.
Binary file not shown.
@@ -1,41 +0,0 @@
from distutils.command.bdist_wininst import bdist_wininst as _bdist_wininst
import os, sys
class bdist_wininst(_bdist_wininst):
def create_exe(self, arcname, fullname, bitmap=None):
_bdist_wininst.create_exe(self, arcname, fullname, bitmap)
dist_files = getattr(self.distribution, 'dist_files', [])
if self.target_version:
installer_name = os.path.join(self.dist_dir,
"%s.win32-py%s.exe" %
(fullname, self.target_version))
pyversion = self.target_version
# fix 2.5 bdist_wininst ignoring --target-version spec
bad = ('bdist_wininst','any',installer_name)
if bad in dist_files:
dist_files.remove(bad)
else:
installer_name = os.path.join(self.dist_dir,
"%s.win32.exe" % fullname)
pyversion = 'any'
good = ('bdist_wininst', pyversion, installer_name)
if good not in dist_files:
dist_files.append(good)
def reinitialize_command (self, command, reinit_subcommands=0):
cmd = self.distribution.reinitialize_command(
command, reinit_subcommands)
if command in ('install', 'install_lib'):
cmd.install_lib = None # work around distutils bug
return cmd
def run(self):
self._is_running = True
try:
_bdist_wininst.run(self)
finally:
self._is_running = False
-185
View File
@@ -1,185 +0,0 @@
"""distutils.command.upload
Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
from distutils.errors import *
from distutils.core import Command
from distutils.spawn import spawn
from distutils import log
try:
from hashlib import md5
except ImportError:
from md5 import md5
import os
import socket
import platform
import ConfigParser
import httplib
import base64
import urlparse
import cStringIO as StringIO
class upload(Command):
description = "upload binary package to PyPI"
DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
user_options = [
('repository=', 'r',
"url of repository [default: %s]" % DEFAULT_REPOSITORY),
('show-response', None,
'display full response text from server'),
('sign', 's',
'sign files to upload using gpg'),
('identity=', 'i', 'GPG identity used to sign files'),
]
boolean_options = ['show-response', 'sign']
def initialize_options(self):
self.username = ''
self.password = ''
self.repository = ''
self.show_response = 0
self.sign = False
self.identity = None
def finalize_options(self):
if self.identity and not self.sign:
raise DistutilsOptionError(
"Must use --sign for --identity to have meaning"
)
if os.environ.has_key('HOME'):
rc = os.path.join(os.environ['HOME'], '.pypirc')
if os.path.exists(rc):
self.announce('Using PyPI login from %s' % rc)
config = ConfigParser.ConfigParser({
'username':'',
'password':'',
'repository':''})
config.read(rc)
if not self.repository:
self.repository = config.get('server-login', 'repository')
if not self.username:
self.username = config.get('server-login', 'username')
if not self.password:
self.password = config.get('server-login', 'password')
if not self.repository:
self.repository = self.DEFAULT_REPOSITORY
def run(self):
if not self.distribution.dist_files:
raise DistutilsOptionError("No dist file created in earlier command")
for command, pyversion, filename in self.distribution.dist_files:
self.upload_file(command, pyversion, filename)
def upload_file(self, command, pyversion, filename):
# Sign if requested
if self.sign:
gpg_args = ["gpg", "--detach-sign", "-a", filename]
if self.identity:
gpg_args[2:2] = ["--local-user", self.identity]
spawn(gpg_args,
dry_run=self.dry_run)
# Fill in the data
f = open(filename,'rb')
content = f.read()
f.close()
basename = os.path.basename(filename)
comment = ''
if command=='bdist_egg' and self.distribution.has_ext_modules():
comment = "built on %s" % platform.platform(terse=1)
data = {
':action':'file_upload',
'protocol_version':'1',
'name':self.distribution.get_name(),
'version':self.distribution.get_version(),
'content':(basename,content),
'filetype':command,
'pyversion':pyversion,
'md5_digest':md5(content).hexdigest(),
}
if command == 'bdist_rpm':
dist, version, id = platform.dist()
if dist:
comment = 'built for %s %s' % (dist, version)
elif command == 'bdist_dumb':
comment = 'built for %s' % platform.platform(terse=1)
data['comment'] = comment
if self.sign:
asc_file = open(filename + ".asc")
data['gpg_signature'] = (os.path.basename(filename) + ".asc", asc_file.read())
asc_file.close()
# set up the authentication
auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip()
# Build up the MIME payload for the POST data
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
sep_boundary = '\n--' + boundary
end_boundary = sep_boundary + '--'
body = StringIO.StringIO()
for key, value in data.items():
# handle multiple entries for the same name
if type(value) != type([]):
value = [value]
for value in value:
if type(value) is tuple:
fn = ';filename="%s"' % value[0]
value = value[1]
else:
fn = ""
value = str(value)
body.write(sep_boundary)
body.write('\nContent-Disposition: form-data; name="%s"'%key)
body.write(fn)
body.write("\n\n")
body.write(value)
if value and value[-1] == '\r':
body.write('\n') # write an extra newline (lurve Macs)
body.write(end_boundary)
body.write("\n")
body = body.getvalue()
self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
# build the Request
# We can't use urllib2 since we need to send the Basic
# auth right with the first request
schema, netloc, url, params, query, fragments = \
urlparse.urlparse(self.repository)
assert not params and not query and not fragments
if schema == 'http':
http = httplib.HTTPConnection(netloc)
elif schema == 'https':
http = httplib.HTTPSConnection(netloc)
else:
raise AssertionError, "unsupported schema "+schema
data = ''
loglevel = log.INFO
try:
http.connect()
http.putrequest("POST", url)
http.putheader('Content-type',
'multipart/form-data; boundary=%s'%boundary)
http.putheader('Content-length', str(len(body)))
http.putheader('Authorization', auth)
http.endheaders()
http.send(body)
except socket.error, e:
self.announce(str(e), log.ERROR)
return
r = http.getresponse()
if r.status == 200:
self.announce('Server response (%s): %s' % (r.status, r.reason),
log.INFO)
else:
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
print '-'*75, r.read(), '-'*75
@@ -1,6 +0,0 @@
# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r
__requires__ = """%(spec)r"""
from pkg_resources import require; require("""%(spec)r""")
del require
__file__ = """%(dev_path)r"""
execfile(__file__)
-75
View File
@@ -1,75 +0,0 @@
import urllib2
import sys
import os
if os.path.exists('distribute_setup.py'):
print 'distribute_setup.py exists in the current dir, aborting'
sys.exit(2)
print '**** Starting Test'
print '\n\n'
is_jython = sys.platform.startswith('java')
if is_jython:
import subprocess
print 'Downloading bootstrap'
file = urllib2.urlopen('http://nightly.ziade.org/distribute_setup.py')
f = open('distribute_setup.py', 'w')
f.write(file.read())
f.close()
# running it
args = [sys.executable] + ['distribute_setup.py']
if is_jython:
res = subprocess.call(args)
else:
res = os.spawnv(os.P_WAIT, sys.executable, args)
if res != 0:
print '**** Test failed, please send me the output at tarek@ziade.org'
os.remove('distribute_setup.py')
sys.exit(2)
# now checking if Distribute is installed
script = """\
import sys
try:
import setuptools
except ImportError:
sys.exit(0)
sys.exit(hasattr(setuptools, "_distribute"))
"""
root = 'script'
seed = 0
script_name = '%s%d.py' % (root, seed)
while os.path.exists(script_name):
seed += 1
script_name = '%s%d.py' % (root, seed)
f = open(script_name, 'w')
try:
f.write(script)
finally:
f.close()
try:
args = [sys.executable] + [script_name]
if is_jython:
res = subprocess.call(args)
else:
res = os.spawnv(os.P_WAIT, sys.executable, args)
print '\n\n'
if res:
print '**** Test is OK'
else:
print '**** Test failed, please send me the output at tarek@ziade.org'
finally:
if os.path.exists(script_name):
os.remove(script_name)
os.remove('distribute_setup.py')
BIN
View File
Binary file not shown.
-23
View File
@@ -1,23 +0,0 @@
MANIFEST
tests/test-scratch/*
tests/test-cache/*
tests/packages/FSPkg/FSPkg.egg-info
testenv
pip.egg-info/*
ScriptTest-*.egg
virtualenv-*.egg
nose-*.egg/*
wsgi_intercept-*.egg/*
WSGIProxy-*.egg/*
WebOb-*.egg
Paste-*.egg/*
mock-*egg
tests/tests_cache/*
dist/*
docs/_build/*
build/*
*.pyc
*.pyo
pip-log.txt
pip.log
*.~
-48
View File
@@ -1,48 +0,0 @@
Alex Grönholm
Alex Morega
Alexandre Conrad
Antti Kaihola
Armin Ronacher
Brian Rosner
Carl Meyer
Christian Oudard
Cody Soyland
Daniel Holth
Dave Abrahams
Francesco
Hugo Lopes Tavares
Ian Bicking
Igor Sobreira
Ionel Maries Cristian
Jakub Vysoky
Jannis Leidel
Jay Graves
John-Scott Atlakson
Jon Parise
Josh Bronson
Kelsey Hightower
Kenneth Belitzky
Kumar McMillan
Luke Macken
Masklinn
Marc Abramowitz
Marcus Smith
Matt Maker
Nowell Strite
Oliver Tonnhofer
Olivier Girardot
Patrick Jenkins
Paul Nasrat
Paul Oswald
Paul van der Linden
Peter Waller
Piet Delport
Qiangning Hong
Rene Dudfield
Ronny Pfannschmidt
Simon Cross
Stavros Korokithakis
Thomas Johansson
Vinay Sajip
Vitaly Babiy
Wil Tan
-6
View File
@@ -1,6 +0,0 @@
include AUTHORS.txt
include LICENSE.txt
recursive-include docs *.txt
recursive-include docs *.html
recursive-exclude docs/_build *.txt
prune docs/_build/_sources
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env python
import os
import sys
from packager import generate_script
here = os.path.dirname(os.path.abspath(__file__))
file_name = os.path.join(here, 'get-pip.py')
entry = """
import sys
try:
import setuptools
import pkg_resources
except ImportError:
raise SystemExit("An error occured while trying to run %s. Make sure "
"you have setuptools or distribute installed." % __file__)
import pip
pip.bootstrap()
"""
def main():
sys.stdout.write("Creating pip bootstrapper...")
script = generate_script(entry, ['pip'])
f = open(file_name, 'w')
try:
f.write(script)
finally:
f.close()
sys.stdout.write('done.\n')
if hasattr(os, 'chmod'):
oldmode = os.stat(file_name).st_mode & 07777
newmode = (oldmode | 0555) & 07777
os.chmod(file_name, newmode)
sys.stdout.write('Made resulting file %s executable.\n\n' % file_name)
if __name__ == '__main__':
main()
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env python
import os
import sys
from packager import generate_script
here = os.path.dirname(os.path.abspath(__file__))
file_name = os.path.join(here, 'run-pip.py')
entry = """
import sys
try:
import setuptools
import pkg_resources
except ImportError:
raise SystemExit("An error occured while trying to run %s. Make sure "
"you have setuptools or distribute installed." % __file__)
import pip
pip.main()
"""
def main():
sys.stdout.write("Creating standalone pip...")
script = generate_script(entry, ['pip'])
f = open(file_name, 'w')
try:
f.write(script)
finally:
f.close()
sys.stdout.write('done.\n')
if hasattr(os, 'chmod'):
oldmode = os.stat(file_name).st_mode & 07777
newmode = (oldmode | 0555) & 07777
os.chmod(file_name, newmode)
sys.stdout.write('Made resulting file %s executable.\n\n' % file_name)
if __name__ == '__main__':
main()
File diff suppressed because it is too large Load Diff
-68
View File
@@ -1,68 +0,0 @@
# Port of Ronny Pfannschmidt's genscript package
# https://bitbucket.org/RonnyPfannschmidt/genscript
import sys
import pickle
import zlib
import base64
import os
import fnmatch
def find_toplevel(name):
for syspath in sys.path:
lib = os.path.join(syspath, name)
if os.path.isdir(lib):
return lib
mod = lib + '.py'
if os.path.isfile(mod):
return mod
raise LookupError(name)
def pkgname(toplevel, rootpath, path):
parts = path.split(os.sep)[len(rootpath.split(os.sep)):]
return '.'.join([toplevel] + [os.path.splitext(x)[0] for x in parts])
def pkg_to_mapping(name):
toplevel = find_toplevel(name)
if os.path.isfile(toplevel):
return {name: toplevel.read()}
name2src = {}
for root, dirs, files in os.walk(toplevel):
for pyfile in files:
if fnmatch.fnmatch(pyfile, '*.py'):
pkg = pkgname(name, toplevel, os.path.join(root, pyfile))
f = open(os.path.join(root, pyfile))
try:
name2src[pkg] = f.read()
finally:
f.close()
return name2src
def compress_mapping(mapping):
data = pickle.dumps(mapping, 2)
data = zlib.compress(data, 9)
data = base64.encodestring(data)
data = data.decode('ascii')
return data
def compress_packages(names):
mapping = {}
for name in names:
mapping.update(pkg_to_mapping(name))
return compress_mapping(mapping)
def generate_script(entry, packages):
data = compress_packages(packages)
tmpl = open(os.path.join(os.path.dirname(__file__), 'template.py'))
exe = tmpl.read()
tmpl.close()
exe = exe.replace('@SOURCES@', data)
exe = exe.replace('@ENTRY@', entry)
return exe
-48
View File
@@ -1,48 +0,0 @@
#! /usr/bin/env python
sources = """
@SOURCES@"""
import os
import sys
import base64
import zlib
import tempfile
import shutil
def unpack(sources):
temp_dir = tempfile.mkdtemp('-scratchdir', 'unpacker-')
for package, content in sources.items():
filepath = package.split(".")
dirpath = os.sep.join(filepath[:-1])
packagedir = os.path.join(temp_dir, dirpath)
if not os.path.isdir(packagedir):
os.makedirs(packagedir)
mod = open(os.path.join(packagedir, "%s.py" % filepath[-1]), 'wb')
try:
mod.write(content.encode("ascii"))
finally:
mod.close()
return temp_dir
if __name__ == "__main__":
if sys.version_info >= (3, 0):
exec("def do_exec(co, loc): exec(co, loc)\n")
import pickle
sources = sources.encode("ascii") # ensure bytes
sources = pickle.loads(zlib.decompress(base64.decodebytes(sources)))
else:
import cPickle as pickle
exec("def do_exec(co, loc): exec co in loc\n")
sources = pickle.loads(zlib.decompress(base64.decodestring(sources)))
try:
temp_dir = unpack(sources)
sys.path.insert(0, temp_dir)
entry = """@ENTRY@"""
do_exec(entry, locals())
finally:
shutil.rmtree(temp_dir)
-130
View File
@@ -1,130 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-compressor.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-compressor.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/django-compressor"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-compressor"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
make -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

-237
View File
@@ -1,237 +0,0 @@
/**
* Sphinx stylesheet -- default theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Arial, sans-serif;
font-size: 100%;
background-color: #111111;
color: #555555;
margin: 0;
padding: 0;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 300px;
}
hr{
border: 1px solid #B1B4B6;
}
div.document {
background-color: #fafafa;
}
div.body {
background-color: #ffffff;
color: #3E4349;
padding: 1em 30px 30px 30px;
font-size: 0.9em;
}
div.footer {
color: #555;
width: 100%;
padding: 13px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #444444;
}
div.related {
background-color: #6BA81E;
line-height: 36px;
color: #ffffff;
text-shadow: 0px 1px 0 #444444;
font-size: 1.1em;
}
div.related a {
color: #E2F3CC;
}
div.related .right {
font-size: 0.9em;
}
div.sphinxsidebar {
font-size: 0.9em;
line-height: 1.5em;
width: 300px
}
div.sphinxsidebarwrapper{
padding: 20px 0;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Arial, sans-serif;
color: #222222;
font-size: 1.2em;
font-weight: bold;
margin: 0;
padding: 5px 10px;
text-shadow: 1px 1px 0 white
}
div.sphinxsidebar h3 a {
color: #444444;
}
div.sphinxsidebar p {
color: #888888;
padding: 5px 20px;
margin: 0.5em 0px;
}
div.sphinxsidebar p.topless {
}
div.sphinxsidebar ul {
margin: 10px 10px 10px 20px;
padding: 0;
color: #000000;
}
div.sphinxsidebar a {
color: #444444;
}
div.sphinxsidebar a:hover {
color: #E32E00;
}
div.sphinxsidebar input {
border: 1px solid #cccccc;
font-family: sans-serif;
font-size: 1.1em;
padding: 0.15em 0.3em;
}
div.sphinxsidebar input[type=text]{
margin-left: 20px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #005B81;
text-decoration: none;
}
a:hover {
color: #E32E00;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: Arial, sans-serif;
font-weight: normal;
color: #212224;
margin: 30px 0px 10px 0px;
padding: 5px 0 5px 0px;
text-shadow: 0px 1px 0 white;
border-bottom: 1px solid #C8D5E3;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 150%; }
div.body h3 { font-size: 120%; }
div.body h4 { font-size: 110%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
line-height: 1.8em;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.highlight{
background-color: white;
}
div.note {
background-color: #eeeeee;
border: 1px solid #cccccc;
}
div.seealso {
background-color: #ffffcc;
border: 1px solid #ffff66;
}
div.topic {
background-color: #fafafa;
border-width: 0;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #ff6666;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 10px;
background-color: #fafafa;
color: #222222;
line-height: 1.5em;
font-size: 1.1em;
margin: 1.5em 0 1.5em 0;
-webkit-box-shadow: 0px 0px 4px #d8d8d8;
-moz-box-shadow: 0px 0px 4px #d8d8d8;
box-shadow: 0px 0px 4px #d8d8d8;
}
tt {
color: #222222;
padding: 1px 2px;
font-size: 1.2em;
font-family: monospace;
}
#table-of-contents ul {
padding-left: 2em;
}
-54
View File
@@ -1,54 +0,0 @@
.c { color: #999988; font-style: italic } /* Comment */
.k { font-weight: bold } /* Keyword */
.o { font-weight: bold } /* Operator */
.cm { color: #999988; font-style: italic } /* Comment.Multiline */
.cp { color: #999999; font-weight: bold } /* Comment.preproc */
.c1 { color: #999988; font-style: italic } /* Comment.Single */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #999999 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #111 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #aaaaaa } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc { font-weight: bold } /* Keyword.Constant */
.kd { font-weight: bold } /* Keyword.Declaration */
.kp { font-weight: bold } /* Keyword.Pseudo */
.kr { font-weight: bold } /* Keyword.Reserved */
.kt { color: #445588; font-weight: bold } /* Keyword.Type */
.m { color: #009999 } /* Literal.Number */
.s { color: #bb8844 } /* Literal.String */
.na { color: #008080 } /* Name.Attribute */
.nb { color: #999999 } /* Name.Builtin */
.nc { color: #445588; font-weight: bold } /* Name.Class */
.no { color: #ff99ff } /* Name.Constant */
.ni { color: #800080 } /* Name.Entity */
.ne { color: #990000; font-weight: bold } /* Name.Exception */
.nf { color: #990000; font-weight: bold } /* Name.Function */
.nn { color: #555555 } /* Name.Namespace */
.nt { color: #000080 } /* Name.Tag */
.nv { color: purple } /* Name.Variable */
.ow { font-weight: bold } /* Operator.Word */
.mf { color: #009999 } /* Literal.Number.Float */
.mh { color: #009999 } /* Literal.Number.Hex */
.mi { color: #009999 } /* Literal.Number.Integer */
.mo { color: #009999 } /* Literal.Number.Oct */
.sb { color: #bb8844 } /* Literal.String.Backtick */
.sc { color: #bb8844 } /* Literal.String.Char */
.sd { color: #bb8844 } /* Literal.String.Doc */
.s2 { color: #bb8844 } /* Literal.String.Double */
.se { color: #bb8844 } /* Literal.String.Escape */
.sh { color: #bb8844 } /* Literal.String.Heredoc */
.si { color: #bb8844 } /* Literal.String.Interpol */
.sx { color: #bb8844 } /* Literal.String.Other */
.sr { color: #808000 } /* Literal.String.Regex */
.s1 { color: #bb8844 } /* Literal.String.Single */
.ss { color: #bb8844 } /* Literal.String.Symbol */
.bp { color: #999999 } /* Name.Builtin.Pseudo */
.vc { color: #ff99ff } /* Name.Variable.Class */
.vg { color: #ff99ff } /* Name.Variable.Global */
.vi { color: #ff99ff } /* Name.Variable.Instance */
.il { color: #009999 } /* Literal.Number.Integer.Long */
-4
View File
@@ -1,4 +0,0 @@
[theme]
inherit = basic
stylesheet = nature.css
pygments_style = tango
-252
View File
@@ -1,252 +0,0 @@
==========================================
Hudson CI server installation step by step
==========================================
Why Hudson
==========
One of the advantages of `Hudson <hudson-ci.org/>`_ over
`Buildbot <http://buildbot.net/>`_, for instance, is that
almost everything is done via its web interface. So anyone can
manage the continuous integration server easily.
Another advantage over the other alternatives is Hudson has many
`available plugins <http://wiki.hudson-ci.org/display/HUDSON/Plugins>`_,
so you don't need to write your own.
Hudson runs on Java, so the next step is to install Java and its dependencies.
Java and its dependencies
=========================
You can install all Java related packages this [not recommended] way::
$ [sudo] apt-get install ca-certificates-java daemon default-jre\
> default-jre-headless gcj-4.4-base gcj-4.4-jre-headless gcj-4.4-jre-lib\
> icedtea-6-jre-cacao java-common libaccess-bridge-java\
> libaccess-bridge-java-jni libgcj-common libgcj10 libjline-java \
> openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib\
> rhino tzdata-java tzdata
Or try installing with the information in the next section and
if you have problems, run::
$ [sudo] apt-get install -f
Installation
============
The recommended installation from `Hudson site for Debian users
<http://hudson-ci.org/debian/>`_ is installing through the `.deb` package.
The advantages are: you can automatically upgrade hudson via apt and
use the `service` or `/etc/init.d` resource to start the daemon on boot.
To install Hudson as they recommend, do the following:
* Add the key to your system::
$ wget -O /tmp/key http://hudson-ci.org/debian/hudson-ci.org.key
$ [sudo] apt-key add /tmp/key
* Then install Hudson::
$ wget -O /tmp/hudson.deb http://hudson-ci.org/latest/debian/hudson.deb
$ [sudo] dpkg --install /tmp/hudson.deb
When you reboot the computer the web daemon will be started at
http://localhost:8080. If you don't want to reboot the computer, run::
$ [sudo] service hudson start
or
$ [sudo] /etc/init.d/hudson start
Apache
======
It is not necessary for all users, but if you want to set up apache to run
the web interface, you should follow this tutorial:
http://wiki.hudson-ci.org/display/HUDSON/Running+Hudson+behind+Apache
Plugins
=======
Installing plugins in Hudson is very easy.
Just click *Manage Hudson*, then *Manage Plugins*.
The tab *Updates* shows all available updates to installed plugins.
But what we need now is to install plugins. So we must go to the
*Available* tab and check what we want to be installed and then press the
*Install* button in the end of the page.
The Hudson server hosted at http://ci.cloudsilverlining.org has the following
plugins installed for pip project:
* Hudson IRC Plugin
* Green Balls
* Hudson Continuous Integration game
* Hudson instant-messaging plugin
* Hudson Jabber notifier plugin
* Hudson Email Extension Plugin
* Hudson Mercurial plugin
Creating a Job
==============
Before Creating a Job for pip
-----------------------------
Hudson manages "jobs". Jobs are complete builds to Hudson. For instance,
you want to build pip project and run its tests with nosetests.
This section assumes you have all needed `dependencies installed`_.
You need to set up some configuration in Hudson before creating your first job.
Go to Hudson home page, "Manage Hudson", then "Configure System".
In the Mercurial section, fill the "Add Mercurial" section with:
* Name: `hg`
* Installation directory: `/usr`
* Executable: `INSTALLATION/bin/hg`
In the Shell section fill the shell executable with `/bin/bash`.
Then press the "Save" button in the bottom of the page.
Configuring a Job Step by Step
------------------------------
* Go to the home of the Hudson web interface
* Click *New Job*
* Pick a name for the job - pip, for instance
* Mark the option "Build a free-style software project"
* Press "OK" button
Now you were redirected to the job's configuration page. Here you will
tell Hudson how it will build your job. The most important
steps are listed (assume Mercurial plugin is installed):
* Check "Mercurial" in Source Control Management section
* Fill in the repository URL with **https://github.com/pypa/pip**
* Mark "Build periodically" in *Build Triggers* section
* Add "0 0 \* \* \*" (without quotes) to tell hudson you want to
run your build everyday at midnight
* Click "Add Build Step" in the *Build* section and pick "Execute Shell"
This box will contain all code you want your build run. To run pip's tests
we need to install pip tests's depencies and run nosetests.
Add the following lines to the box (it assumes you have virtualenv
in your system's python)::
python -mvirtualenv --no-site-packages pip_virtualenv
source pip_virtualenv/bin/activate
cd $WORKSPACE/..
easy_install -U pip
cd $WORKSPACE
pip install virtualenv scripttest nose
nosetests tests -v
The *$WORKSPACE* environment variable is the current build workspace,
in the case above it is the clone repository path. The `cd` stuff is
a work around to a pip's bug.
The process execute above means:
* create a virtualenv called **pip_virtualenv** without shared site-packages
* activate the environment
* updates system's pip
* install pip tests's dependencies
* run nosetests in the current directory
Press the "Save" button and in the next page test if the build is correct
by clicking "Build now" button.
In the left sidebar will appear the run builds and the running (if exists).
Click the top build, then "Console Output". Now you can
watch what Hudson is doing to build your job and watch the results.
Notes
=====
If you change anything in your system environment, like updating
your environment configuration files, and realize Hudson
didn't catch your changes, try restarting it::
$ [sudo] service hudson stop
$ [sudo] service hudson start
If when you run the `start` command you get an error telling you the port
is being used, wait about 2 or 3 seconds and try the command again - it's the
time the port releasing may take.
What is covered here is the basic knowledge to start setting up and using
a Hudson server, the goal is not teaching all about Hudson or all about
how to set up every detail.
There is a running Hudson server aimed for pip project here:
http://ci.cloudsilverlining.org/view/pip
Creating a Windows Slave to Run Jobs
====================================
After starting Hudson on Linux, start your Windows machine and access the
Hudson web interface.
Adding a Windows Node to Hudson CI Server
-----------------------------------------
Click "Manage Hudson", "Manage Nodes", "New Node". The **Node name** value
must be the Windows machine domain name - mywindowsslave.myhost.com, for
instance.
The "Launch method" should be **Launch slave agents via JNLP**
.. image:: _static/launch-jnlp-slave.JPG
:width: 500px
:target: _static/launch-jnlp-slave.JPG
Then press the **Add** button, and in the next page click
the **Launch** icon.
.. image:: _static/slave-launch-icon.png
:width: 500px
:target: _static/launch-jnlp-slave.JPG
Now you are able to create jobs tied to this Windows machine.
Creating Tied Jobs
------------------
The process of creating a job is almost the same as the list in the
`Creating a Job`_ section, the only difference is that you need
to mark the **Tie this project to a node** option and select what
node you want to run that build.
There is a difference in build commands, relying on variables. On Linux
they all start with `$`, like `$WORKSPACE`.
In Windows they will be enclosed by `%`, like `%WORKSPACE%`. And everything
you were doing depending on Bash, you will need to change to DOS
prompt commands and batch files.
.. _dependencies installed: running-tests.html#system-requirements
.. _creating a job: #creating-a-job
-195
View File
@@ -1,195 +0,0 @@
# -*- coding: utf-8 -*-
#
# pip documentation build configuration file, created by
# sphinx-quickstart on Tue Apr 22 22:08:49 2008
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
#sys.path.append(os.path.join(os.path.dirname(__file__), '../'))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
#extensions = ['sphinx.ext.autodoc']
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.txt'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'pip'
copyright = '2008-2011, The pip developers'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
release = "1.1"
version = '.'.join(release.split('.')[:2])
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'nature'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ['_theme']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = '_static/piplogo.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = 'favicon.png'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
html_use_modindex = False
# If false, no index is generated.
html_use_index = False
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'pipdocs'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'pip.tex', u'pip Documentation',
u'The pip developers', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
-141
View File
@@ -1,141 +0,0 @@
Configuration
=============
pip allows you to set its default options by using the following facilities,
in the order of each item's importance:
1. Command line options
2. `Environment variables`_
3. `Config files`_
1. Command specific section, e.g. ``[install]``
2. Global section ``[global]``
That means it will check each of those configuration sources and set the
defaults appropriately.
Examples
--------
- ``--host=foo`` overrides ``PIP_HOST=foo``
- ``PIP_HOST=foo`` overrides a config file with ``[global] host = foo``
- A command specific section in the config file ``[<command>] host = bar``
overrides the option with same name in the ``[global]`` config file section
- Environment variables override config files
Config files
------------
pip allows you to set all command line option defaults in a standard ini
style config file.
The names of the settings are derived from the long command line option, e.g.
if you want to use a different package index (``--index-url``) and set the
HTTP timeout (``--default-timeout``) to 60 seconds your config file would
look like this:
.. code-block:: ini
[global]
timeout = 60
index-url = http://download.zope.org/ppix
Each subcommand can be configured optionally in its own section so that every
global setting with the same name will be overridden; e.g. decreasing the
``timeout`` to ``10`` seconds when running the `freeze`
(`Freezing Requirements <./#freezing-requirements>`_) command and using
``60`` seconds for all other commands is possible with:
.. code-block:: ini
[global]
timeout = 60
[freeze]
timeout = 10
Boolean options like ``--ignore-installed`` or ``--no-dependencies`` can be
set like this:
.. code-block:: ini
[install]
ignore-installed = true
no-dependencies = yes
Appending options like ``--find-links`` can be written on multiple lines:
.. code-block:: ini
[global]
find-links =
http://download.example.com
[install]
find-links =
http://mirror1.example.com
http://mirror2.example.com
Location
********
The names and locations of the configuration files vary slightly across
platforms.
On Unix and Mac OS X the configuration file is: :file:`$HOME/.pip/pip.conf`
And on Windows, the configuration file is: :file:`%HOME%\\pip\\pip.ini`
Environment variables
-----------------------
Just like with `config files`_, each of pip's command line options
(long version, e.g. ``--find-links``) are automatically set by looking for
environment variables with the name format ``PIP_<UPPER_NAME>``. That means
the name of the command line options are capitalized and have dashes (``-``)
replaced with underscores (``_``).
For example, to redefine the default timeout you can also set an
environment variable::
export PIP_DEFAULT_TIMEOUT=60
pip install ipython
Which is the same as passing the option to pip directly::
pip --default-timeout=60 install ipython
This also works for appending command line options, like ``--find-links``.
Just leave an empty space between the passsed values, e.g.::
export PIP_FIND_LINKS="http://mirror1.example.com http://mirror2.example.com"
is the same as calling::
pip install --find-links=http://mirror1.example.com --find-links=http://mirror2.example.com
Configuration options
---------------------
Mirror support
**************
The `PyPI mirroring infrastructure <http://pypi.python.org/mirrors>`_ as
described in `PEP 381 <http://www.python.org/dev/peps/pep-0381/>`_ can be
used by passing the ``--use-mirrors`` option to the install command.
Alternatively, you can use the other ways to configure pip, e.g.::
$ export PIP_USE_MIRRORS=true
If enabled, pip will automatically query the DNS entry of the mirror index URL
to find the list of mirrors to use. In case you want to override this list,
please use the ``--mirrors`` option of the install command, or add to your pip
configuration file::
[install]
use-mirrors = true
mirrors =
http://d.pypi.python.org
http://b.pypi.python.org
-167
View File
@@ -1,167 +0,0 @@
=================
How to contribute
=================
All kinds of contributions are welcome - code, tests, documentation,
bug reports, ideas, etc.
Release Schedule
================
Minor releases of pip (e.g. 1.1, 1.2, 1.3...) occur every four months
(beginning with the release of pip 1.0 on April 4, 2011). Two weeks before a
scheduled release, a new branch ``release/X.Y`` is created for release testing
and preparation. This branch is only open to bugfixes.
.. _contributing-with-code:
Contributing with Code
======================
Forking through Github
----------------------
First of all, you need to fork the the official repository, which is
https://github.com/pypa/pip.
Log in to Github, go to the `pip repository page
<https://github.com/pypa/pip>`_, follow the **fork** link, wait for Github
to copy the repository and then clone your fork, like::
$ git clone https://github.com/YOU_USER_NAME/pip
Now you can change whatever you want, commit, push to your fork and when your
contribution is done, follow the **pull request** link and send us a request
explaining what you did and why.
Branches
--------
Pip uses the `git-flow`_ branching model. The default branch on GitHub is
``develop``, and all development work (new features and bugfixes) should happen
in that branch. The ``master`` branch is stable, and reflects the last released
state.
.. _git-flow: http://nvie.com/posts/a-successful-git-branching-model/
All tests should pass
---------------------
Almost all changes to pip should be accompanied by automated tests -
especially ones adding new behavior.
`Nose`_ is used to find and run all tests. Take a look at :doc:`running-tests`
to see what you need and how you should run the tests.
Before sending us a pull request, please, be sure all tests pass.
Supported Python versions
-------------------------
Pip supports Python versions 2.4, 2.5, 2.6, 2.7, 3.1, and 3.2, from a single
codebase (without use of 2to3 translation). Untested contributions frequently
break Python 2.4 or 3.x compatibility. Please run the tests on at least 2.4 and
3.2 and report your results when sending a pull request.
Continuous Integration server
-----------------------------
We have a continuous integration server running all pip related tests at
http://ci.cloudsilverlining.org/view/pip. But if you want to have your own,
you can learn how to set up a Hudson CI server like that in the
:doc:`ci-server-step-by-step` page.
Running the Tests
=================
Pip uses some system tools - VCS related tools - in its tests, so you need to
intall them (Linux)::
sudo apt-get install subversion bzr git-core mercurial
Or downloading and installing `Subversion
<http://subversion.apache.org/packages.html>`_, `Bazaar
<http://wiki.bazaar.canonical.com/Download>`_, `Git
<http://git-scm.com/download>`_ and `Mercurial
<http://mercurial.selenic.com/downloads/>`_ manually.
After all requirements (system and python) are installed,
just run the following command::
$ python setup.py test
Running tests directly with Nose
--------------------------------
If you want to run only a selection of the tests, you'll need to run them
directly with nose instead. Create a virtualenv, and install required
packages::
pip install nose virtualenv scripttest mock
Run nosetests::
nosetests
Or select just a single test to run::
cd tests; nosetests test_upgrade.py:test_uninstall_rollback
Troubleshooting
---------------
Locale Warnings
There was a problem with locales configuration when running tests in a Hudson
CI Server that broke some tests. The problem was not with pip, but with
`locales` configuration. Hudson was not setting LANG environment variable
correctly, so the solution to fix it was changing default language to
en_US.UTF-8.
The following has been done in a Ubuntu Server 9.10 machine::
$ sudo locale-gen en_US en_US.UTF-8
$ sudo dpkg-reconfigure locales
$ sudo update-locale LANG=en_US.UTF-8
Contributing with Tests
=======================
Pip's test coverage is not as good as we would like, so contributions of
additional tests are welcome. You can contribute these the same way you would
contribute any other kind of code: see the :ref:`contributing-with-code`
section.
Contributing with Bug Reports
=============================
Pip project is hosted at `Github`_ and uses its issue tracker system.
If you have found a bug and want to report it, go to `pip issue tracker page`_,
click **Create new**, add a descriptive
title (so we can easily identify what the bug is) and fill the description box
explaining how you got the bug, what pip version you were using and what is
your operating system, so we can reproduce the bug to try fixing it.
Contributing with Ideas
=======================
We are always open to new ideas, and we will enjoy yours. You can send
enhancement ideas and proposals via `pip issue tracker page`_,
`virtualenv mailing list`_, or #pip channel at freenode.
.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.3/
.. _Github: http://github.com/
.. _pip issue tracker page: https://github.com/pypa/pip/issues
.. _virtualenv mailing list: http://groups.google.com/group/python-virtualenv/
-12
View File
@@ -1,12 +0,0 @@
========
Glossary
========
.. glossary::
PyPI
The `Python Package Index`_, formerly known as the Cheese Shop,
is a central catalog of Python packages. By default, when
installing packages,`pip` searches for them in PyPI.
.. _`Python Package Index`: http://pypi.python.org/pypi
-54
View File
@@ -1,54 +0,0 @@
pip
===
`pip` is a tool for installing and managing Python packages, such as
those found in the `Python Package Index`_. It's a replacement for
easy_install_.
::
$ pip install simplejson
[... progress report ...]
Successfully installed simplejson
.. _`Python Package Index`: http://pypi.python.org/pypi
.. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall
Upgrading a package::
$ pip install --upgrade simplejson
[... progress report ...]
Successfully installed simplejson
Removing a package::
$ pip uninstall simplejson
Uninstalling simplejson:
/home/me/env/lib/python2.7/site-packages/simplejson
/home/me/env/lib/python2.7/site-packages/simplejson-2.2.1-py2.7.egg-info
Proceed (y/n)? y
Successfully uninstalled simplejson
.. comment: split here
.. toctree::
:maxdepth: 2
installing
usage
requirements
configuration
other-tools
contributing
news
glossary
.. comment: split here
Community
---------
The homepage for pip is at `pip-installer.org <http://www.pip-installer.org/>`_.
Bugs can be filed in the `pip issue tracker
<https://github.com/pypa/pip/issues/>`_. Discussion happens on the
`virtualenv email group
<http://groups.google.com/group/python-virtualenv?hl=en>`_.
-66
View File
@@ -1,66 +0,0 @@
Installation instructions
=========================
The recommended way to use pip is within `virtualenv
<http://www.virtualenv.org>`_, since every virtualenv has pip installed in it
automatically. This does not require root access or modify your system Python
installation. For instance::
$ curl -O https://raw.github.com/pypa/virtualenv/master/virtualenv.py
$ python virtualenv.py my_new_env
$ . my_new_env/bin/activate
(my_new_env)$ pip install ...
When used in this manner, pip will only affect the active virtual environment.
If you do want to install pip globally into your Python installation, see the
instructions below.
Prerequisites
-------------
Prior to installing pip make sure you have either `setuptools
<http://pypi.python.org/pypi/setuptools>`_ or `distribute
<http://pypi.python.org/pypi/distribute>`_ installed. Please consult your
operating system's package manager or install it manually::
$ curl http://python-distribute.org/distribute_setup.py | python
.. warning::
If you are using Python 3.X you **must** use distribute; setuptools doesn't
support Python 3.X.
Using the installer
-------------------
Download `get-pip.py <https://raw.github.com/pypa/pip/master/contrib/get-pip.py>`_
and execute it, using the Python interpreter of your choice::
$ curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
This may have to be run as root.
Alternative installation procedures
-----------------------------------
Using the source distribution
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can find the source on `PyPI <http://pypi.python.org/pypi/pip>`_::
$ curl -O http://pypi.python.org/packages/source/p/pip/pip-1.0.tar.gz
$ tar xvfz pip-1.0.tar.gz
$ cd pip-1.0
$ python setup.py install # may need to be root
Installing the development version
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
First you will need to clone the git repo::
$ git clone https://github.com/pypa/pip.git
Now we can install from the repo::
$ cd pip
$ python setup.py install # may need to be root
-170
View File
@@ -1,170 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-compressor.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-compressor.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end
-131
View File
@@ -1,131 +0,0 @@
=============================
Relationship with other tools
=============================
Pip Compared To easy_install
----------------------------
pip is meant to improve on easy_install. Some of the improvements:
* All packages are downloaded before installation. Partially-completed
installation doesn't occur as a result.
* Care is taken to present useful output on the console.
* The reasons for actions are kept track of. For instance, if a package is
being installed, pip keeps track of why that package was required.
* Error messages should be useful.
* The code is relatively concise and cohesive, making it easier to use
programmatically.
* Packages don't have to be installed as egg archives, they can be installed
flat (while keeping the egg metadata).
* Native support for other version control systems (Git, Mercurial and Bazaar)
* Uninstallation of packages.
* Simple to define fixed sets of requirements and reliably reproduce a
set of packages.
pip doesn't do everything that easy_install does. Specifically:
* It cannot install from eggs. It only installs from source. (In the
future it would be good if it could install binaries from Windows ``.exe``
or ``.msi`` -- binary install on other platforms is not a priority.)
* It doesn't understand Setuptools extras (like ``package[test]``). This should
be added eventually.
* It is incompatible with some packages that extensively customize distutils
or setuptools in their ``setup.py`` files.
pip is complementary with `virtualenv
<http://pypi.python.org/pypi/virtualenv>`__, and it is encouraged that you use
virtualenv to isolate your installation.
Using pip with virtualenv
-------------------------
pip is most nutritious when used with `virtualenv
<http://pypi.python.org/pypi/virtualenv>`__. One of the reasons pip
doesn't install "multi-version" eggs is that virtualenv removes much of the need
for it. Because pip is installed by virtualenv, just use
``path/to/my/environment/bin/pip`` to install things into that
specific environment.
To tell pip to only run if there is a virtualenv currently activated,
and to bail if not, use::
export PIP_REQUIRE_VIRTUALENV=true
Using pip with virtualenvwrapper
---------------------------------
If you are using `virtualenvwrapper
<http://www.doughellmann.com/projects/virtualenvwrapper/>`_, you might
want pip to automatically create its virtualenvs in your
``$WORKON_HOME``.
You can tell pip to do so by defining ``PIP_VIRTUALENV_BASE`` in your
environment and setting it to the same value as that of
``$WORKON_HOME``.
Do so by adding the line::
export PIP_VIRTUALENV_BASE=$WORKON_HOME
in your .bashrc under the line starting with ``export WORKON_HOME``.
Using pip with buildout
-----------------------
If you are using `zc.buildout
<http://pypi.python.org/pypi/zc.buildout>`_ you should look at
`gp.recipe.pip <http://pypi.python.org/pypi/gp.recipe.pip>`_ as an
option to use pip and virtualenv in your buildouts.
Using pip with the "user scheme"
--------------------------------
With Python 2.6 came the `"user scheme" for installation
<http://docs.python.org/install/index.html#alternate-installation-the-user-scheme>`_, which means that all
Python distributions support an alternative install location that is specific to a user.
The default location for each OS is explained in the python documentation
for the `site.USER_BASE <http://docs.python.org/library/site.html#site.USER_BASE>`_ variable.
This mode of installation can be turned on by
specifying the ``--user`` option to ``pip install``.
Moreover, the "user scheme" can be customized by setting the
``PYTHONUSERBASE`` environment variable, which updates the value of ``site.USER_BASE``.
To install "somepackage" into an environment with site.USER_BASE customized to '/myappenv', do the following::
export PYTHONUSERBASE=/myappenv
pip install --user somepackage
Command line completion
-----------------------
pip comes with support for command line completion in bash and zsh and
allows you tab complete commands and options. To enable it you simply
need copy the required shell script to the your shell startup file
(e.g. ``.profile`` or ``.zprofile``) by running the special ``completion``
command, e.g. for bash::
$ pip completion --bash >> ~/.profile
And for zsh::
$ pip completion --zsh >> ~/.zprofile
Alternatively, you can use the result of the ``completion`` command
directly with the eval function of you shell, e.g. by adding::
eval "`pip completion --bash`"
to your startup file.
-246
View File
@@ -1,246 +0,0 @@
.. _`requirements-files`:
==================
Requirements files
==================
When installing software, and Python packages in particular, it's common that
you get a lot of libraries installed. You just did ``easy_install MyPackage``
and you get a dozen packages. Each of these packages has its own version.
Maybe you ran that installation and it works. Great! Will it keep working?
Did you have to provide special options to get it to find everything? Did you
have to install a bunch of other optional pieces? Most of all, will you be able
to do it again? Requirements files give you a way to create an *environment*:
a *set* of packages that work together.
If you've ever tried to setup an application on a new system, or with slightly
updated pieces, and had it fail, pip requirements are for you. If you
haven't had this problem then you will eventually, so pip requirements are
for you too -- requirements make explicit, repeatable installation of packages.
So what are requirements files? They are very simple: lists of packages to
install. Instead of running something like ``pip install MyApp`` and
getting whatever libraries come along, you can create a requirements file
something like::
MyApp
Framework==0.9.4
Library>=0.2
If you save this in ``requirements.txt``, then you can ``pip install -r
requirements.txt``. Regardless of what MyApp lists in ``setup.py``, you'll
get a specific version of Framework (0.9.4) and at least the 0.2 version of
Library. (You might think you could list these specific versions in MyApp's
``setup.py`` -- but if you do that you'll have to edit MyApp if you want to
try a new version of Framework, or release a new version of MyApp if you
determine that Library 0.3 doesn't work with your application.) You can also
add optional libraries and support tools that MyApp doesn't strictly
require, giving people a set of recommended libraries.
You can also include "editable" packages -- packages that are checked out from
Subversion, Git, Mercurial and Bazaar. These are just like using the ``-e``
option to pip. They look like::
-e svn+http://myrepo/svn/MyApp#egg=MyApp
You have to start the URL with ``svn+`` (``git+``, ``hg+`` or ``bzr+``), and
you have to include ``#egg=Package`` so pip knows what to expect at that URL.
You can also include ``@rev`` in the URL, e.g., ``@275`` to check out
revision 275.
Requirement files are mostly *flat*. Maybe ``MyApp`` requires
``Framework``, and ``Framework`` requires ``Library``. I encourage
you to still list all these in a single requirement file; it is the
nature of Python programs that there are implicit bindings *directly*
between MyApp and Library. For instance, Framework might expose one
of Library's objects, and so if Library is updated it might directly
break MyApp. If that happens you can update the requirements file to
force an earlier version of Library, and you can do that without
having to re-release MyApp at all.
Read the `requirements file format`_ to learn about other features.
Freezing Requirements
=====================
So you have a working set of packages, and you want to be able to install them
elsewhere. `Requirements files`_ let you install exact versions, but it won't
tell you what all the exact versions are.
To create a new requirements file from a known working environment, use::
$ pip freeze > stable-req.txt
This will write a listing of *all* installed libraries to ``stable-req.txt``
with exact versions for every library. You may want to edit the file down after
generating (e.g., to eliminate unnecessary libraries), but it'll give you a
stable starting point for constructing your requirements file.
You can also give it an existing requirements file, and it will use that as a
sort of template for the new file. So if you do::
$ pip freeze -r devel-req.txt > stable-req.txt
it will keep the packages listed in ``devel-req.txt`` in order and preserve
comments.
The _`requirements file format`
===============================
The requirements file is a way to get pip to install specific packages
to make up an *environment*. This document describes that format. To
read about *when* you should use requirement files, see `Requirements
Files <./#requirements-files>`_.
Each line of the requirements file indicates something to be
installed. For example::
MyPackage==3.0
tells pip to install the 3.0 version of MyPackage.
You can also request `extras`_ in the requirements file::
MyPackage==3.0 [PDF]
.. _extras: http://peak.telecommunity.com/DevCenter/setuptools#declaring-extras-optional-features-with-their-own-dependencies
Packages may also be installed in an "editable" form. This puts the
source code into ``src/distname`` (making the name lower case) and
runs ``python setup.py develop`` on the package. To indicate
editable, use ``-e``, like::
-e svn+http://svn.myproject.org/svn/MyProject/trunk#egg=MyProject
The ``#egg=MyProject`` part is important, because while you can
install simply given the svn location, the project name is useful in
other places.
You can also specify the egg name for a non-editable url. This is useful to
point to HEAD locations on the local filesystem:
file:///path/to/your/lib/project#egg=MyProject
or relative paths:
file:../../lib/project#egg=MyProject
If you need to give pip (and by association easy_install) hints
about where to find a package, you can use the ``-f``
(``--find-links``) option, like::
$ pip -f http://someserver.org/index-of-packages MyPackage==3.0
Pip will then look for a link at http://someserver.org/index-of-packages
that matches version ``3.0`` of ``MyPackage`` -- the link should be
like ``MyPackage-3.0.tar.gz``.
And if you want to install from a tarball or zip file with a direct link,
you don't need ``-f`` option, you just need to pass the absolute url, like::
$ pip install http://someserver.org/packages/MyPackage-3.0.tar.gz
Version Control
---------------
Right now pip knows of the following major version control systems:
Subversion
~~~~~~~~~~
Pip supports the URL schemes ``svn``, ``svn+svn``, ``svn+http``, ``svn+https``, ``svn+ssh``.
You can also give specific revisions to an SVN URL, like::
-e svn+svn://svn.myproject.org/svn/MyProject#egg=MyProject
-e svn+http://svn.myproject.org/svn/MyProject/trunk@2019#egg=MyProject
which will check out revision 2019. ``@{20080101}`` would also check
out the revision from 2008-01-01. You can only check out specific
revisions using ``-e svn+...``.
Git
~~~
Pip currently supports cloning over ``git``, ``git+http`` and ``git+ssh``::
-e git://git.myproject.org/MyProject.git#egg=MyProject
-e git+http://git.myproject.org/MyProject/#egg=MyProject
-e git+ssh://git@myproject.org/MyProject/#egg=MyProject
Passing branch names, a commit hash or a tag name is also possible::
-e git://git.myproject.org/MyProject.git@master#egg=MyProject
-e git://git.myproject.org/MyProject.git@v1.0#egg=MyProject
-e git://git.myproject.org/MyProject.git@da39a3ee5e6b4b0d3255bfef95601890afd80709#egg=MyProject
Mercurial
~~~~~~~~~
The supported schemes are: ``hg+http``, ``hg+https``,
``hg+static-http`` and ``hg+ssh``::
-e hg+http://hg.myproject.org/MyProject/#egg=MyProject
-e hg+https://hg.myproject.org/MyProject/#egg=MyProject
-e hg+ssh://hg@myproject.org/MyProject/#egg=MyProject
You can also specify a revision number, a revision hash, a tag name or a local
branch name::
-e hg+http://hg.myproject.org/MyProject/@da39a3ee5e6b#egg=MyProject
-e hg+http://hg.myproject.org/MyProject/@2019#egg=MyProject
-e hg+http://hg.myproject.org/MyProject/@v1.0#egg=MyProject
-e hg+http://hg.myproject.org/MyProject/@special_feature#egg=MyProject
Bazaar
~~~~~~
Pip supports Bazaar using the ``bzr+http``, ``bzr+https``, ``bzr+ssh``,
``bzr+sftp``, ``bzr+ftp`` and ``bzr+lp`` schemes::
-e bzr+http://bzr.myproject.org/MyProject/trunk/#egg=MyProject
-e bzr+sftp://user@myproject.org/MyProject/trunk/#egg=MyProject
-e bzr+ssh://user@myproject.org/MyProject/trunk/#egg=MyProject
-e bzr+ftp://user@myproject.org/MyProject/trunk/#egg=MyProject
-e bzr+lp:MyProject#egg=MyProject
Tags or revisions can be installed like this::
-e bzr+https://bzr.myproject.org/MyProject/trunk/@2019#egg=MyProject
-e bzr+http://bzr.myproject.org/MyProject/trunk/@v1.0#egg=MyProject
Recursive Requirements
----------------------
If you wish, you can also refer to other requirements files, like::
-r Pylons-requirements.txt
This gives you a way of abstracting out sets of requirements. This
isn't, however, very friendly with `frozen requirements
<./#freezing-requirements>`_, as everything in
``Pylons-requirements.txt`` will show up in your frozen file.
Indexes, find-links
-------------------
You can also provide values for the ``--index-url`` and ``--find-links``
options in your requirement files, like::
--index-url http://example.com/private-pypi/
Note that using ``--index-url`` removes the use of `PyPI
<http://pypi.python.org>`_, while using ``--extra-index-url`` will add
additional indexes.
``--find-links`` is more ad-hoc; instead of a complete "index", you
only need an HTML page of links to available packages. Simply by
putting all your private packages in a directory and using the Apache
auto-index, you can publish your packages so pip can find them.
``--find-links`` is always additive; pip looks at everything it can
find. Use it like::
--find-links http://example.com/private-packages/
Note that all these options must be on a line of their own.
-160
View File
@@ -1,160 +0,0 @@
=====
Usage
=====
Install packages
----------------
The simplest way to install a package is by specifying its name::
$ pip install SomePackage
`SomePackage` is downloaded from :term:`PyPI`, along with its
dependencies, and installed.
If `SomePackage` is already installed, and you need a newer version, use ``pip
install --upgrade SomePackage``. You can also request a specific version (``pip
install SomePackage==1.0.4``) and specify `setuptools extras`_ (``pip install
SomePackage[PDF]``).
You can also install from a particular source distribution file, either
local or remote::
$ pip install ./downloads/SomePackage-1.0.4.tar.gz
$ pip install http://my.package.repo/SomePackage-1.0.4.zip
.. _setuptools extras: http://peak.telecommunity.com/DevCenter/setuptools#declaring-extras-optional-features-with-their-own-dependencies
Edit mode
*********
Packages normally_ install under ``site-packages``, but when you're
making changes, it makes more sense to run the package straight from the
checked-out source tree. "Editable" installs create a ``.pth`` file in
``site-packages`` that extends Python's import path to find the
package::
$ pip install -e path/to/SomePackage
.. _normally: http://docs.python.org/install/index.html#how-installation-works
Version control systems
***********************
Pip knows how to check out a package from version control. `Subversion`,
`Git`, `Mercurial` and `Bazaar` are supported. The repository will be
checked out in a temporary folder, installed, and cleaned up::
$ pip install git+https://github.com/simplejson/simplejson.git
$ pip install svn+svn://svn.zope.org/repos/main/zope.interface/trunk/
This can be combined with the `-e` flag, and Pip will perform the
checkout in ``./src/``. You need to supply a name for the checkout
folder by appending a hash to the repository URL::
$ pip install -e git+https://github.com/lakshmivyas/hyde.git#egg=hyde
Note that only basic checking-out of a repo is supported; pip will not
handle advanced VCS-specific features such as submodules or subrepos.
Alternate package repositories
******************************
pip searches in :term:`PyPI` by default, but this can be overridden using the
``--index-url`` option::
$ pip install --index-url http://d.pypi.python.org/simple/ SomePackage
If you have your own package index with a few additional packages, you may want
to to specify additional index URLs while still also using :term:`PyPI`::
$ pip install --extra-index-url http://my.package.repo/ SomePackage
A "package index" used with ``--index-url`` or ``--extra-index-url`` can be as
simple as a static-web-served directory, with automatic indexes on, with a
subdirectory per package and sdists (tarballs created with ``python setup.py
sdist``) in that directory::
mypackage/
mypackage-0.7.8.tar.gz
mypackage-1.0.1.tar.gz
otherpackage/
otherpackage-2.3.5.tar.gz
If the number of packages in the index is small, it's even simpler to skip the
subdirectories: put all of the sdists in a single directory and use pip's
``--find-links`` option with a URL to that directory::
mypackage-0.7.8.tar.gz
mypackage-1.0.1.tar.gz
otherpackage-2.3.5.tar.gz
``--find-links`` also supports local paths, so installation need not require a
network connection.
Like ``--extra-index-url``, ``--find-links`` is additive by default, it does
not replace or supersede the index. All package sources are checked, and the
latest qualifying version for every requested package is used. If you want only
your ``-find-links`` URL used as package source, you need to pair it with
``--no-index``.
``--index-url``, ``--extra-index-url`` and ``--find-links`` can all be used
within a :ref:`requirements file <requirements-files>` in addition to on the
command line directly.
Uninstall packages
------------------
pip is able to uninstall most installed packages with ``pip uninstall
package-name``.
Known exceptions include pure-distutils packages installed with
``python setup.py install`` (such packages leave behind no metadata allowing
determination of what files were installed), and script wrappers installed
by develop-installs (``python setup.py develop``).
pip also performs an automatic uninstall of an old version of a package
before upgrading to a newer version, so outdated files (and egg-info data)
from conflicting versions aren't left hanging around to cause trouble. The
old version of the package is automatically restored if the new version
fails to download or install.
Searching for packages
----------------------
pip can search :term:`PyPI` for packages using the ``pip search``
command::
$ pip search "query"
The query will be used to search the names and summaries of all
packages. With the ``--index`` option you can search in a different
repository.
Bundles
-------
Another way to distribute a set of libraries is a bundle format (specific to
pip). This format is not stable at this time (there simply hasn't been
any feedback, nor a great deal of thought). A bundle file contains all the
source for your package, and you can have pip install them all together.
Once you have the bundle file further network access won't be necessary. To
build a bundle file, do::
$ pip bundle MyApp.pybundle MyApp
(Using a :ref:`requirements file <requirements-files>` would be wise.) Then
someone else can get the file ``MyApp.pybundle`` and run::
$ pip install MyApp.pybundle
This is *not* a binary format. This only packages source. If you have binary
packages, then the person who installs the files will have to have a compiler,
any necessary headers installed, etc. Binary packages are hard, this is
relatively easy.
-592
View File
@@ -1,592 +0,0 @@
"""Utilities to support packages."""
# NOTE: This module must remain compatible with Python 2.3, as it is shared
# by setuptools for distribution with Python 2.3 and up.
import os
import sys
import imp
import os.path
from types import ModuleType
__all__ = [
'get_importer', 'iter_importers', 'get_loader', 'find_loader',
'walk_packages', 'iter_modules',
'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
]
def read_code(stream):
# This helper is needed in order for the PEP 302 emulation to
# correctly handle compiled files
import marshal
magic = stream.read(4)
if magic != imp.get_magic():
return None
stream.read(4) # Skip timestamp
return marshal.load(stream)
def simplegeneric(func):
"""Make a trivial single-dispatch generic function"""
registry = {}
def wrapper(*args, **kw):
ob = args[0]
try:
cls = ob.__class__
except AttributeError:
cls = type(ob)
try:
mro = cls.__mro__
except AttributeError:
try:
class cls(cls, object):
pass
mro = cls.__mro__[1:]
except TypeError:
mro = object, # must be an ExtensionClass or some such :(
for t in mro:
if t in registry:
return registry[t](*args, **kw)
else:
return func(*args, **kw)
try:
wrapper.__name__ = func.__name__
except (TypeError, AttributeError):
pass # Python 2.3 doesn't allow functions to be renamed
def register(typ, func=None):
if func is None:
return lambda f: register(typ, f)
registry[typ] = func
return func
wrapper.__dict__ = func.__dict__
wrapper.__doc__ = func.__doc__
wrapper.register = register
return wrapper
def walk_packages(path=None, prefix='', onerror=None):
"""Yields (module_loader, name, ispkg) for all modules recursively
on path, or, if path is None, all accessible modules.
'path' should be either None or a list of paths to look for
modules in.
'prefix' is a string to output on the front of every module name
on output.
Note that this function must import all *packages* (NOT all
modules!) on the given path, in order to access the __path__
attribute to find submodules.
'onerror' is a function which gets called with one argument (the
name of the package which was being imported) if any exception
occurs while trying to import a package. If no onerror function is
supplied, ImportErrors are caught and ignored, while all other
exceptions are propagated, terminating the search.
Examples:
# list all modules python can access
walk_packages()
# list all submodules of ctypes
walk_packages(ctypes.__path__, ctypes.__name__+'.')
"""
def seen(p, m={}):
if p in m:
return True
m[p] = True
for importer, name, ispkg in iter_modules(path, prefix):
yield importer, name, ispkg
if ispkg:
try:
__import__(name)
except ImportError:
if onerror is not None:
onerror(name)
except Exception:
if onerror is not None:
onerror(name)
else:
raise
else:
path = getattr(sys.modules[name], '__path__', None) or []
# don't traverse path items we've seen before
path = [p for p in path if not seen(p)]
for item in walk_packages(path, name+'.', onerror):
yield item
def iter_modules(path=None, prefix=''):
"""Yields (module_loader, name, ispkg) for all submodules on path,
or, if path is None, all top-level modules on sys.path.
'path' should be either None or a list of paths to look for
modules in.
'prefix' is a string to output on the front of every module name
on output.
"""
if path is None:
importers = iter_importers()
else:
importers = map(get_importer, path)
yielded = {}
for i in importers:
for name, ispkg in iter_importer_modules(i, prefix):
if name not in yielded:
yielded[name] = 1
yield i, name, ispkg
#@simplegeneric
def iter_importer_modules(importer, prefix=''):
if not hasattr(importer, 'iter_modules'):
return []
return importer.iter_modules(prefix)
iter_importer_modules = simplegeneric(iter_importer_modules)
class ImpImporter:
"""PEP 302 Importer that wraps Python's "classic" import algorithm
ImpImporter(dirname) produces a PEP 302 importer that searches that
directory. ImpImporter(None) produces a PEP 302 importer that searches
the current sys.path, plus any modules that are frozen or built-in.
Note that ImpImporter does not currently support being used by placement
on sys.meta_path.
"""
def __init__(self, path=None):
self.path = path
def find_module(self, fullname, path=None):
# Note: we ignore 'path' argument since it is only used via meta_path
subname = fullname.split(".")[-1]
if subname != fullname and self.path is None:
return None
if self.path is None:
path = None
else:
path = [os.path.realpath(self.path)]
try:
file, filename, etc = imp.find_module(subname, path)
except ImportError:
return None
return ImpLoader(fullname, file, filename, etc)
def iter_modules(self, prefix=''):
if self.path is None or not os.path.isdir(self.path):
return
yielded = {}
import inspect
filenames = os.listdir(self.path)
filenames.sort() # handle packages before same-named modules
for fn in filenames:
modname = inspect.getmodulename(fn)
if modname=='__init__' or modname in yielded:
continue
path = os.path.join(self.path, fn)
ispkg = False
if not modname and os.path.isdir(path) and '.' not in fn:
modname = fn
for fn in os.listdir(path):
subname = inspect.getmodulename(fn)
if subname=='__init__':
ispkg = True
break
else:
continue # not a package
if modname and '.' not in modname:
yielded[modname] = 1
yield prefix + modname, ispkg
class ImpLoader:
"""PEP 302 Loader that wraps Python's "classic" import algorithm
"""
code = source = None
def __init__(self, fullname, file, filename, etc):
self.file = file
self.filename = filename
self.fullname = fullname
self.etc = etc
def load_module(self, fullname):
self._reopen()
try:
mod = imp.load_module(fullname, self.file, self.filename, self.etc)
finally:
if self.file:
self.file.close()
# Note: we don't set __loader__ because we want the module to look
# normal; i.e. this is just a wrapper for standard import machinery
return mod
def get_data(self, pathname):
return open(pathname, "rb").read()
def _reopen(self):
if self.file and self.file.closed:
mod_type = self.etc[2]
if mod_type==imp.PY_SOURCE:
self.file = open(self.filename, 'rU')
elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION):
self.file = open(self.filename, 'rb')
def _fix_name(self, fullname):
if fullname is None:
fullname = self.fullname
elif fullname != self.fullname:
raise ImportError("Loader for module %s cannot handle "
"module %s" % (self.fullname, fullname))
return fullname
def is_package(self, fullname):
fullname = self._fix_name(fullname)
return self.etc[2]==imp.PKG_DIRECTORY
def get_code(self, fullname=None):
fullname = self._fix_name(fullname)
if self.code is None:
mod_type = self.etc[2]
if mod_type==imp.PY_SOURCE:
source = self.get_source(fullname)
self.code = compile(source, self.filename, 'exec')
elif mod_type==imp.PY_COMPILED:
self._reopen()
try:
self.code = read_code(self.file)
finally:
self.file.close()
elif mod_type==imp.PKG_DIRECTORY:
self.code = self._get_delegate().get_code()
return self.code
def get_source(self, fullname=None):
fullname = self._fix_name(fullname)
if self.source is None:
mod_type = self.etc[2]
if mod_type==imp.PY_SOURCE:
self._reopen()
try:
self.source = self.file.read()
finally:
self.file.close()
elif mod_type==imp.PY_COMPILED:
if os.path.exists(self.filename[:-1]):
f = open(self.filename[:-1], 'rU')
self.source = f.read()
f.close()
elif mod_type==imp.PKG_DIRECTORY:
self.source = self._get_delegate().get_source()
return self.source
def _get_delegate(self):
return ImpImporter(self.filename).find_module('__init__')
def get_filename(self, fullname=None):
fullname = self._fix_name(fullname)
mod_type = self.etc[2]
if self.etc[2]==imp.PKG_DIRECTORY:
return self._get_delegate().get_filename()
elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION):
return self.filename
return None
try:
import zipimport
from zipimport import zipimporter
def iter_zipimport_modules(importer, prefix=''):
dirlist = list(zipimport._zip_directory_cache[importer.archive].keys())
dirlist.sort()
_prefix = importer.prefix
plen = len(_prefix)
yielded = {}
import inspect
for fn in dirlist:
if not fn.startswith(_prefix):
continue
fn = fn[plen:].split(os.sep)
if len(fn)==2 and fn[1].startswith('__init__.py'):
if fn[0] not in yielded:
yielded[fn[0]] = 1
yield fn[0], True
if len(fn)!=1:
continue
modname = inspect.getmodulename(fn[0])
if modname=='__init__':
continue
if modname and '.' not in modname and modname not in yielded:
yielded[modname] = 1
yield prefix + modname, False
iter_importer_modules.register(zipimporter, iter_zipimport_modules)
except ImportError:
pass
def get_importer(path_item):
"""Retrieve a PEP 302 importer for the given path item
The returned importer is cached in sys.path_importer_cache
if it was newly created by a path hook.
If there is no importer, a wrapper around the basic import
machinery is returned. This wrapper is never inserted into
the importer cache (None is inserted instead).
The cache (or part of it) can be cleared manually if a
rescan of sys.path_hooks is necessary.
"""
try:
importer = sys.path_importer_cache[path_item]
except KeyError:
for path_hook in sys.path_hooks:
try:
importer = path_hook(path_item)
break
except ImportError:
pass
else:
importer = None
sys.path_importer_cache.setdefault(path_item, importer)
if importer is None:
try:
importer = ImpImporter(path_item)
except ImportError:
importer = None
return importer
def iter_importers(fullname=""):
"""Yield PEP 302 importers for the given module name
If fullname contains a '.', the importers will be for the package
containing fullname, otherwise they will be importers for sys.meta_path,
sys.path, and Python's "classic" import machinery, in that order. If
the named module is in a package, that package is imported as a side
effect of invoking this function.
Non PEP 302 mechanisms (e.g. the Windows registry) used by the
standard import machinery to find files in alternative locations
are partially supported, but are searched AFTER sys.path. Normally,
these locations are searched BEFORE sys.path, preventing sys.path
entries from shadowing them.
For this to cause a visible difference in behaviour, there must
be a module or package name that is accessible via both sys.path
and one of the non PEP 302 file system mechanisms. In this case,
the emulation will find the former version, while the builtin
import mechanism will find the latter.
Items of the following types can be affected by this discrepancy:
imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY
"""
if fullname.startswith('.'):
raise ImportError("Relative module names not supported")
if '.' in fullname:
# Get the containing package's __path__
pkg = '.'.join(fullname.split('.')[:-1])
if pkg not in sys.modules:
__import__(pkg)
path = getattr(sys.modules[pkg], '__path__', None) or []
else:
for importer in sys.meta_path:
yield importer
path = sys.path
for item in path:
yield get_importer(item)
if '.' not in fullname:
yield ImpImporter()
def get_loader(module_or_name):
"""Get a PEP 302 "loader" object for module_or_name
If the module or package is accessible via the normal import
mechanism, a wrapper around the relevant part of that machinery
is returned. Returns None if the module cannot be found or imported.
If the named module is not already imported, its containing package
(if any) is imported, in order to establish the package __path__.
This function uses iter_importers(), and is thus subject to the same
limitations regarding platform-specific special import locations such
as the Windows registry.
"""
if module_or_name in sys.modules:
module_or_name = sys.modules[module_or_name]
if isinstance(module_or_name, ModuleType):
module = module_or_name
loader = getattr(module, '__loader__', None)
if loader is not None:
return loader
fullname = module.__name__
else:
fullname = module_or_name
return find_loader(fullname)
def find_loader(fullname):
"""Find a PEP 302 "loader" object for fullname
If fullname contains dots, path must be the containing package's __path__.
Returns None if the module cannot be found or imported. This function uses
iter_importers(), and is thus subject to the same limitations regarding
platform-specific special import locations such as the Windows registry.
"""
for importer in iter_importers(fullname):
loader = importer.find_module(fullname)
if loader is not None:
return loader
return None
def extend_path(path, name):
"""Extend a package's path.
Intended use is to place the following code in a package's __init__.py:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
This will add to the package's __path__ all subdirectories of
directories on sys.path named after the package. This is useful
if one wants to distribute different parts of a single logical
package as multiple directories.
It also looks for *.pkg files beginning where * matches the name
argument. This feature is similar to *.pth files (see site.py),
except that it doesn't special-case lines starting with 'import'.
A *.pkg file is trusted at face value: apart from checking for
duplicates, all entries found in a *.pkg file are added to the
path, regardless of whether they are exist the filesystem. (This
is a feature.)
If the input path is not a list (as is the case for frozen
packages) it is returned unchanged. The input path is not
modified; an extended copy is returned. Items are only appended
to the copy at the end.
It is assumed that sys.path is a sequence. Items of sys.path that
are not (unicode or 8-bit) strings referring to existing
directories are ignored. Unicode items of sys.path that cause
errors when used as filenames may cause this function to raise an
exception (in line with os.path.isdir() behavior).
"""
if not isinstance(path, list):
# This could happen e.g. when this is called from inside a
# frozen package. Return the path unchanged in that case.
return path
pname = os.path.join(*name.split('.')) # Reconstitute as relative path
# Just in case os.extsep != '.'
sname = os.extsep.join(name.split('.'))
sname_pkg = sname + os.extsep + "pkg"
init_py = "__init__" + os.extsep + "py"
path = path[:] # Start with a copy of the existing path
from pip.backwardcompat import string_types
for dir in sys.path:
if not isinstance(dir, string_types) or not os.path.isdir(dir):
continue
subdir = os.path.join(dir, pname)
# XXX This may still add duplicate entries to path on
# case-insensitive filesystems
initfile = os.path.join(subdir, init_py)
if subdir not in path and os.path.isfile(initfile):
path.append(subdir)
# XXX Is this the right thing for subpackages like zope.app?
# It looks for a file named "zope.app.pkg"
pkgfile = os.path.join(dir, sname_pkg)
if os.path.isfile(pkgfile):
try:
f = open(pkgfile)
except IOError:
msg = sys.exc_info()[1]
sys.stderr.write("Can't open %s: %s\n" %
(pkgfile, msg))
else:
for line in f:
line = line.rstrip('\n')
if not line or line.startswith('#'):
continue
path.append(line) # Don't check for existence!
f.close()
return path
def get_data(package, resource):
"""Get a resource from a package.
This is a wrapper round the PEP 302 loader get_data API. The package
argument should be the name of a package, in standard module format
(foo.bar). The resource argument should be in the form of a relative
filename, using '/' as the path separator. The parent directory name '..'
is not allowed, and nor is a rooted name (starting with a '/').
The function returns a binary string, which is the contents of the
specified resource.
For packages located in the filesystem, which have already been imported,
this is the rough equivalent of
d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()
If the package cannot be located or loaded, or it uses a PEP 302 loader
which does not support get_data(), then None is returned.
"""
loader = get_loader(package)
if loader is None or not hasattr(loader, 'get_data'):
return None
mod = sys.modules.get(package) or loader.load_module(package)
if mod is None or not hasattr(mod, '__file__'):
return None
# Modify the resource name to be compatible with the loader.get_data
# signature - an os.path format "filename" starting with the dirname of
# the package's __file__
parts = resource.split('/')
parts.insert(0, os.path.dirname(mod.__file__))
resource_name = os.path.join(*parts)
return loader.get_data(resource_name)
-193
View File
@@ -1,193 +0,0 @@
"""Base Command class, and related routines"""
import os
import socket
import sys
import traceback
import time
from pip import commands
from pip.log import logger
from pip.baseparser import parser, ConfigOptionParser, UpdatingDefaultsHelpFormatter
from pip.download import urlopen
from pip.exceptions import (BadCommand, InstallationError, UninstallationError,
CommandError)
from pip.backwardcompat import StringIO, walk_packages
from pip.status_codes import SUCCESS, ERROR, UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND
__all__ = ['command_dict', 'Command', 'load_all_commands',
'load_command', 'command_names']
command_dict = {}
# for backwards compatibiliy
get_proxy = urlopen.get_proxy
class Command(object):
name = None
usage = None
hidden = False
def __init__(self):
assert self.name
self.parser = ConfigOptionParser(
usage=self.usage,
prog='%s %s' % (sys.argv[0], self.name),
version=parser.version,
formatter=UpdatingDefaultsHelpFormatter(),
name=self.name)
for option in parser.option_list:
if not option.dest or option.dest == 'help':
# -h, --version, etc
continue
self.parser.add_option(option)
command_dict[self.name] = self
def merge_options(self, initial_options, options):
# Make sure we have all global options carried over
for attr in ['log', 'proxy', 'require_venv',
'log_explicit_levels', 'log_file',
'timeout', 'default_vcs',
'skip_requirements_regex',
'no_input', 'exists_action']:
setattr(options, attr, getattr(initial_options, attr) or getattr(options, attr))
options.quiet += initial_options.quiet
options.verbose += initial_options.verbose
def setup_logging(self):
pass
def main(self, args, initial_options):
options, args = self.parser.parse_args(args)
self.merge_options(initial_options, options)
level = 1 # Notify
level += options.verbose
level -= options.quiet
level = logger.level_for_integer(4-level)
complete_log = []
logger.consumers.extend(
[(level, sys.stdout),
(logger.DEBUG, complete_log.append)])
if options.log_explicit_levels:
logger.explicit_levels = True
self.setup_logging()
if options.no_input:
os.environ['PIP_NO_INPUT'] = '1'
if options.exists_action:
os.environ['PIP_EXISTS_ACTION'] = ''.join(options.exists_action)
if options.require_venv:
# If a venv is required check if it can really be found
if not os.environ.get('VIRTUAL_ENV'):
logger.fatal('Could not find an activated virtualenv (required).')
sys.exit(VIRTUALENV_NOT_FOUND)
if options.log:
log_fp = open_logfile(options.log, 'a')
logger.consumers.append((logger.DEBUG, log_fp))
else:
log_fp = None
socket.setdefaulttimeout(options.timeout or None)
urlopen.setup(proxystr=options.proxy, prompting=not options.no_input)
exit = SUCCESS
store_log = False
try:
status = self.run(options, args)
# FIXME: all commands should return an exit status
# and when it is done, isinstance is not needed anymore
if isinstance(status, int):
exit = status
except (InstallationError, UninstallationError):
e = sys.exc_info()[1]
logger.fatal(str(e))
logger.info('Exception information:\n%s' % format_exc())
store_log = True
exit = ERROR
except BadCommand:
e = sys.exc_info()[1]
logger.fatal(str(e))
logger.info('Exception information:\n%s' % format_exc())
store_log = True
exit = ERROR
except CommandError:
e = sys.exc_info()[1]
logger.fatal('ERROR: %s' % e)
logger.info('Exception information:\n%s' % format_exc())
exit = ERROR
except KeyboardInterrupt:
logger.fatal('Operation cancelled by user')
logger.info('Exception information:\n%s' % format_exc())
store_log = True
exit = ERROR
except:
logger.fatal('Exception:\n%s' % format_exc())
store_log = True
exit = UNKNOWN_ERROR
if log_fp is not None:
log_fp.close()
if store_log:
log_fn = options.log_file
text = '\n'.join(complete_log)
logger.fatal('Storing complete log in %s' % log_fn)
log_fp = open_logfile(log_fn, 'w')
log_fp.write(text)
log_fp.close()
return exit
def format_exc(exc_info=None):
if exc_info is None:
exc_info = sys.exc_info()
out = StringIO()
traceback.print_exception(*exc_info, **dict(file=out))
return out.getvalue()
def open_logfile(filename, mode='a'):
"""Open the named log file in append mode.
If the file already exists, a separator will also be printed to
the file to separate past activity from current activity.
"""
filename = os.path.expanduser(filename)
filename = os.path.abspath(filename)
dirname = os.path.dirname(filename)
if not os.path.exists(dirname):
os.makedirs(dirname)
exists = os.path.exists(filename)
log_fp = open(filename, mode)
if exists:
log_fp.write('%s\n' % ('-'*60))
log_fp.write('%s run on %s\n' % (sys.argv[0], time.strftime('%c')))
return log_fp
def load_command(name):
full_name = 'pip.commands.%s' % name
if full_name in sys.modules:
return
try:
__import__(full_name)
except ImportError:
pass
def load_all_commands():
for name in command_names():
load_command(name)
def command_names():
names = set((pkg[1] for pkg in walk_packages(path=commands.__path__)))
return list(names)
-226
View File
@@ -1,226 +0,0 @@
"""Base option parser setup"""
import sys
import optparse
import pkg_resources
import os
from distutils.util import strtobool
from pip.backwardcompat import ConfigParser, string_types
from pip.locations import default_config_file, default_log_file
class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
"""Custom help formatter for use in ConfigOptionParser that updates
the defaults before expanding them, allowing them to show up correctly
in the help listing"""
def expand_default(self, option):
if self.parser is not None:
self.parser.update_defaults(self.parser.defaults)
return optparse.IndentedHelpFormatter.expand_default(self, option)
class ConfigOptionParser(optparse.OptionParser):
"""Custom option parser which updates its defaults by by checking the
configuration files and environmental variables"""
def __init__(self, *args, **kwargs):
self.config = ConfigParser.RawConfigParser()
self.name = kwargs.pop('name')
self.files = self.get_config_files()
self.config.read(self.files)
assert self.name
optparse.OptionParser.__init__(self, *args, **kwargs)
def get_config_files(self):
config_file = os.environ.get('PIP_CONFIG_FILE', False)
if config_file and os.path.exists(config_file):
return [config_file]
return [default_config_file]
def update_defaults(self, defaults):
"""Updates the given defaults with values from the config files and
the environ. Does a little special handling for certain types of
options (lists)."""
# Then go and look for the other sources of configuration:
config = {}
# 1. config files
for section in ('global', self.name):
config.update(self.normalize_keys(self.get_config_section(section)))
# 2. environmental variables
config.update(self.normalize_keys(self.get_environ_vars()))
# Then set the options with those values
for key, val in config.items():
option = self.get_option(key)
if option is not None:
# ignore empty values
if not val:
continue
# handle multiline configs
if option.action == 'append':
val = val.split()
else:
option.nargs = 1
if option.action in ('store_true', 'store_false', 'count'):
val = strtobool(val)
try:
val = option.convert_value(key, val)
except optparse.OptionValueError:
e = sys.exc_info()[1]
print("An error occured during configuration: %s" % e)
sys.exit(3)
defaults[option.dest] = val
return defaults
def normalize_keys(self, items):
"""Return a config dictionary with normalized keys regardless of
whether the keys were specified in environment variables or in config
files"""
normalized = {}
for key, val in items:
key = key.replace('_', '-')
if not key.startswith('--'):
key = '--%s' % key # only prefer long opts
normalized[key] = val
return normalized
def get_config_section(self, name):
"""Get a section of a configuration"""
if self.config.has_section(name):
return self.config.items(name)
return []
def get_environ_vars(self, prefix='PIP_'):
"""Returns a generator with all environmental vars with prefix PIP_"""
for key, val in os.environ.items():
if key.startswith(prefix):
yield (key.replace(prefix, '').lower(), val)
def get_default_values(self):
"""Overridding to make updating the defaults after instantiation of
the option parser possible, update_defaults() does the dirty work."""
if not self.process_default_values:
# Old, pre-Optik 1.5 behaviour.
return optparse.Values(self.defaults)
defaults = self.update_defaults(self.defaults.copy()) # ours
for option in self._get_all_options():
default = defaults.get(option.dest)
if isinstance(default, string_types):
opt_str = option.get_opt_string()
defaults[option.dest] = option.check_value(opt_str, default)
return optparse.Values(defaults)
try:
pip_dist = pkg_resources.get_distribution('pip')
version = '%s from %s (python %s)' % (
pip_dist, pip_dist.location, sys.version[:3])
except pkg_resources.DistributionNotFound:
# when running pip.py without installing
version=None
parser = ConfigOptionParser(
usage='%prog COMMAND [OPTIONS]',
version=version,
add_help_option=False,
formatter=UpdatingDefaultsHelpFormatter(),
name='global')
parser.add_option(
'-h', '--help',
dest='help',
action='store_true',
help='Show help')
parser.add_option(
# Run only if inside a virtualenv, bail if not.
'--require-virtualenv', '--require-venv',
dest='require_venv',
action='store_true',
default=False,
help=optparse.SUPPRESS_HELP)
parser.add_option(
'-v', '--verbose',
dest='verbose',
action='count',
default=0,
help='Give more output')
parser.add_option(
'-q', '--quiet',
dest='quiet',
action='count',
default=0,
help='Give less output')
parser.add_option(
'--log',
dest='log',
metavar='FILENAME',
help='Log file where a complete (maximum verbosity) record will be kept')
parser.add_option(
# Writes the log levels explicitely to the log'
'--log-explicit-levels',
dest='log_explicit_levels',
action='store_true',
default=False,
help=optparse.SUPPRESS_HELP)
parser.add_option(
# The default log file
'--local-log', '--log-file',
dest='log_file',
metavar='FILENAME',
default=default_log_file,
help=optparse.SUPPRESS_HELP)
parser.add_option(
# Don't ask for input
'--no-input',
dest='no_input',
action='store_true',
default=False,
help=optparse.SUPPRESS_HELP)
parser.add_option(
'--proxy',
dest='proxy',
type='str',
default='',
help="Specify a proxy in the form user:passwd@proxy.server:port. "
"Note that the user:password@ is optional and required only if you "
"are behind an authenticated proxy. If you provide "
"user@proxy.server:port then you will be prompted for a password.")
parser.add_option(
'--timeout', '--default-timeout',
metavar='SECONDS',
dest='timeout',
type='float',
default=15,
help='Set the socket timeout (default %default seconds)')
parser.add_option(
# The default version control system for editables, e.g. 'svn'
'--default-vcs',
dest='default_vcs',
type='str',
default='',
help=optparse.SUPPRESS_HELP)
parser.add_option(
# A regex to be used to skip requirements
'--skip-requirements-regex',
dest='skip_requirements_regex',
type='str',
default='',
help=optparse.SUPPRESS_HELP)
parser.add_option(
# Option when path already exist
'--exists-action',
dest='exists_action',
type='choice',
choices=['s', 'i', 'w', 'b'],
default=[],
action='append',
help="Default action when a path already exists."
"Use this option more then one time to specify "
"another action if a certain option is not "
"available, choices: "
"(s)witch, (i)gnore, (w)ipe, (b)ackup")
parser.disable_interspersed_args()
-1
View File
@@ -1 +0,0 @@
#
-33
View File
@@ -1,33 +0,0 @@
from pip.basecommand import (Command, command_dict,
load_all_commands, SUCCESS,
ERROR)
from pip.exceptions import CommandError
from pip.baseparser import parser
class HelpCommand(Command):
name = 'help'
usage = '%prog'
summary = 'Show available commands'
def run(self, options, args):
load_all_commands()
if args:
## FIXME: handle errors better here
command = args[0]
if command not in command_dict:
raise CommandError('No command with the name: %s' % command)
command = command_dict[command]
command.parser.print_help()
return SUCCESS
parser.print_help()
print('\nCommands available:')
commands = list(set(command_dict.values()))
commands.sort(key=lambda x: x.name)
for command in commands:
if command.hidden:
continue
print(' %s: %s' % (command.name, command.summary))
return SUCCESS
HelpCommand()
-279
View File
@@ -1,279 +0,0 @@
import os
import sys
import tempfile
import shutil
from pip.req import InstallRequirement, RequirementSet
from pip.req import parse_requirements
from pip.log import logger
from pip.locations import build_prefix, src_prefix
from pip.basecommand import Command
from pip.index import PackageFinder
from pip.exceptions import InstallationError, CommandError
class InstallCommand(Command):
name = 'install'
usage = '%prog [OPTIONS] PACKAGE_NAMES...'
summary = 'Install packages'
bundle = False
def __init__(self):
super(InstallCommand, self).__init__()
self.parser.add_option(
'-e', '--editable',
dest='editables',
action='append',
default=[],
metavar='VCS+REPOS_URL[@REV]#egg=PACKAGE',
help='Install a package directly from a checkout. Source will be checked '
'out into src/PACKAGE (lower-case) and installed in-place (using '
'setup.py develop). You can run this on an existing directory/checkout (like '
'pip install -e src/mycheckout). This option may be provided multiple times. '
'Possible values for VCS are: svn, git, hg and bzr.')
self.parser.add_option(
'-r', '--requirement',
dest='requirements',
action='append',
default=[],
metavar='FILENAME',
help='Install all the packages listed in the given requirements file. '
'This option can be used multiple times.')
self.parser.add_option(
'-f', '--find-links',
dest='find_links',
action='append',
default=[],
metavar='URL',
help='URL to look for packages at')
self.parser.add_option(
'-i', '--index-url', '--pypi-url',
dest='index_url',
metavar='URL',
default='http://pypi.python.org/simple/',
help='Base URL of Python Package Index (default %default)')
self.parser.add_option(
'--extra-index-url',
dest='extra_index_urls',
metavar='URL',
action='append',
default=[],
help='Extra URLs of package indexes to use in addition to --index-url')
self.parser.add_option(
'--no-index',
dest='no_index',
action='store_true',
default=False,
help='Ignore package index (only looking at --find-links URLs instead)')
self.parser.add_option(
'-M', '--use-mirrors',
dest='use_mirrors',
action='store_true',
default=False,
help='Use the PyPI mirrors as a fallback in case the main index is down.')
self.parser.add_option(
'--mirrors',
dest='mirrors',
metavar='URL',
action='append',
default=[],
help='Specific mirror URLs to query when --use-mirrors is used')
self.parser.add_option(
'-b', '--build', '--build-dir', '--build-directory',
dest='build_dir',
metavar='DIR',
default=build_prefix,
help='Unpack packages into DIR (default %default) and build from there')
self.parser.add_option(
'-t', '--target',
dest='target_dir',
metavar='DIR',
default=None,
help='Install packages into DIR.')
self.parser.add_option(
'-d', '--download', '--download-dir', '--download-directory',
dest='download_dir',
metavar='DIR',
default=None,
help='Download packages into DIR instead of installing them')
self.parser.add_option(
'--download-cache',
dest='download_cache',
metavar='DIR',
default=None,
help='Cache downloaded packages in DIR')
self.parser.add_option(
'--src', '--source', '--source-dir', '--source-directory',
dest='src_dir',
metavar='DIR',
default=src_prefix,
help='Check out --editable packages into DIR (default %default)')
self.parser.add_option(
'-U', '--upgrade',
dest='upgrade',
action='store_true',
help='Upgrade all packages to the newest available version')
self.parser.add_option(
'--force-reinstall',
dest='force_reinstall',
action='store_true',
help='When upgrading, reinstall all packages even if they are '
'already up-to-date.')
self.parser.add_option(
'-I', '--ignore-installed',
dest='ignore_installed',
action='store_true',
help='Ignore the installed packages (reinstalling instead)')
self.parser.add_option(
'--no-deps', '--no-dependencies',
dest='ignore_dependencies',
action='store_true',
default=False,
help='Ignore package dependencies')
self.parser.add_option(
'--no-install',
dest='no_install',
action='store_true',
help="Download and unpack all packages, but don't actually install them")
self.parser.add_option(
'--no-download',
dest='no_download',
action="store_true",
help="Don't download any packages, just install the ones already downloaded "
"(completes an install run with --no-install)")
self.parser.add_option(
'--install-option',
dest='install_options',
action='append',
help="Extra arguments to be supplied to the setup.py install "
"command (use like --install-option=\"--install-scripts=/usr/local/bin\"). "
"Use multiple --install-option options to pass multiple options to setup.py install. "
"If you are using an option with a directory path, be sure to use absolute path.")
self.parser.add_option(
'--global-option',
dest='global_options',
action='append',
help="Extra global options to be supplied to the setup.py"
"call before the install command")
self.parser.add_option(
'--user',
dest='use_user_site',
action='store_true',
help='Install to user-site')
def _build_package_finder(self, options, index_urls):
"""
Create a package finder appropriate to this install command.
This method is meant to be overridden by subclasses, not
called directly.
"""
return PackageFinder(find_links=options.find_links,
index_urls=index_urls,
use_mirrors=options.use_mirrors,
mirrors=options.mirrors)
def run(self, options, args):
if options.download_dir:
options.no_install = True
options.ignore_installed = True
options.build_dir = os.path.abspath(options.build_dir)
options.src_dir = os.path.abspath(options.src_dir)
install_options = options.install_options or []
if options.use_user_site:
install_options.append('--user')
if options.target_dir:
options.ignore_installed = True
temp_target_dir = tempfile.mkdtemp()
options.target_dir = os.path.abspath(options.target_dir)
if os.path.exists(options.target_dir) and not os.path.isdir(options.target_dir):
raise CommandError("Target path exists but is not a directory, will not continue.")
install_options.append('--home=' + temp_target_dir)
global_options = options.global_options or []
index_urls = [options.index_url] + options.extra_index_urls
if options.no_index:
logger.notify('Ignoring indexes: %s' % ','.join(index_urls))
index_urls = []
finder = self._build_package_finder(options, index_urls)
requirement_set = RequirementSet(
build_dir=options.build_dir,
src_dir=options.src_dir,
download_dir=options.download_dir,
download_cache=options.download_cache,
upgrade=options.upgrade,
ignore_installed=options.ignore_installed,
ignore_dependencies=options.ignore_dependencies,
force_reinstall=options.force_reinstall)
for name in args:
requirement_set.add_requirement(
InstallRequirement.from_line(name, None))
for name in options.editables:
requirement_set.add_requirement(
InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
for filename in options.requirements:
for req in parse_requirements(filename, finder=finder, options=options):
requirement_set.add_requirement(req)
if not requirement_set.has_requirements:
opts = {'name': self.name}
if options.find_links:
msg = ('You must give at least one requirement to %(name)s '
'(maybe you meant "pip %(name)s %(links)s"?)' %
dict(opts, links=' '.join(options.find_links)))
else:
msg = ('You must give at least one requirement '
'to %(name)s (see "pip help %(name)s")' % opts)
logger.warn(msg)
return
if (options.use_user_site and
sys.version_info < (2, 6)):
raise InstallationError('--user is only supported in Python version 2.6 and newer')
import setuptools
if (options.use_user_site and
requirement_set.has_editables and
not getattr(setuptools, '_distribute', False)):
raise InstallationError('--user --editable not supported with setuptools, use distribute')
if not options.no_download:
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
else:
requirement_set.locate_files()
if not options.no_install and not self.bundle:
requirement_set.install(install_options, global_options)
installed = ' '.join([req.name for req in
requirement_set.successfully_installed])
if installed:
logger.notify('Successfully installed %s' % installed)
elif not self.bundle:
downloaded = ' '.join([req.name for req in
requirement_set.successfully_downloaded])
if downloaded:
logger.notify('Successfully downloaded %s' % downloaded)
elif self.bundle:
requirement_set.create_bundle(self.bundle_filename)
logger.notify('Created bundle in %s' % self.bundle_filename)
# Clean up
if not options.no_install or options.download_dir:
requirement_set.cleanup_files(bundle=self.bundle)
if options.target_dir:
if not os.path.exists(options.target_dir):
os.makedirs(options.target_dir)
lib_dir = os.path.join(temp_target_dir, "lib/python/")
for item in os.listdir(lib_dir):
shutil.move(
os.path.join(lib_dir, item),
os.path.join(options.target_dir, item)
)
shutil.rmtree(temp_target_dir)
return requirement_set
InstallCommand()
-481
View File
@@ -1,481 +0,0 @@
import cgi
import getpass
import mimetypes
import os
import re
import shutil
import sys
import tempfile
from pip.backwardcompat import (md5, copytree, xmlrpclib, urllib, urllib2,
urlparse, string_types, HTTPError)
from pip.exceptions import InstallationError
from pip.util import (splitext, rmtree, format_size, display_path,
backup_dir, ask, ask_path_exists, unpack_file,
create_download_cache_folder, cache_download)
from pip.vcs import vcs
from pip.log import logger
__all__ = ['xmlrpclib_transport', 'get_file_content', 'urlopen',
'is_url', 'url_to_path', 'path_to_url', 'path_to_url2',
'geturl', 'is_archive_file', 'unpack_vcs_link',
'unpack_file_url', 'is_vcs_url', 'is_file_url', 'unpack_http_url']
xmlrpclib_transport = xmlrpclib.Transport()
def get_file_content(url, comes_from=None):
"""Gets the content of a file; it may be a filename, file: URL, or
http: URL. Returns (location, content)"""
match = _scheme_re.search(url)
if match:
scheme = match.group(1).lower()
if (scheme == 'file' and comes_from
and comes_from.startswith('http')):
raise InstallationError(
'Requirements file %s references URL %s, which is local'
% (comes_from, url))
if scheme == 'file':
path = url.split(':', 1)[1]
path = path.replace('\\', '/')
match = _url_slash_drive_re.match(path)
if match:
path = match.group(1) + ':' + path.split('|', 1)[1]
path = urllib.unquote(path)
if path.startswith('/'):
path = '/' + path.lstrip('/')
url = path
else:
## FIXME: catch some errors
resp = urlopen(url)
return geturl(resp), resp.read()
try:
f = open(url)
content = f.read()
except IOError:
e = sys.exc_info()[1]
raise InstallationError('Could not open requirements file: %s' % str(e))
else:
f.close()
return url, content
_scheme_re = re.compile(r'^(http|https|file):', re.I)
_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I)
class URLOpener(object):
"""
pip's own URL helper that adds HTTP auth and proxy support
"""
def __init__(self):
self.passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
def __call__(self, url):
"""
If the given url contains auth info or if a normal request gets a 401
response, an attempt is made to fetch the resource using basic HTTP
auth.
"""
url, username, password = self.extract_credentials(url)
if username is None:
try:
response = urllib2.urlopen(self.get_request(url))
except urllib2.HTTPError:
e = sys.exc_info()[1]
if e.code != 401:
raise
response = self.get_response(url)
else:
response = self.get_response(url, username, password)
return response
def get_request(self, url):
"""
Wraps the URL to retrieve to protects against "creative"
interpretation of the RFC: http://bugs.python.org/issue8732
"""
if isinstance(url, string_types):
url = urllib2.Request(url, headers={'Accept-encoding': 'identity'})
return url
def get_response(self, url, username=None, password=None):
"""
does the dirty work of actually getting the rsponse object using urllib2
and its HTTP auth builtins.
"""
scheme, netloc, path, query, frag = urlparse.urlsplit(url)
req = self.get_request(url)
stored_username, stored_password = self.passman.find_user_password(None, netloc)
# see if we have a password stored
if stored_username is None:
if username is None and self.prompting:
username = urllib.quote(raw_input('User for %s: ' % netloc))
password = urllib.quote(getpass.getpass('Password: '))
if username and password:
self.passman.add_password(None, netloc, username, password)
stored_username, stored_password = self.passman.find_user_password(None, netloc)
authhandler = urllib2.HTTPBasicAuthHandler(self.passman)
opener = urllib2.build_opener(authhandler)
# FIXME: should catch a 401 and offer to let the user reenter credentials
return opener.open(req)
def setup(self, proxystr='', prompting=True):
"""
Sets the proxy handler given the option passed on the command
line. If an empty string is passed it looks at the HTTP_PROXY
environment variable.
"""
self.prompting = prompting
proxy = self.get_proxy(proxystr)
if proxy:
proxy_support = urllib2.ProxyHandler({"http": proxy, "ftp": proxy, "https": proxy})
opener = urllib2.build_opener(proxy_support, urllib2.CacheFTPHandler)
urllib2.install_opener(opener)
def parse_credentials(self, netloc):
if "@" in netloc:
userinfo = netloc.rsplit("@", 1)[0]
if ":" in userinfo:
return userinfo.split(":", 1)
return userinfo, None
return None, None
def extract_credentials(self, url):
"""
Extracts user/password from a url.
Returns a tuple:
(url-without-auth, username, password)
"""
if isinstance(url, urllib2.Request):
result = urlparse.urlsplit(url.get_full_url())
else:
result = urlparse.urlsplit(url)
scheme, netloc, path, query, frag = result
username, password = self.parse_credentials(netloc)
if username is None:
return url, None, None
elif password is None and self.prompting:
# remove the auth credentials from the url part
netloc = netloc.replace('%s@' % username, '', 1)
# prompt for the password
prompt = 'Password for %s@%s: ' % (username, netloc)
password = urllib.quote(getpass.getpass(prompt))
else:
# remove the auth credentials from the url part
netloc = netloc.replace('%s:%s@' % (username, password), '', 1)
target_url = urlparse.urlunsplit((scheme, netloc, path, query, frag))
return target_url, username, password
def get_proxy(self, proxystr=''):
"""
Get the proxy given the option passed on the command line.
If an empty string is passed it looks at the HTTP_PROXY
environment variable.
"""
if not proxystr:
proxystr = os.environ.get('HTTP_PROXY', '')
if proxystr:
if '@' in proxystr:
user_password, server_port = proxystr.split('@', 1)
if ':' in user_password:
user, password = user_password.split(':', 1)
else:
user = user_password
prompt = 'Password for %s@%s: ' % (user, server_port)
password = urllib.quote(getpass.getpass(prompt))
return '%s:%s@%s' % (user, password, server_port)
else:
return proxystr
else:
return None
urlopen = URLOpener()
def is_url(name):
"""Returns true if the name looks like a URL"""
if ':' not in name:
return False
scheme = name.split(':', 1)[0].lower()
return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes
def url_to_path(url):
"""
Convert a file: URL to a path.
"""
assert url.startswith('file:'), (
"You can only turn file: urls into filenames (not %r)" % url)
path = url[len('file:'):].lstrip('/')
path = urllib.unquote(path)
if _url_drive_re.match(path):
path = path[0] + ':' + path[2:]
else:
path = '/' + path
return path
_drive_re = re.compile('^([a-z]):', re.I)
_url_drive_re = re.compile('^([a-z])[:|]', re.I)
def path_to_url(path):
"""
Convert a path to a file: URL. The path will be made absolute.
"""
path = os.path.normcase(os.path.abspath(path))
if _drive_re.match(path):
path = path[0] + '|' + path[2:]
url = urllib.quote(path)
url = url.replace(os.path.sep, '/')
url = url.lstrip('/')
return 'file:///' + url
def path_to_url2(path):
"""
Convert a path to a file: URL. The path will be made absolute and have
quoted path parts.
"""
path = os.path.normpath(os.path.abspath(path))
drive, path = os.path.splitdrive(path)
filepath = path.split(os.path.sep)
url = '/'.join([urllib.quote(part) for part in filepath])
if not drive:
url = url.lstrip('/')
return 'file:///' + drive + url
def geturl(urllib2_resp):
"""
Use instead of urllib.addinfourl.geturl(), which appears to have
some issues with dropping the double slash for certain schemes
(e.g. file://). This implementation is probably over-eager, as it
always restores '://' if it is missing, and it appears some url
schemata aren't always followed by '//' after the colon, but as
far as I know pip doesn't need any of those.
The URI RFC can be found at: http://tools.ietf.org/html/rfc1630
This function assumes that
scheme:/foo/bar
is the same as
scheme:///foo/bar
"""
url = urllib2_resp.geturl()
scheme, rest = url.split(':', 1)
if rest.startswith('//'):
return url
else:
# FIXME: write a good test to cover it
return '%s://%s' % (scheme, rest)
def is_archive_file(name):
"""Return True if `name` is a considered as an archive file."""
archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.pybundle')
ext = splitext(name)[1].lower()
if ext in archives:
return True
return False
def unpack_vcs_link(link, location, only_download=False):
vcs_backend = _get_used_vcs_backend(link)
if only_download:
vcs_backend.export(location)
else:
vcs_backend.unpack(location)
def unpack_file_url(link, location):
source = url_to_path(link.url)
content_type = mimetypes.guess_type(source)[0]
if os.path.isdir(source):
# delete the location since shutil will create it again :(
if os.path.isdir(location):
rmtree(location)
copytree(source, location)
else:
unpack_file(source, location, content_type, link)
def _get_used_vcs_backend(link):
for backend in vcs.backends:
if link.scheme in backend.schemes:
vcs_backend = backend(link.url)
return vcs_backend
def is_vcs_url(link):
return bool(_get_used_vcs_backend(link))
def is_file_url(link):
return link.url.lower().startswith('file:')
def _check_md5(download_hash, link):
download_hash = download_hash.hexdigest()
if download_hash != link.md5_hash:
logger.fatal("MD5 hash of the package %s (%s) doesn't match the expected hash %s!"
% (link, download_hash, link.md5_hash))
raise InstallationError('Bad MD5 hash for package %s' % link)
def _get_md5_from_file(target_file, link):
download_hash = md5()
fp = open(target_file, 'rb')
while True:
chunk = fp.read(4096)
if not chunk:
break
download_hash.update(chunk)
fp.close()
return download_hash
def _download_url(resp, link, temp_location):
fp = open(temp_location, 'wb')
download_hash = None
if link.md5_hash:
download_hash = md5()
try:
total_length = int(resp.info()['content-length'])
except (ValueError, KeyError, TypeError):
total_length = 0
downloaded = 0
show_progress = total_length > 40*1000 or not total_length
show_url = link.show_url
try:
if show_progress:
## FIXME: the URL can get really long in this message:
if total_length:
logger.start_progress('Downloading %s (%s): ' % (show_url, format_size(total_length)))
else:
logger.start_progress('Downloading %s (unknown size): ' % show_url)
else:
logger.notify('Downloading %s' % show_url)
logger.debug('Downloading from URL %s' % link)
while True:
chunk = resp.read(4096)
if not chunk:
break
downloaded += len(chunk)
if show_progress:
if not total_length:
logger.show_progress('%s' % format_size(downloaded))
else:
logger.show_progress('%3i%% %s' % (100*downloaded/total_length, format_size(downloaded)))
if link.md5_hash:
download_hash.update(chunk)
fp.write(chunk)
fp.close()
finally:
if show_progress:
logger.end_progress('%s downloaded' % format_size(downloaded))
return download_hash
def _copy_file(filename, location, content_type, link):
copy = True
download_location = os.path.join(location, link.filename)
if os.path.exists(download_location):
response = ask_path_exists(
'The file %s exists. (i)gnore, (w)ipe, (b)ackup ' %
display_path(download_location), ('i', 'w', 'b'))
if response == 'i':
copy = False
elif response == 'w':
logger.warn('Deleting %s' % display_path(download_location))
os.remove(download_location)
elif response == 'b':
dest_file = backup_dir(download_location)
logger.warn('Backing up %s to %s'
% (display_path(download_location), display_path(dest_file)))
shutil.move(download_location, dest_file)
if copy:
shutil.copy(filename, download_location)
logger.indent -= 2
logger.notify('Saved %s' % display_path(download_location))
def unpack_http_url(link, location, download_cache, download_dir=None):
temp_dir = tempfile.mkdtemp('-unpack', 'pip-')
target_url = link.url.split('#', 1)[0]
target_file = None
download_hash = None
if download_cache:
target_file = os.path.join(download_cache,
urllib.quote(target_url, ''))
if not os.path.isdir(download_cache):
create_download_cache_folder(download_cache)
if (target_file
and os.path.exists(target_file)
and os.path.exists(target_file + '.content-type')):
fp = open(target_file+'.content-type')
content_type = fp.read().strip()
fp.close()
if link.md5_hash:
download_hash = _get_md5_from_file(target_file, link)
temp_location = target_file
logger.notify('Using download cache from %s' % target_file)
else:
resp = _get_response_from_url(target_url, link)
content_type = resp.info()['content-type']
filename = link.filename # fallback
# Have a look at the Content-Disposition header for a better guess
content_disposition = resp.info().get('content-disposition')
if content_disposition:
type, params = cgi.parse_header(content_disposition)
# We use ``or`` here because we don't want to use an "empty" value
# from the filename param.
filename = params.get('filename') or filename
ext = splitext(filename)[1]
if not ext:
ext = mimetypes.guess_extension(content_type)
if ext:
filename += ext
if not ext and link.url != geturl(resp):
ext = os.path.splitext(geturl(resp))[1]
if ext:
filename += ext
temp_location = os.path.join(temp_dir, filename)
download_hash = _download_url(resp, link, temp_location)
if link.md5_hash:
_check_md5(download_hash, link)
if download_dir:
_copy_file(temp_location, download_dir, content_type, link)
unpack_file(temp_location, location, content_type, link)
if target_file and target_file != temp_location:
cache_download(target_file, temp_location, content_type)
if target_file is None:
os.unlink(temp_location)
os.rmdir(temp_dir)
def _get_response_from_url(target_url, link):
try:
resp = urlopen(target_url)
except urllib2.HTTPError:
e = sys.exc_info()[1]
logger.fatal("HTTP error %s while getting %s" % (e.code, link))
raise
except IOError:
e = sys.exc_info()[1]
# Typically an FTP error
logger.fatal("Error %s while getting %s" % (e, link))
raise
return resp
class Urllib2HeadRequest(urllib2.Request):
def get_method(self):
return "HEAD"
-27
View File
@@ -1,27 +0,0 @@
"""Exceptions used throughout package"""
class InstallationError(Exception):
"""General exception during installation"""
class UninstallationError(Exception):
"""General exception during uninstallation"""
class DistributionNotFound(InstallationError):
"""Raised when a distribution cannot be found to satisfy a requirement"""
class BestVersionAlreadyInstalled(Exception):
"""Raised when the most up-to-date version of a package is already
installed.
"""
class BadCommand(Exception):
"""Raised when virtualenv or a command is not found"""
class CommandError(Exception):
"""Raised when there is an error in command-line arguments"""
-708
View File
@@ -1,708 +0,0 @@
"""Routines related to PyPI, indexes"""
import sys
import os
import re
import gzip
import mimetypes
try:
import threading
except ImportError:
import dummy_threading as threading
import posixpath
import pkg_resources
import random
import socket
import string
import zlib
from pip.log import logger
from pip.util import Inf
from pip.util import normalize_name, splitext
from pip.exceptions import DistributionNotFound, BestVersionAlreadyInstalled
from pip.backwardcompat import (WindowsError, BytesIO,
Queue, httplib, urlparse,
URLError, HTTPError, u,
product, url2pathname)
from pip.backwardcompat import Empty as QueueEmpty
from pip.download import urlopen, path_to_url2, url_to_path, geturl, Urllib2HeadRequest
__all__ = ['PackageFinder']
DEFAULT_MIRROR_URL = "last.pypi.python.org"
class PackageFinder(object):
"""This finds packages.
This is meant to match easy_install's technique for looking for
packages, by reading pages and looking for appropriate links
"""
def __init__(self, find_links, index_urls,
use_mirrors=False, mirrors=None, main_mirror_url=None):
self.find_links = find_links
self.index_urls = index_urls
self.dependency_links = []
self.cache = PageCache()
# These are boring links that have already been logged somehow:
self.logged_links = set()
if use_mirrors:
self.mirror_urls = self._get_mirror_urls(mirrors, main_mirror_url)
logger.info('Using PyPI mirrors: %s' % ', '.join(self.mirror_urls))
else:
self.mirror_urls = []
def add_dependency_links(self, links):
## FIXME: this shouldn't be global list this, it should only
## apply to requirements of the package that specifies the
## dependency_links value
## FIXME: also, we should track comes_from (i.e., use Link)
self.dependency_links.extend(links)
@staticmethod
def _sort_locations(locations):
"""
Sort locations into "files" (archives) and "urls", and return
a pair of lists (files,urls)
"""
files = []
urls = []
# puts the url for the given file path into the appropriate
# list
def sort_path(path):
url = path_to_url2(path)
if mimetypes.guess_type(url, strict=False)[0] == 'text/html':
urls.append(url)
else:
files.append(url)
for url in locations:
if url.startswith('file:'):
path = url_to_path(url)
if os.path.isdir(path):
path = os.path.realpath(path)
for item in os.listdir(path):
sort_path(os.path.join(path, item))
elif os.path.isfile(path):
sort_path(path)
else:
urls.append(url)
return files, urls
def find_requirement(self, req, upgrade):
url_name = req.url_name
# Only check main index if index URL is given:
main_index_url = None
if self.index_urls:
# Check that we have the url_name correctly spelled:
main_index_url = Link(posixpath.join(self.index_urls[0], url_name))
# This will also cache the page, so it's okay that we get it again later:
page = self._get_page(main_index_url, req)
if page is None:
url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name
# Combine index URLs with mirror URLs here to allow
# adding more index URLs from requirements files
all_index_urls = self.index_urls + self.mirror_urls
def mkurl_pypi_url(url):
loc = posixpath.join(url, url_name)
# For maximum compatibility with easy_install, ensure the path
# ends in a trailing slash. Although this isn't in the spec
# (and PyPI can handle it without the slash) some other index
# implementations might break if they relied on easy_install's behavior.
if not loc.endswith('/'):
loc = loc + '/'
return loc
if url_name is not None:
locations = [
mkurl_pypi_url(url)
for url in all_index_urls] + self.find_links
else:
locations = list(self.find_links)
locations.extend(self.dependency_links)
for version in req.absolute_versions:
if url_name is not None and main_index_url is not None:
locations = [
posixpath.join(main_index_url.url, version)] + locations
file_locations, url_locations = self._sort_locations(locations)
locations = [Link(url) for url in url_locations]
logger.debug('URLs to search for versions for %s:' % req)
for location in locations:
logger.debug('* %s' % location)
found_versions = []
found_versions.extend(
self._package_versions(
[Link(url, '-f') for url in self.find_links], req.name.lower()))
page_versions = []
for page in self._get_pages(locations, req):
logger.debug('Analyzing links from page %s' % page.url)
logger.indent += 2
try:
page_versions.extend(self._package_versions(page.links, req.name.lower()))
finally:
logger.indent -= 2
dependency_versions = list(self._package_versions(
[Link(url) for url in self.dependency_links], req.name.lower()))
if dependency_versions:
logger.info('dependency_links found: %s' % ', '.join([link.url for parsed, link, version in dependency_versions]))
file_versions = list(self._package_versions(
[Link(url) for url in file_locations], req.name.lower()))
if not found_versions and not page_versions and not dependency_versions and not file_versions:
logger.fatal('Could not find any downloads that satisfy the requirement %s' % req)
raise DistributionNotFound('No distributions at all found for %s' % req)
if req.satisfied_by is not None:
found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version))
if file_versions:
file_versions.sort(reverse=True)
logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions]))
found_versions = file_versions + found_versions
all_versions = found_versions + page_versions + dependency_versions
applicable_versions = []
for (parsed_version, link, version) in all_versions:
if version not in req.req:
logger.info("Ignoring link %s, version %s doesn't match %s"
% (link, version, ','.join([''.join(s) for s in req.req.specs])))
continue
applicable_versions.append((link, version))
applicable_versions = sorted(applicable_versions, key=lambda v: pkg_resources.parse_version(v[1]), reverse=True)
existing_applicable = bool([link for link, version in applicable_versions if link is Inf])
if not upgrade and existing_applicable:
if applicable_versions[0][1] is Inf:
logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
% req.satisfied_by.version)
raise BestVersionAlreadyInstalled
else:
logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
% (req.satisfied_by.version, applicable_versions[0][1]))
return None
if not applicable_versions:
logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)'
% (req, ', '.join([version for parsed_version, link, version in found_versions])))
raise DistributionNotFound('No distributions matching the version for %s' % req)
if applicable_versions[0][0] is Inf:
# We have an existing version, and its the best version
logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
% (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
raise BestVersionAlreadyInstalled
if len(applicable_versions) > 1:
logger.info('Using version %s (newest of versions: %s)' %
(applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
return applicable_versions[0][0]
def _find_url_name(self, index_url, url_name, req):
"""Finds the true URL name of a package, when the given name isn't quite correct.
This is usually used to implement case-insensitivity."""
if not index_url.url.endswith('/'):
# Vaguely part of the PyPI API... weird but true.
## FIXME: bad to modify this?
index_url.url += '/'
page = self._get_page(index_url, req)
if page is None:
logger.fatal('Cannot fetch index base URL %s' % index_url)
return
norm_name = normalize_name(req.url_name)
for link in page.links:
base = posixpath.basename(link.path.rstrip('/'))
if norm_name == normalize_name(base):
logger.notify('Real name of requirement %s is %s' % (url_name, base))
return base
return None
def _get_pages(self, locations, req):
"""Yields (page, page_url) from the given locations, skipping
locations that have errors, and adding download/homepage links"""
pending_queue = Queue()
for location in locations:
pending_queue.put(location)
done = []
seen = set()
threads = []
for i in range(min(10, len(locations))):
t = threading.Thread(target=self._get_queued_page, args=(req, pending_queue, done, seen))
t.setDaemon(True)
threads.append(t)
t.start()
for t in threads:
t.join()
return done
_log_lock = threading.Lock()
def _get_queued_page(self, req, pending_queue, done, seen):
while 1:
try:
location = pending_queue.get(False)
except QueueEmpty:
return
if location in seen:
continue
seen.add(location)
page = self._get_page(location, req)
if page is None:
continue
done.append(page)
for link in page.rel_links():
pending_queue.put(link)
_egg_fragment_re = re.compile(r'#egg=([^&]*)')
_egg_info_re = re.compile(r'([a-z0-9_.]+)-([a-z0-9_.-]+)', re.I)
_py_version_re = re.compile(r'-py([123]\.?[0-9]?)$')
def _sort_links(self, links):
"Returns elements of links in order, non-egg links first, egg links second, while eliminating duplicates"
eggs, no_eggs = [], []
seen = set()
for link in links:
if link not in seen:
seen.add(link)
if link.egg_fragment:
eggs.append(link)
else:
no_eggs.append(link)
return no_eggs + eggs
def _package_versions(self, links, search_name):
for link in self._sort_links(links):
for v in self._link_package_versions(link, search_name):
yield v
def _link_package_versions(self, link, search_name):
"""
Return an iterable of triples (pkg_resources_version_key,
link, python_version) that can be extracted from the given
link.
Meant to be overridden by subclasses, not called by clients.
"""
if link.egg_fragment:
egg_info = link.egg_fragment
else:
egg_info, ext = link.splitext()
if not ext:
if link not in self.logged_links:
logger.debug('Skipping link %s; not a file' % link)
self.logged_links.add(link)
return []
if egg_info.endswith('.tar'):
# Special double-extension case:
egg_info = egg_info[:-4]
ext = '.tar' + ext
if ext not in ('.tar.gz', '.tar.bz2', '.tar', '.tgz', '.zip'):
if link not in self.logged_links:
logger.debug('Skipping link %s; unknown archive format: %s' % (link, ext))
self.logged_links.add(link)
return []
if "macosx10" in link.path and ext == '.zip':
if link not in self.logged_links:
logger.debug('Skipping link %s; macosx10 one' % (link))
self.logged_links.add(link)
return []
version = self._egg_info_matches(egg_info, search_name, link)
if version is None:
logger.debug('Skipping link %s; wrong project name (not %s)' % (link, search_name))
return []
match = self._py_version_re.search(version)
if match:
version = version[:match.start()]
py_version = match.group(1)
if py_version != sys.version[:3]:
logger.debug('Skipping %s because Python version is incorrect' % link)
return []
logger.debug('Found link %s, version: %s' % (link, version))
return [(pkg_resources.parse_version(version),
link,
version)]
def _egg_info_matches(self, egg_info, search_name, link):
match = self._egg_info_re.search(egg_info)
if not match:
logger.debug('Could not parse version from link: %s' % link)
return None
name = match.group(0).lower()
# To match the "safe" name that pkg_resources creates:
name = name.replace('_', '-')
if name.startswith(search_name.lower()):
return match.group(0)[len(search_name):].lstrip('-')
else:
return None
def _get_page(self, link, req):
return HTMLPage.get_page(link, req, cache=self.cache)
def _get_mirror_urls(self, mirrors=None, main_mirror_url=None):
"""Retrieves a list of URLs from the main mirror DNS entry
unless a list of mirror URLs are passed.
"""
if not mirrors:
mirrors = get_mirrors(main_mirror_url)
# Should this be made "less random"? E.g. netselect like?
random.shuffle(mirrors)
mirror_urls = set()
for mirror_url in mirrors:
# Make sure we have a valid URL
if not ("http://" or "https://" or "file://") in mirror_url:
mirror_url = "http://%s" % mirror_url
if not mirror_url.endswith("/simple"):
mirror_url = "%s/simple/" % mirror_url
mirror_urls.add(mirror_url)
return list(mirror_urls)
class PageCache(object):
"""Cache of HTML pages"""
failure_limit = 3
def __init__(self):
self._failures = {}
self._pages = {}
self._archives = {}
def too_many_failures(self, url):
return self._failures.get(url, 0) >= self.failure_limit
def get_page(self, url):
return self._pages.get(url)
def is_archive(self, url):
return self._archives.get(url, False)
def set_is_archive(self, url, value=True):
self._archives[url] = value
def add_page_failure(self, url, level):
self._failures[url] = self._failures.get(url, 0)+level
def add_page(self, urls, page):
for url in urls:
self._pages[url] = page
class HTMLPage(object):
"""Represents one page, along with its URL"""
## FIXME: these regexes are horrible hacks:
_homepage_re = re.compile(r'<th>\s*home\s*page', re.I)
_download_re = re.compile(r'<th>\s*download\s+url', re.I)
## These aren't so aweful:
_rel_re = re.compile("""<[^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*>""", re.I)
_href_re = re.compile('href=(?:"([^"]*)"|\'([^\']*)\'|([^>\\s\\n]*))', re.I|re.S)
_base_re = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I)
def __init__(self, content, url, headers=None):
self.content = content
self.url = url
self.headers = headers
def __str__(self):
return self.url
@classmethod
def get_page(cls, link, req, cache=None, skip_archives=True):
url = link.url
url = url.split('#', 1)[0]
if cache.too_many_failures(url):
return None
# Check for VCS schemes that do not support lookup as web pages.
from pip.vcs import VcsSupport
for scheme in VcsSupport.schemes:
if url.lower().startswith(scheme) and url[len(scheme)] in '+:':
logger.debug('Cannot look at %(scheme)s URL %(link)s' % locals())
return None
if cache is not None:
inst = cache.get_page(url)
if inst is not None:
return inst
try:
if skip_archives:
if cache is not None:
if cache.is_archive(url):
return None
filename = link.filename
for bad_ext in ['.tar', '.tar.gz', '.tar.bz2', '.tgz', '.zip']:
if filename.endswith(bad_ext):
content_type = cls._get_content_type(url)
if content_type.lower().startswith('text/html'):
break
else:
logger.debug('Skipping page %s because of Content-Type: %s' % (link, content_type))
if cache is not None:
cache.set_is_archive(url)
return None
logger.debug('Getting page %s' % url)
# Tack index.html onto file:// URLs that point to directories
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
if scheme == 'file' and os.path.isdir(url2pathname(path)):
# add trailing slash if not present so urljoin doesn't trim final segment
if not url.endswith('/'):
url += '/'
url = urlparse.urljoin(url, 'index.html')
logger.debug(' file: URL is directory, getting %s' % url)
resp = urlopen(url)
real_url = geturl(resp)
headers = resp.info()
contents = resp.read()
encoding = headers.get('Content-Encoding', None)
#XXX need to handle exceptions and add testing for this
if encoding is not None:
if encoding == 'gzip':
contents = gzip.GzipFile(fileobj=BytesIO(contents)).read()
if encoding == 'deflate':
contents = zlib.decompress(contents)
inst = cls(u(contents), real_url, headers)
except (HTTPError, URLError, socket.timeout, socket.error, OSError, WindowsError):
e = sys.exc_info()[1]
desc = str(e)
if isinstance(e, socket.timeout):
log_meth = logger.info
level =1
desc = 'timed out'
elif isinstance(e, URLError):
log_meth = logger.info
if hasattr(e, 'reason') and isinstance(e.reason, socket.timeout):
desc = 'timed out'
level = 1
else:
level = 2
elif isinstance(e, HTTPError) and e.code == 404:
## FIXME: notify?
log_meth = logger.info
level = 2
else:
log_meth = logger.info
level = 1
log_meth('Could not fetch URL %s: %s' % (link, desc))
log_meth('Will skip URL %s when looking for download links for %s' % (link.url, req))
if cache is not None:
cache.add_page_failure(url, level)
return None
if cache is not None:
cache.add_page([url, real_url], inst)
return inst
@staticmethod
def _get_content_type(url):
"""Get the Content-Type of the given url, using a HEAD request"""
scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
if not scheme in ('http', 'https', 'ftp', 'ftps'):
## FIXME: some warning or something?
## assertion error?
return ''
req = Urllib2HeadRequest(url, headers={'Host': netloc})
resp = urlopen(req)
try:
if hasattr(resp, 'code') and resp.code != 200 and scheme not in ('ftp', 'ftps'):
## FIXME: doesn't handle redirects
return ''
return resp.info().get('content-type', '')
finally:
resp.close()
@property
def base_url(self):
if not hasattr(self, "_base_url"):
match = self._base_re.search(self.content)
if match:
self._base_url = match.group(1)
else:
self._base_url = self.url
return self._base_url
@property
def links(self):
"""Yields all links in the page"""
for match in self._href_re.finditer(self.content):
url = match.group(1) or match.group(2) or match.group(3)
url = self.clean_link(urlparse.urljoin(self.base_url, url))
yield Link(url, self)
def rel_links(self):
for url in self.explicit_rel_links():
yield url
for url in self.scraped_rel_links():
yield url
def explicit_rel_links(self, rels=('homepage', 'download')):
"""Yields all links with the given relations"""
for match in self._rel_re.finditer(self.content):
found_rels = match.group(1).lower().split()
for rel in rels:
if rel in found_rels:
break
else:
continue
match = self._href_re.search(match.group(0))
if not match:
continue
url = match.group(1) or match.group(2) or match.group(3)
url = self.clean_link(urlparse.urljoin(self.base_url, url))
yield Link(url, self)
def scraped_rel_links(self):
for regex in (self._homepage_re, self._download_re):
match = regex.search(self.content)
if not match:
continue
href_match = self._href_re.search(self.content, pos=match.end())
if not href_match:
continue
url = href_match.group(1) or href_match.group(2) or href_match.group(3)
if not url:
continue
url = self.clean_link(urlparse.urljoin(self.base_url, url))
yield Link(url, self)
_clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I)
def clean_link(self, url):
"""Makes sure a link is fully encoded. That is, if a ' ' shows up in
the link, it will be rewritten to %20 (while not over-quoting
% or other characters)."""
return self._clean_re.sub(
lambda match: '%%%2x' % ord(match.group(0)), url)
class Link(object):
def __init__(self, url, comes_from=None):
self.url = url
self.comes_from = comes_from
def __str__(self):
if self.comes_from:
return '%s (from %s)' % (self.url, self.comes_from)
else:
return self.url
def __repr__(self):
return '<Link %s>' % self
def __eq__(self, other):
return self.url == other.url
def __hash__(self):
return hash(self.url)
@property
def filename(self):
url = self.url_fragment
name = posixpath.basename(url)
assert name, ('URL %r produced no filename' % url)
return name
@property
def scheme(self):
return urlparse.urlsplit(self.url)[0]
@property
def path(self):
return urlparse.urlsplit(self.url)[2]
def splitext(self):
return splitext(posixpath.basename(self.path.rstrip('/')))
@property
def url_fragment(self):
url = self.url
url = url.split('#', 1)[0]
url = url.split('?', 1)[0]
url = url.rstrip('/')
return url
_egg_fragment_re = re.compile(r'#egg=([^&]*)')
@property
def egg_fragment(self):
match = self._egg_fragment_re.search(self.url)
if not match:
return None
return match.group(1)
_md5_re = re.compile(r'md5=([a-f0-9]+)')
@property
def md5_hash(self):
match = self._md5_re.search(self.url)
if match:
return match.group(1)
return None
@property
def show_url(self):
return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
def get_requirement_from_url(url):
"""Get a requirement from the URL, if possible. This looks for #egg
in the URL"""
link = Link(url)
egg_info = link.egg_fragment
if not egg_info:
egg_info = splitext(link.filename)[0]
return package_to_requirement(egg_info)
def package_to_requirement(package_name):
"""Translate a name like Foo-1.2 to Foo==1.3"""
match = re.search(r'^(.*?)-(dev|\d.*)', package_name)
if match:
name = match.group(1)
version = match.group(2)
else:
name = package_name
version = ''
if version:
return '%s==%s' % (name, version)
else:
return name
def get_mirrors(hostname=None):
"""Return the list of mirrors from the last record found on the DNS
entry::
>>> from pip.index import get_mirrors
>>> get_mirrors()
['a.pypi.python.org', 'b.pypi.python.org', 'c.pypi.python.org',
'd.pypi.python.org']
Originally written for the distutils2 project by Alexis Metaireau.
"""
if hostname is None:
hostname = DEFAULT_MIRROR_URL
# return the last mirror registered on PyPI.
try:
hostname = socket.gethostbyname_ex(hostname)[0]
except socket.gaierror:
return []
end_letter = hostname.split(".", 1)
# determine the list from the last one.
return ["%s.%s" % (s, end_letter[1]) for s in string_range(end_letter[0])]
def string_range(last):
"""Compute the range of string between "a" and last.
This works for simple "a to z" lists, but also for "a to zz" lists.
"""
for k in range(len(last)):
for x in product(string.ascii_lowercase, repeat=k+1):
result = ''.join(x)
yield result
if result == last:
return
-52
View File
@@ -1,52 +0,0 @@
"""Locations where we look for configs, install stuff, etc"""
import sys
import os
from pip.backwardcompat import get_python_lib
def running_under_virtualenv():
"""
Return True if we're running inside a virtualenv, False otherwise.
"""
return hasattr(sys, 'real_prefix')
if running_under_virtualenv():
## FIXME: is build/ a good name?
build_prefix = os.path.join(sys.prefix, 'build')
src_prefix = os.path.join(sys.prefix, 'src')
else:
## FIXME: this isn't a very good default
build_prefix = os.path.join(os.getcwd(), 'build')
src_prefix = os.path.join(os.getcwd(), 'src')
# under Mac OS X + virtualenv sys.prefix is not properly resolved
# it is something like /path/to/python/bin/..
build_prefix = os.path.abspath(build_prefix)
src_prefix = os.path.abspath(src_prefix)
# FIXME doesn't account for venv linked to global site-packages
site_packages = get_python_lib()
user_dir = os.path.expanduser('~')
if sys.platform == 'win32':
bin_py = os.path.join(sys.prefix, 'Scripts')
# buildout uses 'bin' on Windows too?
if not os.path.exists(bin_py):
bin_py = os.path.join(sys.prefix, 'bin')
user_dir = os.environ.get('APPDATA', user_dir) # Use %APPDATA% for roaming
default_storage_dir = os.path.join(user_dir, 'pip')
default_config_file = os.path.join(default_storage_dir, 'pip.ini')
default_log_file = os.path.join(default_storage_dir, 'pip.log')
else:
bin_py = os.path.join(sys.prefix, 'bin')
default_storage_dir = os.path.join(user_dir, '.pip')
default_config_file = os.path.join(default_storage_dir, 'pip.conf')
default_log_file = os.path.join(default_storage_dir, 'pip.log')
# Forcing to use /usr/local/bin for standard Mac OS X framework installs
# Also log to ~/Library/Logs/ for use with the Console.app log viewer
if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/':
bin_py = '/usr/local/bin'
default_log_file = os.path.join(user_dir, 'Library/Logs/pip.log')
-2
View File
@@ -1,2 +0,0 @@
[nosetests]
where=tests
-55
View File
@@ -1,55 +0,0 @@
import sys
import os
from setuptools import setup
# If you change this version, change it also in docs/conf.py
version = "1.1"
doc_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "docs")
index_filename = os.path.join(doc_dir, "index.txt")
news_filename = os.path.join(doc_dir, "news.txt")
long_description = """
The main website for pip is `www.pip-installer.org
<http://www.pip-installer.org>`_. You can also install
the `in-development version <https://github.com/pypa/pip/tarball/develop#egg=pip-dev>`_
of pip with ``easy_install pip==dev``.
"""
f = open(index_filename)
# remove the toctree from sphinx index, as it breaks long_description
parts = f.read().split("split here", 2)
long_description = parts[0] + long_description + parts[2]
f.close()
f = open(news_filename)
long_description += "\n\n" + f.read()
f.close()
setup(name="pip",
version=version,
description="pip installs packages. Python packages. An easy_install replacement",
long_description=long_description,
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Topic :: Software Development :: Build Tools',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.4',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2',
],
keywords='easy_install distutils setuptools egg virtualenv',
author='The pip developers',
author_email='python-virtualenv@groups.google.com',
url='http://www.pip-installer.org',
license='MIT',
packages=['pip', 'pip.commands', 'pip.vcs'],
entry_points=dict(console_scripts=['pip=pip:main', 'pip-%s=pip:main' % sys.version[:3]]),
test_suite='nose.collector',
tests_require=['nose', 'virtualenv>=1.7', 'scripttest>=1.1.1', 'mock'],
zip_safe=False)
Binary file not shown.
-3
View File
@@ -1,3 +0,0 @@
<html><head><title>Links for FSPkg</title></head><body><h1>Links for FSPkg</h1><a href="./FSPkg-0.1dev.tar.gz#md5=ba6e46bed32c5b6d20f974d7d889bdb2">FSPkg-0.1dev.tar.gz</a><br/>
<a href="file://../../packages/FSPkg">Source</a><br/>
</body></html>
-2
View File
@@ -1,2 +0,0 @@
This directory has the odd space in its name in order to test urlquoting and
dequoting of file:// scheme index URLs.
-75
View File
@@ -1,75 +0,0 @@
import os
import subprocess
from pip.vcs import subversion, git, bazaar, mercurial
from pip.backwardcompat import urlretrieve
from tests.test_pip import path_to_url
from tests.pypi_server import PyPIProxy
if hasattr(subprocess, "check_call"):
subprocess_call = subprocess.check_call
else:
subprocess_call = subprocess.call
def _create_initools_repository():
subprocess_call('svnadmin create INITools'.split(), cwd=_get_vcs_folder())
def _dump_initools_repository():
filename, _ = urlretrieve('http://bitbucket.org/hltbra/pip-initools-dump/raw/8b55c908a320/INITools_modified.dump')
initools_folder = os.path.join(_get_vcs_folder(), 'INITools')
devnull = open(os.devnull, 'w')
dump = open(filename)
subprocess_call(['svnadmin', 'load', initools_folder], stdin=dump, stdout=devnull)
dump.close()
devnull.close()
os.remove(filename)
def _create_svn_repository_for_initools():
tests_cache = _get_vcs_folder()
if not os.path.exists(os.path.join(tests_cache, 'INITools')):
_create_initools_repository()
_dump_initools_repository()
def _get_vcs_folder():
folder_name = PyPIProxy.CACHE_PATH
if not os.path.exists(folder_name):
os.mkdir(folder_name)
return folder_name
def _get_vcs_and_checkout_url(remote_repository):
tests_cache = _get_vcs_folder()
vcs_classes = {'svn': subversion.Subversion,
'git': git.Git,
'bzr': bazaar.Bazaar,
'hg': mercurial.Mercurial}
default_vcs = 'svn'
if '+' not in remote_repository:
remote_repository = '%s+%s' % (default_vcs, remote_repository)
vcs, repository_path = remote_repository.split('+', 1)
vcs_class = vcs_classes[vcs]
branch = ''
if vcs == 'svn':
branch = os.path.basename(remote_repository)
repository_name = os.path.basename(remote_repository[:-len(branch)-1]) # remove the slash
else:
repository_name = os.path.basename(remote_repository)
destination_path = os.path.join(tests_cache, repository_name)
if not os.path.exists(destination_path):
vcs_class(remote_repository).obtain(destination_path)
return '%s+%s' % (vcs, path_to_url('/'.join([tests_cache, repository_name, branch])))
def local_checkout(remote_repo):
if remote_repo.startswith('svn'):
_create_svn_repository_for_initools()
return _get_vcs_and_checkout_url(remote_repo)
def local_repo(remote_repo):
return local_checkout(remote_repo).split('+', 1)[1]
@@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
from distutils.core import setup
import sys
class FakeError(Exception):
pass
if sys.argv[1] == 'install':
if hasattr(sys.stdout, 'buffer'):
sys.stdout.buffer.write('\nThis package prints out UTF-8 stuff like:\n'.encode('utf-8'))
sys.stdout.buffer.write('* return type of main is not int\n'.encode('utf-8'))
sys.stdout.buffer.write('* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]'.encode('utf-8'))
else:
pass
sys.stdout.write('\nThis package prints out UTF-8 stuff like:\n')
sys.stdout.write('* return type of \xe2\x80\x98main\xe2\x80\x99 is not \xe2\x80\x98int\xe2\x80\x99\n')
sys.stdout.write('* Bj\xc3\xb6rk Gu\xc3\xb0mundsd\xc3\xb3ttir [\xcb\x88pj\xc5\x93r\xcc\xa5k \xcb\x88kv\xca\x8f\xc3\xb0m\xca\x8fnts\xcb\x8cto\xca\x8aht\xc9\xaar]\n')
raise FakeError('this package designed to fail on install')
setup(name='broken',
version='0.2broken',
py_modules=['broken'],
)
@@ -1 +0,0 @@
#
-3
View File
@@ -1,3 +0,0 @@
[egg_info]
tag_build = dev
tag_svn_revision = true
-25
View File
@@ -1,25 +0,0 @@
from setuptools import setup, find_packages
version = '0.1'
setup(name='FSPkg',
version=version,
description="File system test package",
long_description="""\
File system test package""",
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
keywords='pip tests',
author='pip',
author_email='pip@openplans.org',
url='http://pip.openplans.org',
license='',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
include_package_data=True,
zip_safe=False,
install_requires=[
# -*- Extra requirements: -*-
],
entry_points="""
# -*- Entry points: -*-
""",
)
-3
View File
@@ -1,3 +0,0 @@
from distutils.core import setup
setup()
-6
View File
@@ -1,6 +0,0 @@
This package exists for testing uninstall-rollback.
Version 0.2broken has a setup.py crafted to fail on install (and only on
install). If any earlier step would fail (i.e. egg-info-generation), the
already-installed version would never be uninstalled, so uninstall-rollback
would not come into play.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-209
View File
@@ -1,209 +0,0 @@
# -*- coding: utf-8 -*-
# Author: Aziz Köksal
import os
import sys
import shutil
if sys.version_info >= (3,):
unicode = str
u = str
else:
unicode = unicode
u = lambda s: s.decode('utf-8')
_base = os.path.supports_unicode_filenames and unicode or str
from pip.util import rmtree
class Path(_base):
""" Models a path in an object oriented way. """
sep = os.sep # File system path separator: '/' or '\'.
pathsep = os.pathsep # Separator in the PATH environment variable.
string = _base
def __new__(cls, *paths):
if len(paths):
return _base.__new__(cls, os.path.join(*paths))
return _base.__new__(cls)
def __div__(self, path):
""" Joins this path with another path. """
""" path_obj / 'bc.d' """
""" path_obj / path_obj2 """
return Path(self, path)
__truediv__ = __div__
def __rdiv__(self, path):
""" Joins this path with another path. """
""" "/home/a" / path_obj """
return Path(path, self)
__rtruediv__ = __rdiv__
def __idiv__(self, path):
""" Like __div__ but also assigns to the variable. """
""" path_obj /= 'bc.d' """
return Path(self, path)
__itruediv__ = __idiv__
def __floordiv__(self, paths):
""" Returns a list of paths prefixed with 'self'. """
""" '/home/a' // [bc.d, ef.g] -> [/home/a/bc.d, /home/a/ef.g] """
return [Path(self, path) for path in paths]
def __sub__(self, path):
""" Makes this path relative to another path. """
""" path_obj - '/home/a' """
""" path_obj - path_obj2 """
return Path(os.path.relpath(self, path))
def __rsub__(self, path):
""" Returns path relative to this path. """
""" "/home/a" - path_obj """
return Path(os.path.relpath(path, self))
def __add__(self, path):
""" Path('/home/a') + 'bc.d' -> '/home/abc.d' """
return Path(_base(self) + path)
def __radd__(self, path):
""" '/home/a' + Path('bc.d') -> '/home/abc.d' """
return Path(path + _base(self))
def __repr__(self):
return u("Path(%s)" % _base.__repr__(self))
def __hash__(self):
return _base.__hash__(self)
@property
def name(self):
""" '/home/a/bc.d' -> 'bc.d' """
return os.path.basename(self)
@property
def namebase(self):
""" '/home/a/bc.d' -> 'bc' """
return self.noext.name
@property
def noext(self):
""" '/home/a/bc.d' -> '/home/a/bc' """
return Path(os.path.splitext(self)[0])
@property
def ext(self):
""" '/home/a/bc.d' -> '.d' """
return Path(os.path.splitext(self)[1])
@property
def abspath(self):
""" './a/bc.d' -> '/home/a/bc.d' """
return Path(os.path.abspath(self))
@property
def realpath(self):
""" Resolves symbolic links. """
return Path(os.path.realpath(self))
@property
def normpath(self):
""" '/home/x/.././a//bc.d' -> '/home/a/bc.d' """
return Path(os.path.normpath(self))
@property
def normcase(self):
""" Deals with case-insensitive filesystems """
return Path(os.path.normcase(self))
@property
def folder(self):
""" Returns the folder of this path. """
""" '/home/a/bc.d' -> '/home/a' """
""" '/home/a/' -> '/home/a' """
""" '/home/a' -> '/home' """
return Path(os.path.dirname(self))
@property
def exists(self):
""" Returns True if the path exists. """
return os.path.exists(self)
@property
def atime(self):
""" Returns last accessed time. """
return os.path.getatime(self)
@property
def mtime(self):
""" Returns last modified time. """
return os.path.getmtime(self)
@property
def ctime(self):
""" Returns last changed time. """
return os.path.getctime(self)
@classmethod
def supports_unicode(self):
""" Returns True if the system can handle Unicode file names. """
return os.path.supports_unicode_filenames()
def walk(self, **kwargs):
""" Returns a generator that walks through a directory tree. """
if "followlinks" in kwargs:
from sys import version_info as vi
if vi[0]*10+vi[1] < 26: # Only Python 2.6 or newer supports followlinks
del kwargs["followlinks"]
return os.walk(self, **kwargs)
def mkdir(self, mode=0x1FF): # 0o777
""" Creates a directory, if it doesn't exist already. """
if not self.exists:
os.mkdir(self, mode)
def makedirs(self, mode=0x1FF): # 0o777
""" Like mkdir(), but also creates parent directories. """
if not self.exists:
os.makedirs(self, mode)
def remove(self):
""" Removes a file. """
os.remove(self)
rm = remove # Alias.
def rmdir(self):
""" Removes a directory. """
return os.rmdir(self)
def rmtree(self, noerrors=True):
""" Removes a directory tree. Ignores errors by default. """
return rmtree(self, ignore_errors=noerrors)
def copy(self, to):
shutil.copy(self, to)
def copytree(self, to):
""" Copies a directory tree to another path. """
shutil.copytree(self, to)
def move(self, to):
""" Moves a file or directory to another path. """
shutil.move(self, to)
def rename(self, to):
""" Renames a file or directory. May throw an OSError. """
os.rename(self, to)
def renames(self, to):
os.renames(self, to)
def glob(self, pattern):
from glob import glob
return list(map(Path, glob(_base(self/pattern))))
curdir = Path(os.path.curdir)
-129
View File
@@ -1,129 +0,0 @@
import os
import pip.backwardcompat
from pip.backwardcompat import urllib, string_types, b, u, emailmessage
urlopen_original = pip.backwardcompat.urllib2.urlopen
class CachedResponse(object):
"""
CachedResponse always cache url access and returns the cached response.
It returns an object compatible with ``urllib.addinfourl``,
it means the object is like the result of a call like::
>>> response = urllib2.urlopen('http://example.com')
"""
def __init__(self, url, folder):
self.headers = emailmessage.Message()
self.code = 500
self.msg = 'Internal Server Error'
# url can be a simple string, or a urllib2.Request object
if isinstance(url, string_types):
self.url = url
else:
self.url = url.get_full_url()
for key, value in url.headers.items():
self.headers[key] = value
self._body = b('')
self._set_all_fields(folder)
def _set_all_fields(self, folder):
filename = os.path.join(folder, urllib.quote(self.url, ''))
if not os.path.exists(filename):
self._cache_url(filename)
fp = open(filename, 'rb')
try:
line = fp.readline().strip()
self.code, self.msg = line.split(None, 1)
except ValueError:
raise ValueError('Bad field line: %r' % line)
self.code = int(self.code)
self.msg = u(self.msg)
for line in fp:
if line == b('\n'):
break
key, value = line.split(b(': '), 1)
self.headers[u(key)] = u(value.strip())
for line in fp:
self._body += line
fp.close()
def getcode(self):
return self.code
def geturl(self):
return self.url
def info(self):
return self.headers
def read(self, bytes=None):
"""
it can read a chunk of bytes or everything
"""
if bytes:
result = self._body[:bytes]
self._body = self._body[bytes:]
return result
return self._body
def close(self):
pass
def _cache_url(self, filepath):
response = urlopen_original(self.url)
fp = open(filepath, 'wb')
# when it uses file:// scheme, code is None and there is no msg attr
# but it has been successfully opened
status = b('%s %s' % (getattr(response, 'code', 200) or 200, getattr(response, 'msg', 'OK')))
headers = [b('%s: %s' % (key, value)) for key, value in list(response.headers.items())]
body = response.read()
fp.write(b('\n').join([status] + headers + [b(''), body]))
fp.close()
class PyPIProxy(object):
CACHE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "tests_cache")
@classmethod
def setup(cls):
instance = cls()
instance._create_cache_folder()
instance._monkey_patch_urllib2_to_cache_everything()
def _monkey_patch_urllib2_to_cache_everything(self):
def urlopen(url):
return CachedResponse(url, self.CACHE_PATH)
pip.backwardcompat.urllib2.urlopen = urlopen
def _create_cache_folder(self):
if not os.path.exists(self.CACHE_PATH):
os.mkdir(self.CACHE_PATH)
def assert_equal(a, b):
assert a == b, "\nexpected:\n%r\ngot:\n%r" % (b, a)
def test_cache_proxy():
url = 'http://example.com'
here = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(here, urllib.quote(url, ''))
if os.path.exists(filepath):
os.remove(filepath)
response = pip.backwardcompat.urllib2.urlopen(url)
r = CachedResponse(url, here)
try:
assert_equal(r.code, response.code)
assert_equal(r.msg, response.msg)
assert_equal(r.read(), response.read())
assert_equal(r.url, response.url)
assert_equal(r.geturl(), response.geturl())
assert_equal(set(r.headers.keys()), set(response.headers.keys()))
assert_equal(set(r.info().keys()), set(response.info().keys()))
assert_equal(r.headers['content-length'], response.headers['content-length'])
finally:
os.remove(filepath)

Some files were not shown because too many files have changed in this diff Show More