Commit 78f01306 authored by Philip Thiem's avatar Philip Thiem

Merge with default

--HG--
extra : rebase_source : d9c70d5bebd4290f568c828c5bc3a9b93a817ff2
parents 30bb58f0 49ce8061
......@@ -87,3 +87,16 @@ e3d70539e79f39a97f69674ab038661961a1eb43 0.8
1aef141fc968113e4c521d1edf6ea863c4ff7e00 0.9.4
88e3d6788facbb2dd6467a23c4f35529a5ce20a1 0.9.5
acc6c5d61d0f82040c237ac7ea010c0fc9e67d66 0.9.6
19965a03c1d5231c894e0fabfaf45af1fd99f484 0.9.7
e0a6e225ad6b28471cd42cfede6e8a334bb548fb 0.9.8
7b91ff93a30ef78634b7bb34f4a6229a5de281ee 1.0b1
aba16323ec9382da7bc77c633990ccb3bd58d050 1.0b2
8a98492f0d852402c93ddbbf3f07081909a9105f 1.0b3
c385fdf1f976fb1d2a6accc9292d8eca419180fa 1.0
d943b67fe80dbd61326014e4acedfc488adfa1c9 1.1
2e42e86546100c9f6845b04eb31b75c5add05f78 1.1.1
462fe5ccd8befeb2a235e8295d6d73eb3a49cc78 1.1.2
ddf3561d6a54087745f4bf6ea2048b86195d6fe2 1.1.3
f94c7e4fa03077e069c1c3cef93ead735559e706 1.1.4
d9bb58331007ee3f69d31983a180f56b15c731c3 1.1.5
5e426bdeb46b87e299422adc419f4163b6c78d13 1.1.6
......@@ -5,5 +5,6 @@ python:
- 2.7
- 3.2
- 3.3
- pypy
# command to run tests
script: python setup.py test
......@@ -2,6 +2,116 @@
CHANGES
=======
-----
1.1.7
-----
* Fixed behavior of NameError handling in 'script template (dev).py' (script
launcher for 'develop' installs).
* ``ez_setup.py`` now ensures partial downloads are cleaned up following
a failed download.
-----
1.1.6
-----
* Distribute #349: ``sandbox.execfile`` now opens the target file in binary
mode, thus honoring a BOM in the file when compiled.
-----
1.1.5
-----
* Issue #69: Second attempt at fix (logic was reversed).
-----
1.1.4
-----
* Issue #77: Fix error in upload command (Python 2.4).
-----
1.1.3
-----
* Fix NameError in previous patch.
-----
1.1.2
-----
* Issue #69: Correct issue where 404 errors are returned for URLs with
fragments in them (such as #egg=).
-----
1.1.1
-----
* Issue #75: Add ``--insecure`` option to ez_setup.py to accommodate
environments where a trusted SSL connection cannot be validated.
* Issue #76: Fix AttributeError in upload command with Python 2.4.
---
1.1
---
* Issue #71 (Distribute #333): EasyInstall now puts less emphasis on the
condition when a host is blocked via ``--allow-hosts``.
* Issue #72: Restored Python 2.4 compatibility in ``ez_setup.py``.
---
1.0
---
* Issue #60: On Windows, Setuptools supports deferring to another launcher,
such as Vinay Sajip's `pylauncher <https://bitbucket.org/pypa/pylauncher>`_
(included with Python 3.3) to launch console and GUI scripts and not install
its own launcher executables. This experimental functionality is currently
only enabled if the ``SETUPTOOLS_LAUNCHER`` environment variable is set to
"natural". In the future, this behavior may become default, but only after
it has matured and seen substantial adoption. The ``SETUPTOOLS_LAUNCHER``
also accepts "executable" to force the default behavior of creating launcher
executables.
* Issue #63: Bootstrap script (ez_setup.py) now prefers Powershell, curl, or
wget for retrieving the Setuptools tarball for improved security of the
install. The script will still fall back to a simple ``urlopen`` on
platforms that do not have these tools.
* Issue #65: Deprecated the ``Features`` functionality.
* Issue #52: In ``VerifyingHTTPSConn``, handle a tunnelled (proxied)
connection.
Backward-Incompatible Changes
=============================
This release includes a couple of backward-incompatible changes, but most if
not all users will find 1.0 a drop-in replacement for 0.9.
* Issue #50: Normalized API of environment marker support. Specifically,
removed line number and filename from SyntaxErrors when returned from
`pkg_resources.invalid_marker`. Any clients depending on the specific
string representation of exceptions returned by that function may need to
be updated to account for this change.
* Issue #50: SyntaxErrors generated by `pkg_resources.invalid_marker` are
normalized for cross-implementation consistency.
* Removed ``--ignore-conflicts-at-my-risk`` and ``--delete-conflicting``
options to easy_install. These options have been deprecated since 0.6a11.
-----
0.9.8
-----
* Issue #53: Fix NameErrors in `_vcs_split_rev_from_url`.
-----
0.9.7
-----
* Issue #49: Correct AttributeError on PyPy where a hashlib.HASH object does
not have a `.name` attribute.
* Issue #34: Documentation now refers to bootstrap script in code repository
referenced by bookmark.
* Add underscore-separated keys to environment markers (markerlib).
-----
0.9.6
-----
......@@ -739,3 +849,588 @@ easy_install
* Immediately close all file handles. This closes Distribute #3.
-----
0.6c9
-----
* Fixed a missing files problem when using Windows source distributions on
non-Windows platforms, due to distutils not handling manifest file line
endings correctly.
* Updated Pyrex support to work with Pyrex 0.9.6 and higher.
* Minor changes for Jython compatibility, including skipping tests that can't
work on Jython.
* Fixed not installing eggs in ``install_requires`` if they were also used for
``setup_requires`` or ``tests_require``.
* Fixed not fetching eggs in ``install_requires`` when running tests.
* Allow ``ez_setup.use_setuptools()`` to upgrade existing setuptools
installations when called from a standalone ``setup.py``.
* Added a warning if a namespace package is declared, but its parent package
is not also declared as a namespace.
* Support Subversion 1.5
* Removed use of deprecated ``md5`` module if ``hashlib`` is available
* Fixed ``bdist_wininst upload`` trying to upload the ``.exe`` twice
* Fixed ``bdist_egg`` putting a ``native_libs.txt`` in the source package's
``.egg-info``, when it should only be in the built egg's ``EGG-INFO``.
* Ensure that _full_name is set on all shared libs before extensions are
checked for shared lib usage. (Fixes a bug in the experimental shared
library build support.)
* Fix to allow unpacked eggs containing native libraries to fail more
gracefully under Google App Engine (with an ``ImportError`` loading the
C-based module, instead of getting a ``NameError``).
-----
0.6c7
-----
* Fixed ``distutils.filelist.findall()`` crashing on broken symlinks, and
``egg_info`` command failing on new, uncommitted SVN directories.
* Fix import problems with nested namespace packages installed via
``--root`` or ``--single-version-externally-managed``, due to the
parent package not having the child package as an attribute.
-----
0.6c6
-----
* Added ``--egg-path`` option to ``develop`` command, allowing you to force
``.egg-link`` files to use relative paths (allowing them to be shared across
platforms on a networked drive).
* Fix not building binary RPMs correctly.
* Fix "eggsecutables" (such as setuptools' own egg) only being runnable with
bash-compatible shells.
* Fix ``#!`` parsing problems in Windows ``.exe`` script wrappers, when there
was whitespace inside a quoted argument or at the end of the ``#!`` line
(a regression introduced in 0.6c4).
* Fix ``test`` command possibly failing if an older version of the project
being tested was installed on ``sys.path`` ahead of the test source
directory.
* Fix ``find_packages()`` treating ``ez_setup`` and directories with ``.`` in
their names as packages.
-----
0.6c5
-----
* Fix uploaded ``bdist_rpm`` packages being described as ``bdist_egg``
packages under Python versions less than 2.5.
* Fix uploaded ``bdist_wininst`` packages being described as suitable for
"any" version by Python 2.5, even if a ``--target-version`` was specified.
-----
0.6c4
-----
* Overhauled Windows script wrapping to support ``bdist_wininst`` better.
Scripts installed with ``bdist_wininst`` will always use ``#!python.exe`` or
``#!pythonw.exe`` as the executable name (even when built on non-Windows
platforms!), and the wrappers will look for the executable in the script's
parent directory (which should find the right version of Python).
* Fix ``upload`` command not uploading files built by ``bdist_rpm`` or
``bdist_wininst`` under Python 2.3 and 2.4.
* Add support for "eggsecutable" headers: a ``#!/bin/sh`` script that is
prepended to an ``.egg`` file to allow it to be run as a script on Unix-ish
platforms. (This is mainly so that setuptools itself can have a single-file
installer on Unix, without doing multiple downloads, dealing with firewalls,
etc.)
* Fix problem with empty revision numbers in Subversion 1.4 ``entries`` files
* Use cross-platform relative paths in ``easy-install.pth`` when doing
``develop`` and the source directory is a subdirectory of the installation
target directory.
* Fix a problem installing eggs with a system packaging tool if the project
contained an implicit namespace package; for example if the ``setup()``
listed a namespace package ``foo.bar`` without explicitly listing ``foo``
as a namespace package.
-----
0.6c3
-----
* Fixed breakages caused by Subversion 1.4's new "working copy" format
-----
0.6c2
-----
* The ``ez_setup`` module displays the conflicting version of setuptools (and
its installation location) when a script requests a version that's not
available.
* Running ``setup.py develop`` on a setuptools-using project will now install
setuptools if needed, instead of only downloading the egg.
-----
0.6c1
-----
* Fixed ``AttributeError`` when trying to download a ``setup_requires``
dependency when a distribution lacks a ``dependency_links`` setting.
* Made ``zip-safe`` and ``not-zip-safe`` flag files contain a single byte, so
as to play better with packaging tools that complain about zero-length
files.
* Made ``setup.py develop`` respect the ``--no-deps`` option, which it
previously was ignoring.
* Support ``extra_path`` option to ``setup()`` when ``install`` is run in
backward-compatibility mode.
* Source distributions now always include a ``setup.cfg`` file that explicitly
sets ``egg_info`` options such that they produce an identical version number
to the source distribution's version number. (Previously, the default
version number could be different due to the use of ``--tag-date``, or if
the version was overridden on the command line that built the source
distribution.)
-----
0.6b4
-----
* Fix ``register`` not obeying name/version set by ``egg_info`` command, if
``egg_info`` wasn't explicitly run first on the same command line.
* Added ``--no-date`` and ``--no-svn-revision`` options to ``egg_info``
command, to allow suppressing tags configured in ``setup.cfg``.
* Fixed redundant warnings about missing ``README`` file(s); it should now
appear only if you are actually a source distribution.
-----
0.6b3
-----
* Fix ``bdist_egg`` not including files in subdirectories of ``.egg-info``.
* Allow ``.py`` files found by the ``include_package_data`` option to be
automatically included. Remove duplicate data file matches if both
``include_package_data`` and ``package_data`` are used to refer to the same
files.
-----
0.6b1
-----
* Strip ``module`` from the end of compiled extension modules when computing
the name of a ``.py`` loader/wrapper. (Python's import machinery ignores
this suffix when searching for an extension module.)
------
0.6a11
------
* Added ``test_loader`` keyword to support custom test loaders
* Added ``setuptools.file_finders`` entry point group to allow implementing
revision control plugins.
* Added ``--identity`` option to ``upload`` command.
* Added ``dependency_links`` to allow specifying URLs for ``--find-links``.
* Enhanced test loader to scan packages as well as modules, and call
``additional_tests()`` if present to get non-unittest tests.
* Support namespace packages in conjunction with system packagers, by omitting
the installation of any ``__init__.py`` files for namespace packages, and
adding a special ``.pth`` file to create a working package in
``sys.modules``.
* Made ``--single-version-externally-managed`` automatic when ``--root`` is
used, so that most system packagers won't require special support for
setuptools.
* Fixed ``setup_requires``, ``tests_require``, etc. not using ``setup.cfg`` or
other configuration files for their option defaults when installing, and
also made the install use ``--multi-version`` mode so that the project
directory doesn't need to support .pth files.
* ``MANIFEST.in`` is now forcibly closed when any errors occur while reading
it. Previously, the file could be left open and the actual error would be
masked by problems trying to remove the open file on Windows systems.
------
0.6a10
------
* Fixed the ``develop`` command ignoring ``--find-links``.
-----
0.6a9
-----
* The ``sdist`` command no longer uses the traditional ``MANIFEST`` file to
create source distributions. ``MANIFEST.in`` is still read and processed,
as are the standard defaults and pruning. But the manifest is built inside
the project's ``.egg-info`` directory as ``SOURCES.txt``, and it is rebuilt
every time the ``egg_info`` command is run.
* Added the ``include_package_data`` keyword to ``setup()``, allowing you to
automatically include any package data listed in revision control or
``MANIFEST.in``
* Added the ``exclude_package_data`` keyword to ``setup()``, allowing you to
trim back files included via the ``package_data`` and
``include_package_data`` options.
* Fixed ``--tag-svn-revision`` not working when run from a source
distribution.
* Added warning for namespace packages with missing ``declare_namespace()``
* Added ``tests_require`` keyword to ``setup()``, so that e.g. packages
requiring ``nose`` to run unit tests can make this dependency optional
unless the ``test`` command is run.
* Made all commands that use ``easy_install`` respect its configuration
options, as this was causing some problems with ``setup.py install``.
* Added an ``unpack_directory()`` driver to ``setuptools.archive_util``, so
that you can process a directory tree through a processing filter as if it
were a zipfile or tarfile.
* Added an internal ``install_egg_info`` command to use as part of old-style
``install`` operations, that installs an ``.egg-info`` directory with the
package.
* Added a ``--single-version-externally-managed`` option to the ``install``
command so that you can more easily wrap a "flat" egg in a system package.
* Enhanced ``bdist_rpm`` so that it installs single-version eggs that
don't rely on a ``.pth`` file. The ``--no-egg`` option has been removed,
since all RPMs are now built in a more backwards-compatible format.
* Support full roundtrip translation of eggs to and from ``bdist_wininst``
format. Running ``bdist_wininst`` on a setuptools-based package wraps the
egg in an .exe that will safely install it as an egg (i.e., with metadata
and entry-point wrapper scripts), and ``easy_install`` can turn the .exe
back into an ``.egg`` file or directory and install it as such.
-----
0.6a8
-----
* Fixed some problems building extensions when Pyrex was installed, especially
with Python 2.4 and/or packages using SWIG.
* Made ``develop`` command accept all the same options as ``easy_install``,
and use the ``easy_install`` command's configuration settings as defaults.
* Made ``egg_info --tag-svn-revision`` fall back to extracting the revision
number from ``PKG-INFO`` in case it is being run on a source distribution of
a snapshot taken from a Subversion-based project.
* Automatically detect ``.dll``, ``.so`` and ``.dylib`` files that are being
installed as data, adding them to ``native_libs.txt`` automatically.
* Fixed some problems with fresh checkouts of projects that don't include
``.egg-info/PKG-INFO`` under revision control and put the project's source
code directly in the project directory. If such a package had any
requirements that get processed before the ``egg_info`` command can be run,
the setup scripts would fail with a "Missing 'Version:' header and/or
PKG-INFO file" error, because the egg runtime interpreted the unbuilt
metadata in a directory on ``sys.path`` (i.e. the current directory) as
being a corrupted egg. Setuptools now monkeypatches the distribution
metadata cache to pretend that the egg has valid version information, until
it has a chance to make it actually be so (via the ``egg_info`` command).
-----
0.6a5
-----
* Fixed missing gui/cli .exe files in distribution. Fixed bugs in tests.
-----
0.6a3
-----
* Added ``gui_scripts`` entry point group to allow installing GUI scripts
on Windows and other platforms. (The special handling is only for Windows;
other platforms are treated the same as for ``console_scripts``.)
-----
0.6a2
-----
* Added ``console_scripts`` entry point group to allow installing scripts
without the need to create separate script files. On Windows, console
scripts get an ``.exe`` wrapper so you can just type their name. On other
platforms, the scripts are written without a file extension.
-----
0.6a1
-----
* Added support for building "old-style" RPMs that don't install an egg for
the target package, using a ``--no-egg`` option.
* The ``build_ext`` command now works better when using the ``--inplace``
option and multiple Python versions. It now makes sure that all extensions
match the current Python version, even if newer copies were built for a
different Python version.
* The ``upload`` command no longer attaches an extra ``.zip`` when uploading
eggs, as PyPI now supports egg uploads without trickery.
* The ``ez_setup`` script/module now displays a warning before downloading
the setuptools egg, and attempts to check the downloaded egg against an
internal MD5 checksum table.
* Fixed the ``--tag-svn-revision`` option of ``egg_info`` not finding the
latest revision number; it was using the revision number of the directory
containing ``setup.py``, not the highest revision number in the project.
* Added ``eager_resources`` setup argument
* The ``sdist`` command now recognizes Subversion "deleted file" entries and
does not include them in source distributions.
* ``setuptools`` now embeds itself more thoroughly into the distutils, so that
other distutils extensions (e.g. py2exe, py2app) will subclass setuptools'
versions of things, rather than the native distutils ones.
* Added ``entry_points`` and ``setup_requires`` arguments to ``setup()``;
``setup_requires`` allows you to automatically find and download packages
that are needed in order to *build* your project (as opposed to running it).
* ``setuptools`` now finds its commands, ``setup()`` argument validators, and
metadata writers using entry points, so that they can be extended by
third-party packages. See `Creating distutils Extensions
<http://pythonhosted.org/setuptools/setuptools.html#creating-distutils-extensions>`_
for more details.
* The vestigial ``depends`` command has been removed. It was never finished
or documented, and never would have worked without EasyInstall - which it
pre-dated and was never compatible with.
------
0.5a12
------
* The zip-safety scanner now checks for modules that might be used with
``python -m``, and marks them as unsafe for zipping, since Python 2.4 can't
handle ``-m`` on zipped modules.
------
0.5a11
------
* Fix breakage of the "develop" command that was caused by the addition of
``--always-unzip`` to the ``easy_install`` command.
-----
0.5a9
-----
* Include ``svn:externals`` directories in source distributions as well as
normal subversion-controlled files and directories.
* Added ``exclude=patternlist`` option to ``setuptools.find_packages()``
* Changed --tag-svn-revision to include an "r" in front of the revision number
for better readability.
* Added ability to build eggs without including source files (except for any
scripts, of course), using the ``--exclude-source-files`` option to
``bdist_egg``.
* ``setup.py install`` now automatically detects when an "unmanaged" package
or module is going to be on ``sys.path`` ahead of a package being installed,
thereby preventing the newer version from being imported. If this occurs,
a warning message is output to ``sys.stderr``, but installation proceeds
anyway. The warning message informs the user what files or directories
need deleting, and advises them they can also use EasyInstall (with the
``--delete-conflicting`` option) to do it automatically.
* The ``egg_info`` command now adds a ``top_level.txt`` file to the metadata
directory that lists all top-level modules and packages in the distribution.
This is used by the ``easy_install`` command to find possibly-conflicting
"unmanaged" packages when installing the distribution.
* Added ``zip_safe`` and ``namespace_packages`` arguments to ``setup()``.
Added package analysis to determine zip-safety if the ``zip_safe`` flag
is not given, and advise the author regarding what code might need changing.
* Fixed the swapped ``-d`` and ``-b`` options of ``bdist_egg``.
-----
0.5a8
-----
* The "egg_info" command now always sets the distribution metadata to "safe"
forms of the distribution name and version, so that distribution files will
be generated with parseable names (i.e., ones that don't include '-' in the
name or version). Also, this means that if you use the various ``--tag``
options of "egg_info", any distributions generated will use the tags in the
version, not just egg distributions.
* Added support for defining command aliases in distutils configuration files,
under the "[aliases]" section. To prevent recursion and to allow aliases to
call the command of the same name, a given alias can be expanded only once
per command-line invocation. You can define new aliases with the "alias"
command, either for the local, global, or per-user configuration.
* Added "rotate" command to delete old distribution files, given a set of
patterns to match and the number of files to keep. (Keeps the most
recently-modified distribution files matching each pattern.)
* Added "saveopts" command that saves all command-line options for the current
invocation to the local, global, or per-user configuration file. Useful for
setting defaults without having to hand-edit a configuration file.
* Added a "setopt" command that sets a single option in a specified distutils
configuration file.
-----
0.5a7
-----
* Added "upload" support for egg and source distributions, including a bug
fix for "upload" and a temporary workaround for lack of .egg support in
PyPI.
-----
0.5a6
-----
* Beefed up the "sdist" command so that if you don't have a MANIFEST.in, it
will include all files under revision control (CVS or Subversion) in the
current directory, and it will regenerate the list every time you create a
source distribution, not just when you tell it to. This should make the
default "do what you mean" more often than the distutils' default behavior
did, while still retaining the old behavior in the presence of MANIFEST.in.
* Fixed the "develop" command always updating .pth files, even if you
specified ``-n`` or ``--dry-run``.
* Slightly changed the format of the generated version when you use
``--tag-build`` on the "egg_info" command, so that you can make tagged
revisions compare *lower* than the version specified in setup.py (e.g. by
using ``--tag-build=dev``).
-----
0.5a5
-----
* Added ``develop`` command to ``setuptools``-based packages. This command
installs an ``.egg-link`` pointing to the package's source directory, and
script wrappers that ``execfile()`` the source versions of the package's
scripts. This lets you put your development checkout(s) on sys.path without
having to actually install them. (To uninstall the link, use
use ``setup.py develop --uninstall``.)
* Added ``egg_info`` command to ``setuptools``-based packages. This command
just creates or updates the "projectname.egg-info" directory, without
building an egg. (It's used by the ``bdist_egg``, ``test``, and ``develop``
commands.)
* Enhanced the ``test`` command so that it doesn't install the package, but
instead builds any C extensions in-place, updates the ``.egg-info``
metadata, adds the source directory to ``sys.path``, and runs the tests
directly on the source. This avoids an "unmanaged" installation of the
package to ``site-packages`` or elsewhere.
* Made ``easy_install`` a standard ``setuptools`` command, moving it from
the ``easy_install`` module to ``setuptools.command.easy_install``. Note
that if you were importing or extending it, you must now change your imports
accordingly. ``easy_install.py`` is still installed as a script, but not as
a module.
-----
0.5a4
-----
* Setup scripts using setuptools can now list their dependencies directly in
the setup.py file, without having to manually create a ``depends.txt`` file.
The ``install_requires`` and ``extras_require`` arguments to ``setup()``
are used to create a dependencies file automatically. If you are manually
creating ``depends.txt`` right now, please switch to using these setup
arguments as soon as practical, because ``depends.txt`` support will be
removed in the 0.6 release cycle. For documentation on the new arguments,
see the ``setuptools.dist.Distribution`` class.
* Setup scripts using setuptools now always install using ``easy_install``
internally, for ease of uninstallation and upgrading.
-----
0.5a1
-----
* Added support for "self-installation" bootstrapping. Packages can now
include ``ez_setup.py`` in their source distribution, and add the following
to their ``setup.py``, in order to automatically bootstrap installation of
setuptools as part of their setup process::
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup
# etc...
-----
0.4a2
-----
* Added ``ez_setup.py`` installer/bootstrap script to make initial setuptools
installation easier, and to allow distributions using setuptools to avoid
having to include setuptools in their source distribution.
* All downloads are now managed by the ``PackageIndex`` class (which is now
subclassable and replaceable), so that embedders can more easily override
download logic, give download progress reports, etc. The class has also
been moved to the new ``setuptools.package_index`` module.
* The ``Installer`` class no longer handles downloading, manages a temporary
directory, or tracks the ``zip_ok`` option. Downloading is now handled
by ``PackageIndex``, and ``Installer`` has become an ``easy_install``
command class based on ``setuptools.Command``.
* There is a new ``setuptools.sandbox.run_setup()`` API to invoke a setup
script in a directory sandbox, and a new ``setuptools.archive_util`` module
with an ``unpack_archive()`` API. These were split out of EasyInstall to
allow reuse by other tools and applications.
* ``setuptools.Command`` now supports reinitializing commands using keyword
arguments to set/reset options. Also, ``Command`` subclasses can now set
their ``command_consumes_arguments`` attribute to ``True`` in order to
receive an ``args`` option containing the rest of the command line.
-----
0.3a2
-----
* Added new options to ``bdist_egg`` to allow tagging the egg's version number
with a subversion revision number, the current date, or an explicit tag
value. Run ``setup.py bdist_egg --help`` to get more information.
* Misc. bug fixes
-----
0.3a1
-----
* Initial release.
......@@ -21,6 +21,7 @@ Contributors
* Marc Abramowitz
* Martin von Löwis
* Noufal Ibrahim
* Pedro Algarvio
* Pete Hollobon
* Phillip J. Eby
* Philip Jenvey
......
......@@ -14,8 +14,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
import setuptools
import setup as setup_script
# 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
......@@ -49,9 +48,9 @@ copyright = '2009-2013, The fellowship of the packaging'
# built documents.
#
# The short X.Y version.
version = setuptools.__version__
version = setup_script.setup_params['version']
# The full version, including alpha/beta/rc tags.
release = setuptools.__version__
release = setup_script.setup_params['version']
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
-------------------------
Development on Setuptools
-------------------------
Setuptools is maintained by the Python community under the Python Packaging
Authority (PyPA) and led by Jason R. Coombs.
This document describes the process by which Setuptools is developed.
This document assumes the reader has some passing familiarity with
*using* setuptools, the ``pkg_resources`` module, and EasyInstall. It
does not attempt to explain basic concepts like inter-project
dependencies, nor does it contain detailed lexical syntax for most
file formats. Neither does it explain concepts like "namespace
packages" or "resources" in any detail, as all of these subjects are
covered at length in the setuptools developer's guide and the
``pkg_resources`` reference manual.
Instead, this is **internal** documentation for how those concepts and
features are *implemented* in concrete terms. It is intended for people
who are working on the setuptools code base, who want to be able to
troubleshoot setuptools problems, want to write code that reads the file
formats involved, or want to otherwise tinker with setuptools-generated
files and directories.
Note, however, that these are all internal implementation details and
are therefore subject to change; stick to the published API if you don't
want to be responsible for keeping your code from breaking when
setuptools changes. You have been warned.
.. toctree::
:maxdepth: 1
formats
releases
......@@ -35,9 +35,8 @@ Please see the `setuptools PyPI page <https://pypi.python.org/pypi/setuptools>`_
for download links and basic installation instructions for each of the
supported platforms.
You will need at least Python 2.3.5, or if you are on a 64-bit platform, Python
2.4. An ``easy_install`` script will be installed in the normal location for
Python scripts on your platform.
You will need at least Python 2.4. An ``easy_install`` script will be
installed in the normal location for Python scripts on your platform.
Note that the instructions on the setuptools PyPI page assume that you are
are installling to Python's primary ``site-packages`` directory. If this is
......@@ -77,25 +76,10 @@ section on `Custom Installation Locations`_ for more details.
Windows Notes
~~~~~~~~~~~~~
On Windows, an ``easy_install.exe`` launcher will also be installed, so that
you can just type ``easy_install`` as long as it's on your ``PATH``. If typing
``easy_install`` at the command prompt doesn't work, check to make sure your
``PATH`` includes the appropriate ``C:\\Python2X\\Scripts`` directory. On
most current versions of Windows, you can change the ``PATH`` by right-clicking
"My Computer", choosing "Properties" and selecting the "Advanced" tab, then
clicking the "Environment Variables" button. ``PATH`` will be in the "System
Variables" section, and you will need to exit and restart your command shell
(command.com, cmd.exe, bash, or other) for the change to take effect. Be sure
to add a ``;`` after the last item on ``PATH`` before adding the scripts
directory to it.
Note that instead of changing your ``PATH`` to include the Python scripts
directory, you can also retarget the installation location for scripts so they
go on a directory that's already on the ``PATH``. For more information see the
sections below on `Command-Line Options`_ and `Configuration Files`_. You
can pass command line options (such as ``--script-dir``) to
``ez_setup.py`` to control where ``easy_install.exe`` will be installed.
Installing setuptools will provide an ``easy_install`` command according to
the techniques described in `Executables and Launchers`_. If the
``easy_install`` command is not available after installation, that section
provides details on how to configure Windows to make the commands available.
Downloading and Installing a Package
......@@ -305,24 +289,80 @@ installations, so that Python won't lock us out of using anything but the most
recently-installed version of the package.)
Executables and Launchers
-------------------------
On Unix systems, scripts are installed with as natural files with a "#!"
header and no extension and they launch under the Python version indicated in
the header.
On Windows, there is no mechanism to "execute" files without extensions, so
EasyInstall provides two techniques to mirror the Unix behavior. The behavior
is indicated by the SETUPTOOLS_LAUNCHER environment variable, which may be
"executable" (default) or "natural".
Regardless of the technique used, the script(s) will be installed to a Scripts
directory (by default in the Python installation directory). It is recommended
for EasyInstall that you ensure this directory is in the PATH environment
variable. The easiest way to ensure the Scripts directory is in the PATH is
to run ``Tools\Scripts\win_add2path.py`` from the Python directory (requires
Python 2.6 or later).
Note that instead of changing your ``PATH`` to include the Python scripts
directory, you can also retarget the installation location for scripts so they
go on a directory that's already on the ``PATH``. For more information see
`Command-Line Options`_ and `Configuration Files`_. During installation,
pass command line options (such as ``--script-dir``) to
``ez_setup.py`` to control where ``easy_install.exe`` will be installed.
Windows Executable Launcher
~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the "executable" launcher is used, EasyInstall will create a '.exe'
launcher of the same name beside each installed script (including
``easy_install`` itself). These small .exe files launch the script of the
same name using the Python version indicated in the '#!' header.
This behavior is currently default. To force
the use of executable launchers, set ``SETUPTOOLS_LAUNCHER`` to "executable".
Natural Script Launcher
~~~~~~~~~~~~~~~~~~~~~~~
EasyInstall also supports deferring to an external launcher such as
`pylauncher <https://bitbucket.org/pypa/pylauncher>`_ for launching scripts.
Enable this experimental functionality by setting the
``SETUPTOOLS_LAUNCHER`` environment variable to "natural". EasyInstall will
then install scripts as simple
scripts with a .pya (or .pyw) extension appended. If these extensions are
associated with the pylauncher and listed in the PATHEXT environment variable,
these scripts can then be invoked simply and directly just like any other
executable. This behavior may become default in a future version.
EasyInstall uses the .pya extension instead of simply
the typical '.py' extension. This distinct extension is necessary to prevent
Python
from treating the scripts as importable modules (where name conflicts exist).
Current releases of pylauncher do not yet associate with .pya files by
default, but future versions should do so.
Tips & Techniques
-----------------
Multiple Python Versions
~~~~~~~~~~~~~~~~~~~~~~~~
As of version 0.6a11, EasyInstall installs itself under two names:
EasyInstall installs itself under two names:
``easy_install`` and ``easy_install-N.N``, where ``N.N`` is the Python version
used to install it. Thus, if you install EasyInstall for both Python 2.3 and
2.4, you can use the ``easy_install-2.3`` or ``easy_install-2.4`` scripts to
install packages for Python 2.3 or 2.4, respectively.
Also, if you're working with Python version 2.4 or higher, you can run Python
with ``-m easy_install`` to run that particular Python version's
``easy_install`` command.
used to install it. Thus, if you install EasyInstall for both Python 3.2 and
2.7, you can use the ``easy_install-3.2`` or ``easy_install-2.7`` scripts to
install packages for the respective Python version.
Setuptools also supplies easy_install as a runnable module which may be
invoked using ``python -m easy_install`` for any Python with Setuptools
installed.
Restricting Downloads with ``--allow-hosts``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......@@ -532,14 +572,12 @@ install``, becuase the ``distutils`` just install new packages on top of old
ones, possibly combining two unrelated packages or leaving behind modules that
have been deleted in the newer version of the package.)
By default, EasyInstall will stop the installation if it detects a conflict
EasyInstall will stop the installation if it detects a conflict
between an existing, "unmanaged" package, and a module or package in any of
the distributions you're installing. It will display a list of all of the
existing files and directories that would need to be deleted for the new
package to be able to function correctly. You can then either delete these
conflicting files and directories yourself and re-run EasyInstall, or you can
just use the ``--delete-conflicting`` or ``--ignore-conflicts-at-my-risk``
options, as described under `Command-Line Options`_, below.
package to be able to function correctly. To proceed, you must manually
delete these conflicting files and directories and re-run EasyInstall.
Of course, once you've replaced all of your existing "unmanaged" packages with
versions managed by EasyInstall, you won't have any more conflicts to worry
......@@ -783,27 +821,6 @@ Command-Line Options
Added in Distribute 0.6.11 and Setuptools 0.7.
``--delete-conflicting, -D`` (Removed in 0.6a11)
(As of 0.6a11, this option is no longer necessary; please do not use it!)
If you are replacing a package that was previously installed *without*
using EasyInstall, the old version may end up on ``sys.path`` before the
version being installed with EasyInstall. EasyInstall will normally abort
the installation of a package if it detects such a conflict, and ask you to
manually remove the conflicting files or directories. If you specify this
option, however, EasyInstall will attempt to delete the files or
directories itself, and then proceed with the installation.
``--ignore-conflicts-at-my-risk`` (Removed in 0.6a11)
(As of 0.6a11, this option is no longer necessary; please do not use it!)
Ignore conflicting packages and proceed with installation anyway, even
though it means the package probably won't work properly. If the
conflicting package is in a directory you can't write to, this may be your
only option, but you will need to take more invasive measures to get the
installed package to work, like manually adding it to ``PYTHONPATH`` or to
``sys.path`` at runtime.
``--index-url=URL, -i URL`` (New in 0.4a1; default changed in 0.6c7)
Specifies the base URL of the Python Package Index. The default is
https://pypi.python.org/simple if not specified. When a package is requested
......
......@@ -4,26 +4,6 @@ The Internal Structure of Python Eggs
STOP! This is not the first document you should read!
This document assumes you have at least some passing familiarity with
*using* setuptools, the ``pkg_resources`` module, and EasyInstall. It
does not attempt to explain basic concepts like inter-project
dependencies, nor does it contain detailed lexical syntax for most
file formats. Neither does it explain concepts like "namespace
packages" or "resources" in any detail, as all of these subjects are
covered at length in the setuptools developer's guide and the
``pkg_resources`` reference manual.
Instead, this is **internal** documentation for how those concepts and
features are *implemented* in concrete terms. It is intended for people
who are working on the setuptools code base, who want to be able to
troubleshoot setuptools problems, want to write code that reads the file
formats involved, or want to otherwise tinker with setuptools-generated
files and directories.
Note, however, that these are all internal implementation details and
are therefore subject to change; stick to the published API if you don't
want to be responsible for keeping your code from breaking when
setuptools changes. You have been warned.
.. contents:: **Table of Contents**
......
......@@ -23,3 +23,4 @@ Documentation content:
setuptools
easy_install
pkg_resources
development
......@@ -18,19 +18,31 @@ packages.
Overview
--------
Eggs are a distribution format for Python modules, similar in concept to Java's
"jars" or Ruby's "gems". They differ from previous Python distribution formats
in that they are importable (i.e. they can be added to ``sys.path``), and they
are *discoverable*, meaning that they carry metadata that unambiguously
identifies their contents and dependencies, and thus can be *automatically*
found and added to ``sys.path`` in response to simple requests of the form,
"get me everything I need to use docutils' PDF support".
The ``pkg_resources`` module provides runtime facilities for finding,
introspecting, activating and using eggs and other "pluggable" distribution
formats. Because these are new concepts in Python (and not that well-
established in other languages either), it helps to have a few special terms
for talking about eggs and how they can be used:
introspecting, activating and using installed Python distributions. Some
of the more advanced features (notably the support for parallel installation
of multiple versions) rely specifically on the "egg" format (either as a
zip archive or subdirectory), while others (such as plugin discovery) will
work correctly so long as "egg-info" metadata directories are available for
relevant distributions.
Eggs are a distribution format for Python modules, similar in concept to
Java's "jars" or Ruby's "gems", or the "wheel" format defined in PEP 427.
However, unlike a pure distribution format, eggs can also be installed and
added directly to ``sys.path`` as an import location. When installed in
this way, eggs are *discoverable*, meaning that they carry metadata that
unambiguously identifies their contents and dependencies. This means that
an installed egg can be *automatically* found and added to ``sys.path`` in
response to simple requests of the form, "get me everything I need to use
docutils' PDF support". This feature allows mutually conflicting versions of
a distribution to co-exist in the same Python installation, with individual
applications activating the desired version at runtime by manipulating the
contents of ``sys.path`` (this differs from the virtual environment
approach, which involves creating isolated environments for each
application).
The following terms are needed in order to explain the capabilities offered
by this module:
project
A library, framework, script, plugin, application, or collection of data
......@@ -79,9 +91,13 @@ eggs
with ``.egg`` and follows the egg naming conventions, and contain an
``EGG-INFO`` subdirectory (zipped or otherwise). Development eggs are
normal directories of Python code with one or more ``ProjectName.egg-info``
subdirectories. And egg links are ``*.egg-link`` files that contain the
name of a built or development egg, to support symbolic linking on
platforms that do not have native symbolic links.
subdirectories. The development egg format is also used to provide a
default version of a distribution that is available to software that
doesn't use ``pkg_resources`` to request specific versions. Egg links
are ``*.egg-link`` files that contain the name of a built or
development egg, to support symbolic linking on platforms that do not
have native symbolic links (or where the symbolic link support is
limited).
(For more information about these terms and concepts, see also this
`architectural overview`_ of ``pkg_resources`` and Python Eggs in general.)
......@@ -190,6 +206,17 @@ not provide any way to detect arbitrary changes to a list object like
is designed so that the ``working_set`` is used by default, such that you
don't have to explicitly refer to it most of the time.
All distributions available directly on ``sys.path`` will be activated
automatically when ``pkg_resources`` is imported. This behaviour can cause
version conflicts for applications which require non-default versions of
those distributions. To handle this situation, ``pkg_resources`` checks for a
``__requires__`` attribute in the ``__main__`` module when initializing the
default working set, and uses this to ensure a suitable version of each
affected distribution is activated. For example::
__requires__ = ["CherryPy < 3"] # Must be set before pkg_resources import
import pkg_resources
Basic ``WorkingSet`` Methods
----------------------------
......
===============
Release Process
===============
In order to allow for rapid, predictable releases, Setuptools uses a
mechanical technique for releases. The release script, ``release.py`` in the
repository, defines the details of the releases, and is executed by the
`jaraco.packaging <https://bitbucket.org/jaraco/jaraco.packaging>`_ release
module. The script does some checks (some interactive) and fully automates
the release process.
A Setuptools release manager must have maintainer access on PyPI to the
project and administrative access to the BitBucket project.
Release Managers
----------------
Currently, the project has one release manager, Jason R. Coombs.
......@@ -20,7 +20,7 @@ package from source and doesn't have a suitable version already installed.
Feature Highlights:
* Automatically find/download/install/upgrade dependencies at build time using
the `EasyInstall tool <http://peak.telecommunity.com/DevCenter/EasyInstall>`_,
the `EasyInstall tool <easy_install.html>`_,
which supports downloading via HTTP, FTP, Subversion, and SourceForge, and
automatically scans web pages linked from PyPI to find download links. (It's
the closest thing to CPAN currently available for Python.)
......@@ -72,7 +72,7 @@ is available from the `Python SVN sandbox`_, and in-development versions of the
.. contents:: **Table of Contents**
.. _distribute_setup.py: `bootstrap module`_
.. _ez_setup.py: `bootstrap module`_
-----------------
......@@ -88,14 +88,14 @@ current stable version of setuptools. In particular, be sure to read the
section on `Custom Installation Locations`_ if you are installing anywhere
other than Python's ``site-packages`` directory.
.. _EasyInstall Installation Instructions: http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions
.. _EasyInstall Installation Instructions: easy_install.html#installation-instructions
.. _Custom Installation Locations: http://peak.telecommunity.com/DevCenter/EasyInstall#custom-installation-locations
.. _Custom Installation Locations: easy_install.html#custom-installation-locations
If you want the current in-development version of setuptools, you should first
install a stable version, and then run::
distribute_setup.py setuptools==dev
ez_setup.py setuptools==dev
This will download and install the latest development (i.e. unstable) version
of setuptools from the Python Subversion sandbox.
......@@ -529,7 +529,7 @@ Python must be available via the ``PATH`` environment variable, under its
"long" name. That is, if the egg is built for Python 2.3, there must be a
``python2.3`` executable present in a directory on ``PATH``.
This feature is primarily intended to support distribute_setup the installation of
This feature is primarily intended to support ez_setup the installation of
setuptools itself on non-Windows platforms, but may also be useful for other
projects as well.
......@@ -652,7 +652,7 @@ A more complete example would be:
``vcs+proto://host/path@revision#egg=project-version``
Be careful with the version. It should match the one inside the project files.
If you want do disregard the version, you have to omit it both in the
If you want to disregard the version, you have to omit it both in the
``requires`` and in the URL's fragment.
This will do a checkout (or a clone, in Git and Mercurial parlance) to a
......@@ -713,10 +713,11 @@ declare it like this, so that the "PDF" requirements are only resolved if the
name="Project-A",
...
entry_points = {
'console_scripts':
['rst2pdf = project_a.tools.pdfgen [PDF]'],
['rst2html = project_a.tools.htmlgen'],
'console_scripts': [
'rst2pdf = project_a.tools.pdfgen [PDF]',
'rst2html = project_a.tools.htmlgen',
# more script entry points ...
],
}
)
......@@ -1147,20 +1148,20 @@ Using ``setuptools``... Without bundling it!
Your users might not have ``setuptools`` installed on their machines, or even
if they do, it might not be the right version. Fixing this is easy; just
download `distribute_setup.py`_, and put it in the same directory as your ``setup.py``
download `ez_setup.py`_, and put it in the same directory as your ``setup.py``
script. (Be sure to add it to your revision control system, too.) Then add
these two lines to the very top of your setup script, before the script imports
anything from setuptools:
.. code-block:: python
import distribute_setup
distribute_setup.use_setuptools()
import ez_setup
ez_setup.use_setuptools()
That's it. The ``distribute_setup`` module will automatically download a matching
That's it. The ``ez_setup`` module will automatically download a matching
version of ``setuptools`` from PyPI, if it isn't present on the target system.
Whenever you install an updated version of setuptools, you should also update
your projects' ``distribute_setup.py`` files, so that a matching version gets installed
your projects' ``ez_setup.py`` files, so that a matching version gets installed
on the target machine(s).
By the way, setuptools supports the new PyPI "upload" command, so you can use
......@@ -1190,7 +1191,7 @@ relevant to your project and your target audience isn't already familiar with
setuptools and ``easy_install``.
Network Access
If your project is using ``distribute_setup``, you should inform users of the
If your project is using ``ez_setup``, you should inform users of the
need to either have network access, or to preinstall the correct version of
setuptools using the `EasyInstall installation instructions`_. Those
instructions also have tips for dealing with firewalls as well as how to
......@@ -1266,45 +1267,6 @@ Creating System Packages
resolve the issue.
Managing Multiple Projects
--------------------------
If you're managing several projects that need to use ``distribute_setup``, and you
are using Subversion as your revision control system, you can use the
"svn:externals" property to share a single copy of ``distribute_setup`` between
projects, so that it will always be up-to-date whenever you check out or update
an individual project, without having to manually update each project to use
a new version.
However, because Subversion only supports using directories as externals, you
have to turn ``distribute_setup.py`` into ``distribute_setup/__init__.py`` in order
to do this, then create "externals" definitions that map the ``distribute_setup``
directory into each project. Also, if any of your projects use
``find_packages()`` on their setup directory, you will need to exclude the
resulting ``distribute_setup`` package, to keep it from being included in your
distributions, e.g.::
setup(
...
packages = find_packages(exclude=['distribute_setup']),
)
Of course, the ``distribute_setup`` package will still be included in your
packages' source distributions, as it needs to be.
For your convenience, you may use the following external definition, which will
track the latest version of setuptools::
ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
You can set this by executing this command in your project directory::
svn propedit svn:externals .
And then adding the line shown above to the file that comes up for editing.
Setting the ``zip_safe`` flag
-----------------------------
......@@ -1416,20 +1378,21 @@ other copies will ever be loaded!)
TRANSITIONAL NOTE
~~~~~~~~~~~~~~~~~
Setuptools 0.6a automatically calls ``declare_namespace()`` for you at runtime,
but the 0.7a versions will *not*. This is because the automatic declaration
Setuptools automatically calls ``declare_namespace()`` for you at runtime,
but future versions may *not*. This is because the automatic declaration
feature has some negative side effects, such as needing to import all namespace
packages during the initialization of the ``pkg_resources`` runtime, and also
the need for ``pkg_resources`` to be explicitly imported before any namespace
packages work at all. Beginning with the 0.7a releases, you'll be responsible
packages work at all. In some future releases, you'll be responsible
for including your own declaration lines, and the automatic declaration feature
will be dropped to get rid of the negative side effects.
During the remainder of the 0.6 development cycle, therefore, setuptools will
warn you about missing ``declare_namespace()`` calls in your ``__init__.py``
files, and you should correct these as soon as possible before setuptools 0.7a1
is released. Namespace packages without declaration lines will not work
correctly once a user has upgraded to setuptools 0.7a1, so it's important that
During the remainder of the current development cycle, therefore, setuptools
will warn you about missing ``declare_namespace()`` calls in your
``__init__.py`` files, and you should correct these as soon as possible
before the compatibility support is removed.
Namespace packages without declaration lines will not work
correctly once a user has upgraded to a later version, so it's important that
you make this change now in order to avoid having your code break in the field.
Our apologies for the inconvenience, and thank you for your patience.
......@@ -1984,7 +1947,7 @@ them in a ``[develop]`` section or on the command line.
============================================
This command runs the `EasyInstall tool
<http://peak.telecommunity.com/DevCenter/EasyInstall>`_ for you. It is exactly
<easy_install.html>`_ for you. It is exactly
equivalent to running the ``easy_install`` command. All command line arguments
following this command are consumed and not processed further by the distutils,
so this must be the last command listed on the command line. Please see
......@@ -2699,8 +2662,8 @@ XXX
Reusing ``setuptools`` Code
===========================
``distribute_setup``
--------------------
``ez_setup``
------------
XXX
......@@ -2722,500 +2685,6 @@ XXX
XXX
History
=======
0.6c9
* Fixed a missing files problem when using Windows source distributions on
non-Windows platforms, due to distutils not handling manifest file line
endings correctly.
* Updated Pyrex support to work with Pyrex 0.9.6 and higher.
* Minor changes for Jython compatibility, including skipping tests that can't
work on Jython.
* Fixed not installing eggs in ``install_requires`` if they were also used for
``setup_requires`` or ``tests_require``.
* Fixed not fetching eggs in ``install_requires`` when running tests.
* Allow ``ez_setup.use_setuptools()`` to upgrade existing setuptools
installations when called from a standalone ``setup.py``.
* Added a warning if a namespace package is declared, but its parent package
is not also declared as a namespace.
* Support Subversion 1.5
* Removed use of deprecated ``md5`` module if ``hashlib`` is available
* Fixed ``bdist_wininst upload`` trying to upload the ``.exe`` twice
* Fixed ``bdist_egg`` putting a ``native_libs.txt`` in the source package's
``.egg-info``, when it should only be in the built egg's ``EGG-INFO``.
* Ensure that _full_name is set on all shared libs before extensions are
checked for shared lib usage. (Fixes a bug in the experimental shared
library build support.)
* Fix to allow unpacked eggs containing native libraries to fail more
gracefully under Google App Engine (with an ``ImportError`` loading the
C-based module, instead of getting a ``NameError``).
0.6c7
* Fixed ``distutils.filelist.findall()`` crashing on broken symlinks, and
``egg_info`` command failing on new, uncommitted SVN directories.
* Fix import problems with nested namespace packages installed via
``--root`` or ``--single-version-externally-managed``, due to the
parent package not having the child package as an attribute.
0.6c6
* Added ``--egg-path`` option to ``develop`` command, allowing you to force
``.egg-link`` files to use relative paths (allowing them to be shared across
platforms on a networked drive).
* Fix not building binary RPMs correctly.
* Fix "eggsecutables" (such as setuptools' own egg) only being runnable with
bash-compatible shells.
* Fix ``#!`` parsing problems in Windows ``.exe`` script wrappers, when there
was whitespace inside a quoted argument or at the end of the ``#!`` line
(a regression introduced in 0.6c4).
* Fix ``test`` command possibly failing if an older version of the project
being tested was installed on ``sys.path`` ahead of the test source
directory.
* Fix ``find_packages()`` treating ``ez_setup`` and directories with ``.`` in
their names as packages.
0.6c5
* Fix uploaded ``bdist_rpm`` packages being described as ``bdist_egg``
packages under Python versions less than 2.5.
* Fix uploaded ``bdist_wininst`` packages being described as suitable for
"any" version by Python 2.5, even if a ``--target-version`` was specified.
0.6c4
* Overhauled Windows script wrapping to support ``bdist_wininst`` better.
Scripts installed with ``bdist_wininst`` will always use ``#!python.exe`` or
``#!pythonw.exe`` as the executable name (even when built on non-Windows
platforms!), and the wrappers will look for the executable in the script's
parent directory (which should find the right version of Python).
* Fix ``upload`` command not uploading files built by ``bdist_rpm`` or
``bdist_wininst`` under Python 2.3 and 2.4.
* Add support for "eggsecutable" headers: a ``#!/bin/sh`` script that is
prepended to an ``.egg`` file to allow it to be run as a script on Unix-ish
platforms. (This is mainly so that setuptools itself can have a single-file
installer on Unix, without doing multiple downloads, dealing with firewalls,
etc.)
* Fix problem with empty revision numbers in Subversion 1.4 ``entries`` files
* Use cross-platform relative paths in ``easy-install.pth`` when doing
``develop`` and the source directory is a subdirectory of the installation
target directory.
* Fix a problem installing eggs with a system packaging tool if the project
contained an implicit namespace package; for example if the ``setup()``
listed a namespace package ``foo.bar`` without explicitly listing ``foo``
as a namespace package.
0.6c3
* Fixed breakages caused by Subversion 1.4's new "working copy" format
0.6c2
* The ``ez_setup`` module displays the conflicting version of setuptools (and
its installation location) when a script requests a version that's not
available.
* Running ``setup.py develop`` on a setuptools-using project will now install
setuptools if needed, instead of only downloading the egg.
0.6c1
* Fixed ``AttributeError`` when trying to download a ``setup_requires``
dependency when a distribution lacks a ``dependency_links`` setting.
* Made ``zip-safe`` and ``not-zip-safe`` flag files contain a single byte, so
as to play better with packaging tools that complain about zero-length
files.
* Made ``setup.py develop`` respect the ``--no-deps`` option, which it
previously was ignoring.
* Support ``extra_path`` option to ``setup()`` when ``install`` is run in
backward-compatibility mode.
* Source distributions now always include a ``setup.cfg`` file that explicitly
sets ``egg_info`` options such that they produce an identical version number
to the source distribution's version number. (Previously, the default
version number could be different due to the use of ``--tag-date``, or if
the version was overridden on the command line that built the source
distribution.)
0.6b4
* Fix ``register`` not obeying name/version set by ``egg_info`` command, if
``egg_info`` wasn't explicitly run first on the same command line.
* Added ``--no-date`` and ``--no-svn-revision`` options to ``egg_info``
command, to allow suppressing tags configured in ``setup.cfg``.
* Fixed redundant warnings about missing ``README`` file(s); it should now
appear only if you are actually a source distribution.
0.6b3
* Fix ``bdist_egg`` not including files in subdirectories of ``.egg-info``.
* Allow ``.py`` files found by the ``include_package_data`` option to be
automatically included. Remove duplicate data file matches if both
``include_package_data`` and ``package_data`` are used to refer to the same
files.
0.6b1
* Strip ``module`` from the end of compiled extension modules when computing
the name of a ``.py`` loader/wrapper. (Python's import machinery ignores
this suffix when searching for an extension module.)
0.6a11
* Added ``test_loader`` keyword to support custom test loaders
* Added ``setuptools.file_finders`` entry point group to allow implementing
revision control plugins.
* Added ``--identity`` option to ``upload`` command.
* Added ``dependency_links`` to allow specifying URLs for ``--find-links``.
* Enhanced test loader to scan packages as well as modules, and call
``additional_tests()`` if present to get non-unittest tests.
* Support namespace packages in conjunction with system packagers, by omitting
the installation of any ``__init__.py`` files for namespace packages, and
adding a special ``.pth`` file to create a working package in
``sys.modules``.
* Made ``--single-version-externally-managed`` automatic when ``--root`` is
used, so that most system packagers won't require special support for
setuptools.
* Fixed ``setup_requires``, ``tests_require``, etc. not using ``setup.cfg`` or
other configuration files for their option defaults when installing, and
also made the install use ``--multi-version`` mode so that the project
directory doesn't need to support .pth files.
* ``MANIFEST.in`` is now forcibly closed when any errors occur while reading
it. Previously, the file could be left open and the actual error would be
masked by problems trying to remove the open file on Windows systems.
0.6a10
* Fixed the ``develop`` command ignoring ``--find-links``.
0.6a9
* The ``sdist`` command no longer uses the traditional ``MANIFEST`` file to
create source distributions. ``MANIFEST.in`` is still read and processed,
as are the standard defaults and pruning. But the manifest is built inside
the project's ``.egg-info`` directory as ``SOURCES.txt``, and it is rebuilt
every time the ``egg_info`` command is run.
* Added the ``include_package_data`` keyword to ``setup()``, allowing you to
automatically include any package data listed in revision control or
``MANIFEST.in``
* Added the ``exclude_package_data`` keyword to ``setup()``, allowing you to
trim back files included via the ``package_data`` and
``include_package_data`` options.
* Fixed ``--tag-svn-revision`` not working when run from a source
distribution.
* Added warning for namespace packages with missing ``declare_namespace()``
* Added ``tests_require`` keyword to ``setup()``, so that e.g. packages
requiring ``nose`` to run unit tests can make this dependency optional
unless the ``test`` command is run.
* Made all commands that use ``easy_install`` respect its configuration
options, as this was causing some problems with ``setup.py install``.
* Added an ``unpack_directory()`` driver to ``setuptools.archive_util``, so
that you can process a directory tree through a processing filter as if it
were a zipfile or tarfile.
* Added an internal ``install_egg_info`` command to use as part of old-style
``install`` operations, that installs an ``.egg-info`` directory with the
package.
* Added a ``--single-version-externally-managed`` option to the ``install``
command so that you can more easily wrap a "flat" egg in a system package.
* Enhanced ``bdist_rpm`` so that it installs single-version eggs that
don't rely on a ``.pth`` file. The ``--no-egg`` option has been removed,
since all RPMs are now built in a more backwards-compatible format.
* Support full roundtrip translation of eggs to and from ``bdist_wininst``
format. Running ``bdist_wininst`` on a setuptools-based package wraps the
egg in an .exe that will safely install it as an egg (i.e., with metadata
and entry-point wrapper scripts), and ``easy_install`` can turn the .exe
back into an ``.egg`` file or directory and install it as such.
0.6a8
* Fixed some problems building extensions when Pyrex was installed, especially
with Python 2.4 and/or packages using SWIG.
* Made ``develop`` command accept all the same options as ``easy_install``,
and use the ``easy_install`` command's configuration settings as defaults.
* Made ``egg_info --tag-svn-revision`` fall back to extracting the revision
number from ``PKG-INFO`` in case it is being run on a source distribution of
a snapshot taken from a Subversion-based project.
* Automatically detect ``.dll``, ``.so`` and ``.dylib`` files that are being
installed as data, adding them to ``native_libs.txt`` automatically.
* Fixed some problems with fresh checkouts of projects that don't include
``.egg-info/PKG-INFO`` under revision control and put the project's source
code directly in the project directory. If such a package had any
requirements that get processed before the ``egg_info`` command can be run,
the setup scripts would fail with a "Missing 'Version:' header and/or
PKG-INFO file" error, because the egg runtime interpreted the unbuilt
metadata in a directory on ``sys.path`` (i.e. the current directory) as
being a corrupted egg. Setuptools now monkeypatches the distribution
metadata cache to pretend that the egg has valid version information, until
it has a chance to make it actually be so (via the ``egg_info`` command).
0.6a5
* Fixed missing gui/cli .exe files in distribution. Fixed bugs in tests.
0.6a3
* Added ``gui_scripts`` entry point group to allow installing GUI scripts
on Windows and other platforms. (The special handling is only for Windows;
other platforms are treated the same as for ``console_scripts``.)
0.6a2
* Added ``console_scripts`` entry point group to allow installing scripts
without the need to create separate script files. On Windows, console
scripts get an ``.exe`` wrapper so you can just type their name. On other
platforms, the scripts are written without a file extension.
0.6a1
* Added support for building "old-style" RPMs that don't install an egg for
the target package, using a ``--no-egg`` option.
* The ``build_ext`` command now works better when using the ``--inplace``
option and multiple Python versions. It now makes sure that all extensions
match the current Python version, even if newer copies were built for a
different Python version.
* The ``upload`` command no longer attaches an extra ``.zip`` when uploading
eggs, as PyPI now supports egg uploads without trickery.
* The ``ez_setup`` script/module now displays a warning before downloading
the setuptools egg, and attempts to check the downloaded egg against an
internal MD5 checksum table.
* Fixed the ``--tag-svn-revision`` option of ``egg_info`` not finding the
latest revision number; it was using the revision number of the directory
containing ``setup.py``, not the highest revision number in the project.
* Added ``eager_resources`` setup argument
* The ``sdist`` command now recognizes Subversion "deleted file" entries and
does not include them in source distributions.
* ``setuptools`` now embeds itself more thoroughly into the distutils, so that
other distutils extensions (e.g. py2exe, py2app) will subclass setuptools'
versions of things, rather than the native distutils ones.
* Added ``entry_points`` and ``setup_requires`` arguments to ``setup()``;
``setup_requires`` allows you to automatically find and download packages
that are needed in order to *build* your project (as opposed to running it).
* ``setuptools`` now finds its commands, ``setup()`` argument validators, and
metadata writers using entry points, so that they can be extended by
third-party packages. See `Creating distutils Extensions`_ above for more
details.
* The vestigial ``depends`` command has been removed. It was never finished
or documented, and never would have worked without EasyInstall - which it
pre-dated and was never compatible with.
0.5a12
* The zip-safety scanner now checks for modules that might be used with
``python -m``, and marks them as unsafe for zipping, since Python 2.4 can't
handle ``-m`` on zipped modules.
0.5a11
* Fix breakage of the "develop" command that was caused by the addition of
``--always-unzip`` to the ``easy_install`` command.
0.5a9
* Include ``svn:externals`` directories in source distributions as well as
normal subversion-controlled files and directories.
* Added ``exclude=patternlist`` option to ``setuptools.find_packages()``
* Changed --tag-svn-revision to include an "r" in front of the revision number
for better readability.
* Added ability to build eggs without including source files (except for any
scripts, of course), using the ``--exclude-source-files`` option to
``bdist_egg``.
* ``setup.py install`` now automatically detects when an "unmanaged" package
or module is going to be on ``sys.path`` ahead of a package being installed,
thereby preventing the newer version from being imported. If this occurs,
a warning message is output to ``sys.stderr``, but installation proceeds
anyway. The warning message informs the user what files or directories
need deleting, and advises them they can also use EasyInstall (with the
``--delete-conflicting`` option) to do it automatically.
* The ``egg_info`` command now adds a ``top_level.txt`` file to the metadata
directory that lists all top-level modules and packages in the distribution.
This is used by the ``easy_install`` command to find possibly-conflicting
"unmanaged" packages when installing the distribution.
* Added ``zip_safe`` and ``namespace_packages`` arguments to ``setup()``.
Added package analysis to determine zip-safety if the ``zip_safe`` flag
is not given, and advise the author regarding what code might need changing.
* Fixed the swapped ``-d`` and ``-b`` options of ``bdist_egg``.
0.5a8
* The "egg_info" command now always sets the distribution metadata to "safe"
forms of the distribution name and version, so that distribution files will
be generated with parseable names (i.e., ones that don't include '-' in the
name or version). Also, this means that if you use the various ``--tag``
options of "egg_info", any distributions generated will use the tags in the
version, not just egg distributions.
* Added support for defining command aliases in distutils configuration files,
under the "[aliases]" section. To prevent recursion and to allow aliases to
call the command of the same name, a given alias can be expanded only once
per command-line invocation. You can define new aliases with the "alias"
command, either for the local, global, or per-user configuration.
* Added "rotate" command to delete old distribution files, given a set of
patterns to match and the number of files to keep. (Keeps the most
recently-modified distribution files matching each pattern.)
* Added "saveopts" command that saves all command-line options for the current
invocation to the local, global, or per-user configuration file. Useful for
setting defaults without having to hand-edit a configuration file.
* Added a "setopt" command that sets a single option in a specified distutils
configuration file.
0.5a7
* Added "upload" support for egg and source distributions, including a bug
fix for "upload" and a temporary workaround for lack of .egg support in
PyPI.
0.5a6
* Beefed up the "sdist" command so that if you don't have a MANIFEST.in, it
will include all files under revision control (CVS or Subversion) in the
current directory, and it will regenerate the list every time you create a
source distribution, not just when you tell it to. This should make the
default "do what you mean" more often than the distutils' default behavior
did, while still retaining the old behavior in the presence of MANIFEST.in.
* Fixed the "develop" command always updating .pth files, even if you
specified ``-n`` or ``--dry-run``.
* Slightly changed the format of the generated version when you use
``--tag-build`` on the "egg_info" command, so that you can make tagged
revisions compare *lower* than the version specified in setup.py (e.g. by
using ``--tag-build=dev``).
0.5a5
* Added ``develop`` command to ``setuptools``-based packages. This command
installs an ``.egg-link`` pointing to the package's source directory, and
script wrappers that ``execfile()`` the source versions of the package's
scripts. This lets you put your development checkout(s) on sys.path without
having to actually install them. (To uninstall the link, use
use ``setup.py develop --uninstall``.)
* Added ``egg_info`` command to ``setuptools``-based packages. This command
just creates or updates the "projectname.egg-info" directory, without
building an egg. (It's used by the ``bdist_egg``, ``test``, and ``develop``
commands.)
* Enhanced the ``test`` command so that it doesn't install the package, but
instead builds any C extensions in-place, updates the ``.egg-info``
metadata, adds the source directory to ``sys.path``, and runs the tests
directly on the source. This avoids an "unmanaged" installation of the
package to ``site-packages`` or elsewhere.
* Made ``easy_install`` a standard ``setuptools`` command, moving it from
the ``easy_install`` module to ``setuptools.command.easy_install``. Note
that if you were importing or extending it, you must now change your imports
accordingly. ``easy_install.py`` is still installed as a script, but not as
a module.
0.5a4
* Setup scripts using setuptools can now list their dependencies directly in
the setup.py file, without having to manually create a ``depends.txt`` file.
The ``install_requires`` and ``extras_require`` arguments to ``setup()``
are used to create a dependencies file automatically. If you are manually
creating ``depends.txt`` right now, please switch to using these setup
arguments as soon as practical, because ``depends.txt`` support will be
removed in the 0.6 release cycle. For documentation on the new arguments,
see the ``setuptools.dist.Distribution`` class.
* Setup scripts using setuptools now always install using ``easy_install``
internally, for ease of uninstallation and upgrading.
0.5a1
* Added support for "self-installation" bootstrapping. Packages can now
include ``ez_setup.py`` in their source distribution, and add the following
to their ``setup.py``, in order to automatically bootstrap installation of
setuptools as part of their setup process::
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup
# etc...
0.4a2
* Added ``ez_setup.py`` installer/bootstrap script to make initial setuptools
installation easier, and to allow distributions using setuptools to avoid
having to include setuptools in their source distribution.
* All downloads are now managed by the ``PackageIndex`` class (which is now
subclassable and replaceable), so that embedders can more easily override
download logic, give download progress reports, etc. The class has also
been moved to the new ``setuptools.package_index`` module.
* The ``Installer`` class no longer handles downloading, manages a temporary
directory, or tracks the ``zip_ok`` option. Downloading is now handled
by ``PackageIndex``, and ``Installer`` has become an ``easy_install``
command class based on ``setuptools.Command``.
* There is a new ``setuptools.sandbox.run_setup()`` API to invoke a setup
script in a directory sandbox, and a new ``setuptools.archive_util`` module
with an ``unpack_archive()`` API. These were split out of EasyInstall to
allow reuse by other tools and applications.
* ``setuptools.Command`` now supports reinitializing commands using keyword
arguments to set/reset options. Also, ``Command`` subclasses can now set
their ``command_consumes_arguments`` attribute to ``True`` in order to
receive an ``args`` option containing the rest of the command line.
0.3a2
* Added new options to ``bdist_egg`` to allow tagging the egg's version number
with a subversion revision number, the current date, or an explicit tag
value. Run ``setup.py bdist_egg --help`` to get more information.
* Misc. bug fixes
0.3a1
* Initial release.
Mailing List and Bug Tracker
============================
......@@ -3226,5 +2695,5 @@ confirmed via the list are actual bugs, and which you have reduced to a minimal
set of steps to reproduce.
.. _distutils-sig mailing list: http://mail.python.org/pipermail/distutils-sig/
.. _setuptools bug tracker: http://bugs.python.org/setuptools/
.. _setuptools bug tracker: https://bitbucket.org/pypa/setuptools/
......@@ -4,7 +4,7 @@ Using Setuptools in your project
To use Setuptools in your project, the recommended way is to ship
`ez_setup.py` alongside your `setup.py` script and call
it at the very begining of `setup.py` like this::
it at the very beginning of `setup.py` like this::
from ez_setup import use_setuptools
use_setuptools()
......@@ -20,6 +20,7 @@ import tempfile
import tarfile
import optparse
import subprocess
import platform
from distutils import log
......@@ -28,13 +29,22 @@ try:
except ImportError:
USER_SITE = None
DEFAULT_VERSION = "0.9.7"
DEFAULT_VERSION = "1.1.7"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args):
args = (sys.executable,) + args
return subprocess.call(args) == 0
def _check_call_py24(cmd, *args, **kwargs):
res = subprocess.call(cmd, *args, **kwargs)
class CalledProcessError(Exception):
pass
if not res == 0:
msg = "Command '%s' return non-zero exit status %d" % (cmd, res)
raise CalledProcessError(msg)
vars(subprocess).setdefault('check_call', _check_call_py24)
def _install(tarball, install_args=()):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
......@@ -141,41 +151,143 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
return _do_download(version, download_base, to_dir,
download_delay)
def _clean_check(cmd, target):
"""
Run the command to download target. If the command fails, clean up before
re-raising the error.
"""
try:
subprocess.check_call(cmd)
except subprocess.CalledProcessError:
if os.access(target, os.F_OK):
os.unlink(target)
raise
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15):
"""Download setuptools from a specified location and return its filename
def download_file_powershell(url, target):
"""
Download the file at url to target using Powershell (which will validate
trust). Raise an exception if the command cannot complete.
"""
target = os.path.abspath(target)
cmd = [
'powershell',
'-Command',
"(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(),
]
_clean_check(cmd, target)
def has_powershell():
if platform.system() != 'Windows':
return False
cmd = ['powershell', '-Command', 'echo test']
devnull = open(os.path.devnull, 'wb')
try:
try:
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
except:
return False
finally:
devnull.close()
return True
`version` should be a valid setuptools 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.
download_file_powershell.viable = has_powershell
def download_file_curl(url, target):
cmd = ['curl', url, '--silent', '--output', target]
_clean_check(cmd, target)
def has_curl():
cmd = ['curl', '--version']
devnull = open(os.path.devnull, 'wb')
try:
try:
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
except:
return False
finally:
devnull.close()
return True
download_file_curl.viable = has_curl
def download_file_wget(url, target):
cmd = ['wget', url, '--quiet', '--output-document', target]
_clean_check(cmd, target)
def has_wget():
cmd = ['wget', '--version']
devnull = open(os.path.devnull, 'wb')
try:
try:
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
except:
return False
finally:
devnull.close()
return True
download_file_wget.viable = has_wget
def download_file_insecure(url, target):
"""
Use Python to download the file, even though it cannot authenticate the
connection.
"""
# 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 = "setuptools-%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 = open(target, "wb")
dst.write(data)
finally:
if src:
src.close()
if dst:
dst.close()
download_file_insecure.viable = lambda: True
def get_best_downloader():
downloaders = [
download_file_powershell,
download_file_curl,
download_file_wget,
download_file_insecure,
]
for dl in downloaders:
if dl.viable():
return dl
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15,
downloader_factory=get_best_downloader):
"""Download setuptools from a specified location and return its filename
`version` should be a valid setuptools 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.
``downloader_factory`` should be a function taking no arguments and
returning a function for downloading a URL to a target.
"""
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
tgz_name = "setuptools-%s.tar.gz" % version
url = download_base + tgz_name
saveto = os.path.join(to_dir, tgz_name)
if not os.path.exists(saveto): # Avoid repeated downloads
log.warn("Downloading %s", url)
downloader = downloader_factory()
downloader(url, saveto)
return os.path.realpath(saveto)
......@@ -250,6 +362,11 @@ def _parse_args():
'--download-base', dest='download_base', metavar="URL",
default=DEFAULT_URL,
help='alternative URL from where to download the setuptools package')
parser.add_option(
'--insecure', dest='downloader_factory', action='store_const',
const=lambda: download_file_insecure, default=get_best_downloader,
help='Use internal, non-validating downloader'
)
options, args = parser.parse_args()
# positional arguments are ignored
return options
......@@ -257,7 +374,8 @@ def _parse_args():
def main(version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
options = _parse_args()
tarball = download_setuptools(download_base=options.download_base)
tarball = download_setuptools(download_base=options.download_base,
downloader_factory=options.downloader_factory)
return _install(tarball, _build_install_args(options))
if __name__ == '__main__':
......
......@@ -13,7 +13,13 @@ The package resource API is designed to work with normal filesystem packages,
method.
"""
import sys, os, time, re, imp, types, zipfile, zipimport
import sys
import os
import time
import re
import imp
import zipfile
import zipimport
import warnings
import stat
try:
......@@ -122,8 +128,6 @@ def _sset_object(key, ob, state):
_sget_none = _sset_none = lambda *args: None
def get_supported_platform():
"""Return this platform's maximum compatible version.
......@@ -137,33 +141,14 @@ def get_supported_platform():
If this condition occurs for any other platform with a version in its
platform strings, this function should be extended accordingly.
"""
plat = get_build_platform(); m = macosVersionString.match(plat)
plat = get_build_platform()
m = macosVersionString.match(plat)
if m is not None and sys.platform == "darwin":
try:
plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3))
except ValueError:
pass # not Mac OS X
return plat
__all__ = [
# Basic resource access and distribution/entry point discovery
......@@ -206,6 +191,7 @@ __all__ = [
# Deprecated/backward compatibility only
'run_main', 'AvailableDistributions',
]
class ResolutionError(Exception):
"""Abstract base for dependency resolution errors"""
def __repr__(self):
......@@ -299,11 +285,6 @@ darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)")
get_platform = get_build_platform # XXX backward compat
def compatible_platforms(provided,required):
"""Can code for the `provided` platform run on the `required` platform?
......@@ -343,8 +324,6 @@ def compatible_platforms(provided,required):
provMac.group(3) != reqMac.group(3):
return False
# is the required OS major update >= the provided one?
if int(provMac.group(2)) > int(reqMac.group(2)):
return False
......@@ -410,14 +389,6 @@ class IMetadataProvider:
"""Execute the named script in the supplied namespace dictionary"""
class IResourceProvider(IMetadataProvider):
"""An object that provides access to package resources"""
......@@ -446,19 +417,6 @@ class IResourceProvider(IMetadataProvider):
"""List of resource names in the directory (like ``os.listdir()``)"""
class WorkingSet(object):
"""A collection of active distributions on sys.path (or a similar list)"""
......@@ -475,7 +433,6 @@ class WorkingSet(object):
for entry in entries:
self.add_entry(entry)
def add_entry(self, entry):
"""Add a path item to ``.entries``, finding any distributions on it
......@@ -491,15 +448,10 @@ class WorkingSet(object):
for dist in find_distributions(entry, True):
self.add(dist, entry, False)
def __contains__(self,dist):
"""True if `dist` is the active distribution for its project"""
return self.by_key.get(dist.key) == dist
def find(self, req):
"""Find a distribution matching requirement `req`
......@@ -539,8 +491,6 @@ class WorkingSet(object):
ns['__name__'] = name
self.require(requires)[0].run_script(script_name, ns)
def __iter__(self):
"""Yield distributions for non-duplicate projects in the working set
......@@ -633,9 +583,8 @@ class WorkingSet(object):
return to_activate # return list of distros to activate
def find_plugins(self,
plugin_env, full_env=None, installer=None, fallback=True
):
def find_plugins(self, plugin_env, full_env=None, installer=None,
fallback=True):
"""Find all activatable distributions in `plugin_env`
Example usage::
......@@ -712,10 +661,6 @@ class WorkingSet(object):
return distributions, error_info
def require(self, *requirements):
"""Ensure that distributions matching `requirements` are activated
......@@ -839,7 +784,6 @@ class Environment(object):
if dist.key in self._cache:
_sort_dists(self._cache[dist.key])
def best_match(self, req, working_set, installer=None):
"""Find distribution best matching `req` and usable on `working_set`
......@@ -878,9 +822,6 @@ class Environment(object):
for key in self._distmap.keys():
if self[key]: yield key
def __iadd__(self, other):
"""In-place addition of a distribution or environment"""
if isinstance(other,Distribution):
......@@ -920,8 +861,6 @@ class ExtractionError(RuntimeError):
"""
class ResourceManager:
"""Manage resource extraction and packages"""
extraction_path = None
......@@ -990,20 +929,6 @@ variable to point to an accessible directory.
err.original_error = old_exc
raise err
def get_cache_path(self, archive_name, names=()):
"""Return absolute location in cache for `archive_name` and `names`
......@@ -1053,23 +978,6 @@ variable to point to an accessible directory.
"PYTHON_EGG_CACHE environment variable)." % path)
warnings.warn(msg, UserWarning)
def postprocess(self, tempname, filename):
"""Perform any platform-specific postprocessing of `tempname`
......@@ -1090,27 +998,6 @@ variable to point to an accessible directory.
mode = ((os.stat(tempname).st_mode) | 0x16D) & 0xFFF # 0555, 07777
os.chmod(tempname, mode)
def set_extraction_path(self, path):
"""Set the base path where resources will be extracted to, if needed.
......@@ -1150,8 +1037,6 @@ variable to point to an accessible directory.
"""
# XXX
def get_default_cache():
"""Determine the default cache location
......@@ -1227,13 +1112,6 @@ def to_filename(name):
"""
return name.replace('-','_')
_marker_names = {
'os': ['name'], 'sys': ['platform'],
'platform': ['version','machine','python_implementation'],
......@@ -1267,12 +1145,28 @@ def _pyimp():
else:
return 'CPython'
def normalize_exception(exc):
"""
Given a SyntaxError from a marker evaluation, normalize the error message:
- Remove indications of filename and line number.
- Replace platform-specific error messages with standard error messages.
"""
subs = {
'unexpected EOF while parsing': 'invalid syntax',
'parenthesis is never closed': 'invalid syntax',
}
exc.filename = None
exc.lineno = None
exc.msg = subs.get(exc.msg, exc.msg)
return exc
def invalid_marker(text):
"""Validate text as a PEP 426 environment marker; return exception or False"""
try:
evaluate_marker(text)
except SyntaxError:
return sys.exc_info()[1]
return normalize_exception(sys.exc_info()[1])
return False
def evaluate_marker(text, extra=None, _ops={}):
......@@ -1289,7 +1183,9 @@ def evaluate_marker(text, extra=None, _ops={}):
if not _ops:
from token import NAME, STRING
import token, symbol, operator
import token
import symbol
import operator
def and_test(nodelist):
# MUST NOT short-circuit evaluation, or invalid syntax can be skipped!
......@@ -1434,7 +1330,6 @@ class NullProvider:
def metadata_isdir(self,name):
return self.egg_info and self._isdir(self._fn(self.egg_info,name))
def resource_listdir(self,resource_name):
return self._listdir(self._fn(self.module_path,resource_name))
......@@ -1512,11 +1407,6 @@ class EggProvider(NullProvider):
old = path
path, base = os.path.split(path)
class DefaultProvider(EggProvider):
"""Provides access to package resources in the filesystem"""
......@@ -1752,28 +1642,6 @@ class ZipProvider(EggProvider):
register_loader_type(zipimport.zipimporter, ZipProvider)
class FileMetadata(EmptyProvider):
"""Metadata handler for standalone PKG-INFO files
......@@ -1804,20 +1672,6 @@ class FileMetadata(EmptyProvider):
return yield_lines(self.get_metadata(name))
class PathMetadata(DefaultProvider):
"""Metadata provider for egg directories
......@@ -1898,8 +1752,6 @@ class ImpLoader:
return mod
def get_importer(path_item):
"""Retrieve a PEP 302 "importer" for the given path item
......@@ -1937,10 +1789,6 @@ else:
del ImpLoader, ImpImporter
_declare_state('dict', _distribution_finders = {})
def register_finder(importer_type, distribution_finder):
......@@ -2271,8 +2119,6 @@ class EntryPoint(object):
list(map(working_set.add,
working_set.resolve(self.dist.requires(self.extras),env,installer)))
#@classmethod
def parse(cls, src, dist=None):
"""Parse a single entry point from string `src`
......@@ -2307,13 +2153,6 @@ class EntryPoint(object):
parse = classmethod(parse)
#@classmethod
def parse_group(cls, group, lines, dist=None):
"""Parse an entry point group"""
......@@ -2364,10 +2203,9 @@ class Distribution(object):
"""Wrap an actual or potential sys.path entry w/metadata"""
PKG_INFO = 'PKG-INFO'
def __init__(self,
location=None, metadata=None, project_name=None, version=None,
py_version=PY_MAJOR, platform=None, precedence = EGG_DIST
):
def __init__(self, location=None, metadata=None, project_name=None,
version=None, py_version=PY_MAJOR, platform=None,
precedence=EGG_DIST):
self.project_name = safe_name(project_name or 'Unknown')
if version is not None:
self._version = safe_version(version)
......@@ -2395,7 +2233,6 @@ class Distribution(object):
)
from_location = classmethod(from_location)
hashcmp = property(
lambda self: (
getattr(self,'parsed_version',()),
......@@ -2461,9 +2298,6 @@ class Distribution(object):
)
version = property(version)
#@property
def _dep_map(self):
try:
......@@ -2503,8 +2337,6 @@ class Distribution(object):
for line in self.get_metadata_lines(name):
yield line
def activate(self,path=None):
"""Ensure distribution is importable on `path` (default=sys.path)"""
if path is None: path = sys.path
......@@ -2513,7 +2345,6 @@ class Distribution(object):
fixup_namespace_packages(self.location)
list(map(declare_namespace, self._get_metadata('namespace_packages.txt')))
def egg_name(self):
"""Return what this distribution's standard .egg filename should be"""
filename = "%s-%s-py%s" % (
......@@ -2543,9 +2374,6 @@ class Distribution(object):
raise AttributeError(attr)
return getattr(self._provider, attr)
#@classmethod
def from_filename(cls,filename,metadata=None, **kw):
return cls.from_location(
......@@ -2581,12 +2409,6 @@ class Distribution(object):
"""Return the EntryPoint object for `group`+`name`, or ``None``"""
return self.get_entry_map(group).get(name)
def insert_on(self, path, loc = None):
"""Insert self.location in path before its nearest parent directory"""
......@@ -2627,7 +2449,6 @@ class Distribution(object):
return
def check_version_conflict(self):
if self.key=='setuptools':
return # ignore the inevitable setuptools self-conflicts :(
......@@ -2636,8 +2457,7 @@ class Distribution(object):
loc = normalize_path(self.location)
for modname in self._get_metadata('top_level.txt'):
if (modname not in sys.modules or modname in nsp
or modname in _namespace_packages
):
or modname in _namespace_packages):
continue
if modname in ('pkg_resources', 'setuptools', 'site'):
continue
......@@ -2668,9 +2488,6 @@ class Distribution(object):
kw.setdefault('metadata', self._provider)
return self.__class__(**kw)
#@property
def extras(self):
return [dep for dep in self._dep_map if dep]
......@@ -2740,9 +2557,11 @@ class DistInfoDistribution(Distribution):
return dm
_distributionImpl = {'.egg': Distribution,
_distributionImpl = {
'.egg': Distribution,
'.egg-info': Distribution,
'.dist-info': DistInfoDistribution }
'.dist-info': DistInfoDistribution,
}
def issue_warning(*args,**kw):
......@@ -2759,27 +2578,6 @@ def issue_warning(*args,**kw):
warn(stacklevel = level+1, *args, **kw)
def parse_requirements(strs):
"""Yield ``Requirement`` objects for each specification in `strs`
......@@ -2796,7 +2594,8 @@ def parse_requirements(strs):
while not TERMINATOR(line,p):
if CONTINUE(line,p):
try:
line = next(lines); p = 0
line = next(lines)
p = 0
except StopIteration:
raise ValueError(
"\\ must not appear on the last nonblank line"
......@@ -2847,21 +2646,6 @@ def _sort_dists(dists):
dists[::-1] = [d for hc,d in tmp]
class Requirement:
def __init__(self, project_name, specs, extras):
"""DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
......@@ -2896,14 +2680,16 @@ class Requirement:
compare = lambda a, b: (a > b) - (a < b) # -1, 0, 1
for parsed,trans,op,ver in self.index:
action = trans[compare(item,parsed)] # Indexing: 0, 1, -1
if action=='F': return False
elif action=='T': return True
elif action=='+': last = True
if action=='F':
return False
elif action=='T':
return True
elif action=='+':
last = True
elif action=='-' or last is None: last = False
if last is None: last = True # no rules encountered
return last
def __hash__(self):
return self.__hash
......@@ -2922,9 +2708,9 @@ class Requirement:
state_machine = {
# =><
'<' : '--T',
'<': '--T',
'<=': 'T-T',
'>' : 'F+F',
'>': 'F+F',
'>=': 'T+F',
'==': 'T..',
'!=': 'F++',
......@@ -3025,5 +2811,5 @@ run_main = run_script # backward compatibility
# all distributions added to the working set in the future (e.g. by
# calling ``require()``) will get activated as well.
add_activation_listener(lambda dist: dist.activate())
working_set.entries=[]; list(map(working_set.add_entry,sys.path)) # match order
working_set.entries=[]
list(map(working_set.add_entry,sys.path)) # match order
......@@ -7,13 +7,22 @@ import re
import os
import subprocess
import pkg_resources
pkg_resources.require('jaraco.packaging>=2.0')
def before_upload():
_linkify('CHANGES.txt', 'CHANGES (links).txt')
_add_bootstrap_bookmark()
BootstrapBookmark.add()
def after_push():
os.remove('CHANGES (links).txt')
BootstrapBookmark.push()
files_with_versions = (
'ez_setup.py', 'setuptools/__init__.py',
'ez_setup.py', 'setuptools/version.py',
)
test_info = "Travis-CI tests: http://travis-ci.org/#!/jaraco/setuptools"
......@@ -55,7 +64,21 @@ def replacer(match):
url = issue_urls[key].format(**match_dict)
return "`{text} <{url}>`_".format(text=text, url=url)
class BootstrapBookmark:
name = 'bootstrap'
def _add_bootstrap_bookmark():
cmd = ['hg', 'bookmark', '-i', 'bootstrap', '-f']
@classmethod
def add(cls):
cmd = ['hg', 'bookmark', '-i', cls.name, '-f']
subprocess.Popen(cmd)
@classmethod
def push(cls):
"""
Push the bootstrap bookmark
"""
push_command = ['hg', 'push', '-B', cls.name]
# don't use check_call here because mercurial will return a non-zero
# code even if it succeeds at pushing the bookmark (because there are
# no changesets to be pushed). !dm mercurial
subprocess.call(push_command)
......@@ -16,3 +16,6 @@ upload-dir = docs/build/html
[sdist]
formats=gztar
[wheel]
universal=1
......@@ -20,10 +20,10 @@ init_file.close()
SETUP_COMMANDS = command_ns['__all__']
main_ns = {}
init_path = convert_path('setuptools/__init__.py')
init_file = open(init_path)
exec(init_file.read(), main_ns)
init_file.close()
ver_path = convert_path('setuptools/version.py')
ver_file = open(ver_path)
exec(ver_file.read(), main_ns)
ver_file.close()
import setuptools
from setuptools.command.build_py import build_py as _build_py
......
[setuptools.installation]
eggsecutable = setuptools.command.easy_install:bootstrap
[console_scripts]
easy_install = setuptools.command.easy_install:main
easy_install-3.3 = setuptools.command.easy_install:main
[distutils.setup_keywords]
use_2to3 = setuptools.dist:assert_bool
namespace_packages = setuptools.dist:check_nsp
packages = setuptools.dist:check_packages
install_requires = setuptools.dist:check_requirements
eager_resources = setuptools.dist:assert_string_list
include_package_data = setuptools.dist:assert_bool
convert_2to3_doctests = setuptools.dist:assert_string_list
package_data = setuptools.dist:check_package_data
use_2to3_exclude_fixers = setuptools.dist:assert_string_list
dependency_links = setuptools.dist:assert_string_list
use_2to3_fixers = setuptools.dist:assert_string_list
test_suite = setuptools.dist:check_test_suite
tests_require = setuptools.dist:check_requirements
use_2to3 = setuptools.dist:assert_bool
exclude_package_data = setuptools.dist:check_package_data
test_loader = setuptools.dist:check_importable
extras_require = setuptools.dist:check_extras
install_requires = setuptools.dist:check_requirements
eager_resources = setuptools.dist:assert_string_list
include_package_data = setuptools.dist:assert_bool
packages = setuptools.dist:check_packages
entry_points = setuptools.dist:check_entry_points
use_2to3_fixers = setuptools.dist:assert_string_list
namespace_packages = setuptools.dist:check_nsp
zip_safe = setuptools.dist:assert_bool
tests_require = setuptools.dist:check_requirements
convert_2to3_doctests = setuptools.dist:assert_string_list
test_loader = setuptools.dist:check_importable
dependency_links = setuptools.dist:assert_string_list
entry_points = setuptools.dist:check_entry_points
[setuptools.file_finders]
svn_cvs = setuptools.command.sdist:_default_revctrl
[egg_info.writers]
depends.txt = setuptools.command.egg_info:warn_depends_obsolete
top_level.txt = setuptools.command.egg_info:write_toplevel_names
entry_points.txt = setuptools.command.egg_info:write_entries
requires.txt = setuptools.command.egg_info:write_requirements
PKG-INFO = setuptools.command.egg_info:write_pkg_info
eager_resources.txt = setuptools.command.egg_info:overwrite_arg
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
depends.txt = setuptools.command.egg_info:warn_depends_obsolete
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
entry_points.txt = setuptools.command.egg_info:write_entries
requires.txt = setuptools.command.egg_info:write_requirements
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
[distutils.commands]
test = setuptools.command.test:test
bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst
alias = setuptools.command.alias:alias
rotate = setuptools.command.rotate:rotate
bdist_egg = setuptools.command.bdist_egg:bdist_egg
install_scripts = setuptools.command.install_scripts:install_scripts
install_egg_info = setuptools.command.install_egg_info:install_egg_info
build_py = setuptools.command.build_py:build_py
build_ext = setuptools.command.build_ext:build_ext
install = setuptools.command.install:install
sdist = setuptools.command.sdist:sdist
upload_docs = setuptools.command.upload_docs:upload_docs
saveopts = setuptools.command.saveopts:saveopts
develop = setuptools.command.develop:develop
bdist_egg = setuptools.command.bdist_egg:bdist_egg
alias = setuptools.command.alias:alias
register = setuptools.command.register:register
setopt = setuptools.command.setopt:setopt
egg_info = setuptools.command.egg_info:egg_info
build_ext = setuptools.command.build_ext:build_ext
upload_docs = setuptools.command.upload_docs:upload_docs
test = setuptools.command.test:test
easy_install = setuptools.command.easy_install:easy_install
install = setuptools.command.install:install
install_egg_info = setuptools.command.install_egg_info:install_egg_info
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
install_lib = setuptools.command.install_lib:install_lib
rotate = setuptools.command.rotate:rotate
saveopts = setuptools.command.saveopts:saveopts
install_scripts = setuptools.command.install_scripts:install_scripts
build_py = setuptools.command.build_py:build_py
register = setuptools.command.register:register
bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
[setuptools.installation]
eggsecutable = setuptools.command.easy_install:bootstrap
[console_scripts]
easy_install = setuptools.command.easy_install:main
easy_install-3.3 = setuptools.command.easy_install:main
[ssl:python_version in '2.4, 2.5']
ssl==1.16
[ssl:sys_platform=='win32' and python_version=='2.4']
ctypes==1.0.2
[ssl:python_version in '2.4, 2.5']
ssl==1.16
[certs]
certifi==0.0.8
......
"""Extensions to the 'distutils' for large or complex distributions"""
from setuptools.extension import Extension, Library
from setuptools.dist import Distribution, Feature, _get_unpatched
import distutils.core, setuptools.command
from setuptools.depends import Require
from distutils.core import Command as _Command
from distutils.util import convert_path
import os
import sys
import distutils.core
import distutils.filelist
from distutils.core import Command as _Command
from distutils.util import convert_path
import setuptools.version
from setuptools.extension import Extension
from setuptools.dist import Distribution, Feature, _get_unpatched
from setuptools.depends import Require
__version__ = '0.9.7'
__all__ = [
'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
'find_packages'
]
__version__ = setuptools.version.__version__
bootstrap_install_from = None
# If we run 2to3 on .py files, should we also convert docstrings?
......@@ -37,10 +42,14 @@ def find_packages(where='.', exclude=()):
where,prefix = stack.pop(0)
for name in os.listdir(where):
fn = os.path.join(where,name)
if ('.' not in name and os.path.isdir(fn) and
os.path.isfile(os.path.join(fn,'__init__.py'))
):
out.append(prefix+name); stack.append((fn,prefix+name+'.'))
looks_like_package = (
'.' not in name
and os.path.isdir(fn)
and os.path.isfile(os.path.join(fn, '__init__.py'))
)
if looks_like_package:
out.append(prefix+name)
stack.append((fn, prefix+name+'.'))
for pat in list(exclude)+['ez_setup']:
from fnmatch import fnmatchcase
out = [item for item in out if not fnmatchcase(item,pat)]
......@@ -67,7 +76,6 @@ class Command(_Command):
setattr(cmd,k,v) # update command with keywords
return cmd
import distutils.core
distutils.core.Command = Command # we can't patch distutils.cmd, alas
def findall(dir = os.curdir):
......@@ -83,12 +91,8 @@ def findall(dir = os.curdir):
all_files.extend(filter(os.path.isfile, files))
return all_files
import distutils.filelist
distutils.filelist.findall = findall # fix findall bug in distutils.
# sys.dont_write_bytecode was introduced in Python 2.6.
if ((hasattr(sys, "dont_write_bytecode") and sys.dont_write_bytecode) or
(not hasattr(sys, "dont_write_bytecode") and os.environ.get("PYTHONDONTWRITEBYTECODE"))):
_dont_write_bytecode = True
else:
_dont_write_bytecode = False
_dont_write_bytecode = getattr(sys, 'dont_write_bytecode',
bool(os.environ.get("PYTHONDONTWRITEBYTECODE")))
#!python
"""\
"""
Easy Install
------------
......@@ -10,6 +11,7 @@ file, or visit the `EasyInstall home page`__.
__ https://pythonhosted.org/setuptools/easy_install.html
"""
import sys
import os
import zipimport
......@@ -20,11 +22,16 @@ import re
import stat
import random
import platform
import textwrap
import warnings
import site
import struct
from glob import glob
from distutils import log, dir_util
import pkg_resources
from setuptools import Command, _dont_write_bytecode
from setuptools.sandbox import run_setup
from distutils import log, dir_util
try:
# Python 2.7 or >=3.2
from sysconfig import get_config_vars, get_path
......@@ -51,12 +58,12 @@ from setuptools.package_index import URL_SCHEME
from setuptools.command import bdist_egg, egg_info
from setuptools.compat import (iteritems, maxsize, xrange, basestring, unicode,
reraise)
from pkg_resources import yield_lines, normalize_path, resource_string, \
ensure_directory, get_distribution, find_distributions, \
Environment, Requirement, Distribution, \
PathMetadata, EggMetadata, WorkingSet, \
DistributionNotFound, VersionConflict, \
DEVELOP_DIST
from pkg_resources import (
yield_lines, normalize_path, resource_string, ensure_directory,
get_distribution, find_distributions, Environment, Requirement,
Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound,
VersionConflict, DEVELOP_DIST,
)
if '__VENV_LAUNCHER__' in os.environ:
sys_executable = os.environ['__VENV_LAUNCHER__']
......@@ -68,22 +75,19 @@ __all__ = [
'main', 'get_exe_prefixes',
]
import site
HAS_USER_SITE = not sys.version < "2.6" and site.ENABLE_USER_SITE
import struct
def is_64bit():
return struct.calcsize("P") == 8
def samefile(p1,p2):
if hasattr(os.path,'samefile') and (
os.path.exists(p1) and os.path.exists(p2)
):
return os.path.samefile(p1,p2)
return (
os.path.normpath(os.path.normcase(p1)) ==
os.path.normpath(os.path.normcase(p2))
)
def samefile(p1, p2):
both_exist = os.path.exists(p1) and os.path.exists(p2)
use_samefile = hasattr(os.path, 'samefile') and both_exist
if use_samefile:
return os.path.samefile(p1, p2)
norm_p1 = os.path.normpath(os.path.normcase(p1))
norm_p2 = os.path.normpath(os.path.normcase(p2))
return norm_p1 == norm_p2
if sys.version_info <= (3,):
def _to_ascii(s):
......@@ -120,9 +124,6 @@ class easy_install(Command):
("always-copy", "a", "Copy all needed packages to install dir"),
("index-url=", "i", "base URL of Python Package Index"),
("find-links=", "f", "additional URL(s) to search for packages"),
("delete-conflicting", "D", "no longer needed; don't use this"),
("ignore-conflicts-at-my-risk", None,
"no longer needed; don't use this"),
("build-directory=", "b",
"download/extract/build in DIR; keep the results"),
('optimize=', 'O',
......@@ -135,23 +136,23 @@ class easy_install(Command):
('editable', 'e', "Install specified packages in editable form"),
('no-deps', 'N', "don't install dependencies"),
('allow-hosts=', 'H', "pattern(s) that hostnames must match"),
('local-snapshots-ok', 'l', "allow building eggs from local checkouts"),
('local-snapshots-ok', 'l',
"allow building eggs from local checkouts"),
('version', None, "print version information and exit"),
('no-find-links', None,
"Don't load find-links defined in packages being installed")
]
boolean_options = [
'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
'delete-conflicting', 'ignore-conflicts-at-my-risk', 'editable',
'editable',
'no-deps', 'local-snapshots-ok', 'version'
]
if HAS_USER_SITE:
user_options.append(('user', None,
"install in user site-package '%s'" % site.USER_SITE))
help_msg = "install in user site-package '%s'" % site.USER_SITE
user_options.append(('user', None, help_msg))
boolean_options.append('user')
negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex
......@@ -192,8 +193,6 @@ class easy_install(Command):
# Options not specifiable via command line
self.package_index = None
self.pth_file = self.always_copy_from = None
self.delete_conflicting = None
self.ignore_conflicts_at_my_risk = None
self.site_dirs = None
self.installed_projects = {}
self.sitepy_installed = False
......@@ -226,7 +225,8 @@ class easy_install(Command):
py_version = sys.version.split()[0]
prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix')
self.config_vars = {'dist_name': self.distribution.get_name(),
self.config_vars = {
'dist_name': self.distribution.get_name(),
'dist_version': self.distribution.get_version(),
'dist_fullname': self.distribution.get_fullname(),
'py_version': py_version,
......@@ -336,11 +336,6 @@ class easy_install(Command):
except ValueError:
raise DistutilsOptionError("--optimize must be 0, 1, or 2")
if self.delete_conflicting and self.ignore_conflicts_at_my_risk:
raise DistutilsOptionError(
"Can't use both --delete-conflicting and "
"--ignore-conflicts-at-my-risk at the same time"
)
if self.editable and not self.build_directory:
raise DistutilsArgError(
"Must specify a build directory (-b) when using --editable"
......@@ -351,7 +346,6 @@ class easy_install(Command):
self.outputs = []
def _expand_attrs(self, attrs):
for attr in attrs:
val = getattr(self, attr)
......@@ -406,12 +400,7 @@ class easy_install(Command):
return os.path.join(self.install_dir, "test-easy-install-%s" % pid)
def warn_deprecated_options(self):
if self.delete_conflicting or self.ignore_conflicts_at_my_risk:
log.warn(
"Note: The -D, --delete-conflicting and"
" --ignore-conflicts-at-my-risk no longer have any purpose"
" and should not be used."
)
pass
def check_site_dir(self):
"""Verify that self.install_dir is .pth-capable dir, if needed"""
......@@ -456,7 +445,7 @@ class easy_install(Command):
self.install_dir = instdir
def cant_write_to_target(self):
msg = """can't create or remove files in install directory
template = """can't create or remove files in install directory
The following error occurred while trying to add or remove files in the
installation directory:
......@@ -467,7 +456,8 @@ The installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:
%s
""" % (sys.exc_info()[1], self.install_dir,)
"""
msg = template % (sys.exc_info()[1], self.install_dir,)
if not os.path.exists(self.install_dir):
msg += """
......@@ -493,9 +483,6 @@ Please make the appropriate changes for your system and try again.
"""
raise DistutilsError(msg)
def check_pth_processing(self):
"""Empirically verify whether .pth files are supported in inst. dir"""
instdir = self.install_dir
......@@ -514,7 +501,8 @@ Please make the appropriate changes for your system and try again.
else:
try:
f.write("import os; f = open(%r, 'w'); f.write('OK'); f.close()\n" % (ok_file,))
f.close(); f=None
f.close()
f=None
executable = sys.executable
if os.name=='nt':
dirname,basename = os.path.split(executable)
......@@ -533,9 +521,12 @@ Please make the appropriate changes for your system and try again.
)
return True
finally:
if f: f.close()
if os.path.exists(ok_file): os.unlink(ok_file)
if os.path.exists(pth_file): os.unlink(pth_file)
if f:
f.close()
if os.path.exists(ok_file):
os.unlink(ok_file)
if os.path.exists(pth_file):
os.unlink(pth_file)
if not self.multi_version:
log.warn("TEST FAILED: %s does NOT support .pth files", instdir)
return False
......@@ -580,11 +571,6 @@ Please make the appropriate changes for your system and try again.
(spec.key, self.build_directory)
)
def easy_install(self, spec, deps=False):
tmpdir = tempfile.mkdtemp(prefix="easy_install-")
download = None
......@@ -654,7 +640,7 @@ Please make the appropriate changes for your system and try again.
for dist in dists:
self.process_distribution(spec, dist, deps)
else:
dists = [self.check_conflicts(self.egg_distribution(download))]
dists = [self.egg_distribution(download)]
self.process_distribution(spec, dists[0], deps, "Using")
if spec is not None:
......@@ -662,8 +648,6 @@ Please make the appropriate changes for your system and try again.
if dist in spec:
return dist
def select_scheme(self, name):
"""Sets the install directories by applying the install schemes."""
# it's the caller's problem if they supply a bad name!
......@@ -673,9 +657,6 @@ Please make the appropriate changes for your system and try again.
if getattr(self, attrname) is None:
setattr(self, attrname, scheme[key])
def process_distribution(self, requirement, dist, deps=True, *info):
self.update_pth(dist)
self.package_index.add(dist)
......@@ -735,10 +716,8 @@ Please make the appropriate changes for your system and try again.
def maybe_move(self, spec, dist_filename, setup_base):
dst = os.path.join(self.build_directory, spec.key)
if os.path.exists(dst):
log.warn(
"%r already exists in %s; build directory %s will not be kept",
spec.key, self.build_directory, setup_base
)
msg = "%r already exists in %s; build directory %s will not be kept"
log.warn(msg, spec.key, self.build_directory, setup_base)
return setup_base
if os.path.isdir(dist_filename):
setup_base = dist_filename
......@@ -751,7 +730,8 @@ Please make the appropriate changes for your system and try again.
if os.path.isdir(dist_filename):
# if the only thing there is a directory, move it instead
setup_base = dist_filename
ensure_directory(dst); shutil.move(setup_base, dst)
ensure_directory(dst)
shutil.move(setup_base, dst)
return dst
def install_wrapper_scripts(self, dist):
......@@ -759,8 +739,6 @@ Please make the appropriate changes for your system and try again.
for args in get_script_args(dist):
self.write_script(*args)
def install_script(self, dist, script_name, script_text, dev_path=None):
"""Generate a legacy script wrapper and install it"""
spec = str(dist.as_requirement())
......@@ -799,14 +777,13 @@ Please make the appropriate changes for your system and try again.
mask = current_umask()
if not self.dry_run:
ensure_directory(target)
if os.path.exists(target):
os.unlink(target)
f = open(target,"w"+mode)
f.write(contents)
f.close()
chmod(target, 0x1FF-mask) # 0777
def install_eggs(self, spec, dist_filename, tmpdir):
# .egg dirs or files are already built, so just return them
if dist_filename.lower().endswith('.egg'):
......@@ -822,8 +799,7 @@ Please make the appropriate changes for your system and try again.
setup_base = os.path.abspath(dist_filename)
if (setup_base.startswith(tmpdir) # something we downloaded
and self.build_directory and spec is not None
):
and self.build_directory and spec is not None):
setup_base = self.maybe_move(spec, dist_filename, setup_base)
# Find the setup.py file
......@@ -862,7 +838,6 @@ Please make the appropriate changes for your system and try again.
ensure_directory(destination)
dist = self.egg_distribution(egg_path)
self.check_conflicts(dist)
if not samefile(egg_path, destination):
if os.path.isdir(destination) and not os.path.islink(destination):
dir_util.remove_tree(destination, dry_run=self.dry_run)
......@@ -897,18 +872,19 @@ Please make the appropriate changes for your system and try again.
"%s is not a valid distutils Windows .exe" % dist_filename
)
# Create a dummy distribution object until we build the real distro
dist = Distribution(None,
dist = Distribution(
None,
project_name=cfg.get('metadata','name'),
version=cfg.get('metadata','version'), platform=get_platform()
version=cfg.get('metadata','version'), platform=get_platform(),
)
# Convert the .exe to an unpacked egg
egg_path = dist.location = os.path.join(tmpdir, dist.egg_name()+'.egg')
egg_tmp = egg_path+'.tmp'
egg_info = os.path.join(egg_tmp, 'EGG-INFO')
pkg_inf = os.path.join(egg_info, 'PKG-INFO')
egg_tmp = egg_path + '.tmp'
_egg_info = os.path.join(egg_tmp, 'EGG-INFO')
pkg_inf = os.path.join(_egg_info, 'PKG-INFO')
ensure_directory(pkg_inf) # make sure EGG-INFO dir exists
dist._provider = PathMetadata(egg_tmp, egg_info) # XXX
dist._provider = PathMetadata(egg_tmp, _egg_info) # XXX
self.exe_to_egg(dist_filename, egg_tmp)
# Write EGG-INFO/PKG-INFO
......@@ -919,7 +895,7 @@ Please make the appropriate changes for your system and try again.
if k != 'target_version':
f.write('%s: %s\n' % (k.replace('_','-').title(), v))
f.close()
script_dir = os.path.join(egg_info,'scripts')
script_dir = os.path.join(_egg_info,'scripts')
self.delete_blockers( # delete entry-point scripts to avoid duping
[os.path.join(script_dir,args[0]) for args in get_script_args(dist)]
)
......@@ -965,7 +941,8 @@ Please make the appropriate changes for your system and try again.
resource = parts[-1]
parts[-1] = bdist_egg.strip_module(parts[-1])+'.py'
pyfile = os.path.join(egg_tmp, *parts)
to_compile.append(pyfile); stubs.append(pyfile)
to_compile.append(pyfile)
stubs.append(pyfile)
bdist_egg.write_stub(resource, pyfile)
self.byte_compile(to_compile) # compile .py's
bdist_egg.write_safety_flag(os.path.join(egg_tmp,'EGG-INFO'),
......@@ -979,82 +956,6 @@ Please make the appropriate changes for your system and try again.
f.write('\n'.join(locals()[name])+'\n')
f.close()
def check_conflicts(self, dist):
"""Verify that there are no conflicting "old-style" packages"""
return dist # XXX temporarily disable until new strategy is stable
from imp import find_module, get_suffixes
from glob import glob
blockers = []
names = dict.fromkeys(dist._get_metadata('top_level.txt')) # XXX private attr
exts = {'.pyc':1, '.pyo':1} # get_suffixes() might leave one out
for ext,mode,typ in get_suffixes():
exts[ext] = 1
for path,files in expand_paths([self.install_dir]+self.all_site_dirs):
for filename in files:
base,ext = os.path.splitext(filename)
if base in names:
if not ext:
# no extension, check for package
try:
f, filename, descr = find_module(base, [path])
except ImportError:
continue
else:
if f: f.close()
if filename not in blockers:
blockers.append(filename)
elif ext in exts and base!='site': # XXX ugh
blockers.append(os.path.join(path,filename))
if blockers:
self.found_conflicts(dist, blockers)
return dist
def found_conflicts(self, dist, blockers):
if self.delete_conflicting:
log.warn("Attempting to delete conflicting packages:")
return self.delete_blockers(blockers)
msg = """\
-------------------------------------------------------------------------
CONFLICT WARNING:
The following modules or packages have the same names as modules or
packages being installed, and will be *before* the installed packages in
Python's search path. You MUST remove all of the relevant files and
directories before you will be able to use the package(s) you are
installing:
%s
""" % '\n '.join(blockers)
if self.ignore_conflicts_at_my_risk:
msg += """\
(Note: you can run EasyInstall on '%s' with the
--delete-conflicting option to attempt deletion of the above files
and/or directories.)
""" % dist.project_name
else:
msg += """\
Note: you can attempt this installation again with EasyInstall, and use
either the --delete-conflicting (-D) option or the
--ignore-conflicts-at-my-risk option, to either delete the above files
and directories, or to ignore the conflicts, respectively. Note that if
you ignore the conflicts, the installed package(s) may not work.
"""
msg += """\
-------------------------------------------------------------------------
"""
sys.stderr.write(msg)
sys.stderr.flush()
if not self.ignore_conflicts_at_my_risk:
raise DistutilsError("Installation aborted due to conflicts")
def installation_report(self, req, dist, what="Installed"):
"""Helpful installation message for display to package users"""
msg = "\n%(what)s %(eggloc)s%(extras)s"
......@@ -1164,8 +1065,7 @@ See the setuptools documentation for the "develop" command for more info.
cfg_filename = os.path.join(base, 'setup.cfg')
setopt.edit_config(cfg_filename, settings)
def update_pth(self,dist):
def update_pth(self, dist):
if self.pth_file is None:
return
......@@ -1207,9 +1107,10 @@ See the setuptools documentation for the "develop" command for more info.
return dst # only unpack-and-compile skips files for dry run
def unpack_and_compile(self, egg_path, destination):
to_compile = []; to_chmod = []
to_compile = []
to_chmod = []
def pf(src,dst):
def pf(src, dst):
if dst.endswith('.py') and not src.startswith('EGG-INFO/'):
to_compile.append(dst)
elif dst.endswith('.dll') or dst.endswith('.so'):
......@@ -1243,16 +1144,8 @@ See the setuptools documentation for the "develop" command for more info.
finally:
log.set_verbosity(self.verbose) # restore original verbosity
def no_default_version_msg(self):
return """bad install directory or PYTHONPATH
template = """bad install directory or PYTHONPATH
You are attempting to install a package to a directory that is not
on PYTHONPATH and which Python does not read ".pth" files from. The
......@@ -1279,18 +1172,8 @@ Here are some of your options for correcting the problem:
https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations
Please make the appropriate changes for your system and try again.""" % (
self.install_dir, os.environ.get('PYTHONPATH','')
)
Please make the appropriate changes for your system and try again."""
return template % (self.install_dir, os.environ.get('PYTHONPATH',''))
def install_site_py(self):
"""Make sure there's a site.py in the target dir, if needed"""
......@@ -1328,9 +1211,6 @@ Please make the appropriate changes for your system and try again.""" % (
self.sitepy_installed = True
def create_home_path(self):
"""Create directories under ~."""
if not self.user:
......@@ -1341,12 +1221,6 @@ Please make the appropriate changes for your system and try again.""" % (
self.debug_print("os.makedirs('%s', 0700)" % path)
os.makedirs(path, 0x1C0) # 0700
INSTALL_SCHEMES = dict(
posix = dict(
install_dir = '$base/lib/python$py_version_short/site-packages',
......@@ -1380,14 +1254,6 @@ Please make the appropriate changes for your system and try again.""" % (
val = os.path.expanduser(val)
setattr(self, attr, val)
def get_site_dirs():
# return a list of 'site' dirs
sitedirs = [_f for _f in os.environ.get('PYTHONPATH',
......@@ -1522,12 +1388,6 @@ def extract_wininst_cfg(dist_filename):
f.close()
def get_exe_prefixes(exe_filename):
"""Get exe->egg path translations for a given .exe file"""
......@@ -1561,7 +1421,8 @@ def get_exe_prefixes(exe_filename):
finally:
z.close()
prefixes = [(x.lower(),y) for x, y in prefixes]
prefixes.sort(); prefixes.reverse()
prefixes.sort()
prefixes.reverse()
return prefixes
......@@ -1582,7 +1443,8 @@ class PthDistributions(Environment):
self.filename = filename
self.sitedirs = list(map(normalize_path, sitedirs))
self.basedir = normalize_path(os.path.dirname(self.filename))
self._load(); Environment.__init__(self, [], None, None)
self._load()
Environment.__init__(self, [], None, None)
for path in yield_lines(self.paths):
list(map(self.add, find_distributions(path, True)))
......@@ -1637,7 +1499,8 @@ class PthDistributions(Environment):
if os.path.islink(self.filename):
os.unlink(self.filename)
f = open(self.filename,'wt')
f.write(data); f.close()
f.write(data)
f.close()
elif os.path.exists(self.filename):
log.debug("Deleting empty %s", self.filename)
......@@ -1645,22 +1508,22 @@ class PthDistributions(Environment):
self.dirty = False
def add(self,dist):
def add(self, dist):
"""Add `dist` to the distribution map"""
if (dist.location not in self.paths and (
dist.location not in self.sitedirs or
dist.location == os.getcwd() #account for '.' being in PYTHONPATH
dist.location == os.getcwd() # account for '.' being in PYTHONPATH
)):
self.paths.append(dist.location)
self.dirty = True
Environment.add(self,dist)
Environment.add(self, dist)
def remove(self,dist):
def remove(self, dist):
"""Remove `dist` from the distribution map"""
while dist.location in self.paths:
self.paths.remove(dist.location); self.dirty = True
Environment.remove(self,dist)
self.paths.remove(dist.location)
self.dirty = True
Environment.remove(self, dist)
def make_relative(self,path):
npath, last = os.path.split(normalize_path(path))
......@@ -1782,14 +1645,6 @@ def nt_quote_arg(arg):
return ''.join(result)
def is_python_script(script_text, filename):
"""Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.
"""
......@@ -1828,7 +1683,8 @@ def fix_jython_executable(executable, options):
# shebang line interpreter)
if options:
# Can't apply the workaround, leave it broken
log.warn("WARNING: Unable to adapt shebang line for Jython,"
log.warn(
"WARNING: Unable to adapt shebang line for Jython,"
" the following script is NOT executable\n"
" see http://bugs.jython.org/issue1112 for"
" more information.")
......@@ -1837,41 +1693,115 @@ def fix_jython_executable(executable, options):
return executable
def get_script_args(dist, executable=sys_executable, wininst=False):
"""Yield write_script() argument tuples for a distribution's entrypoints"""
class ScriptWriter(object):
"""
Encapsulates behavior around writing entry point scripts for console and
gui apps.
"""
template = textwrap.dedent("""
# EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
__requires__ = %(spec)r
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point(%(spec)r, %(group)r, %(name)r)()
)
""").lstrip()
@classmethod
def get_script_args(cls, dist, executable=sys_executable, wininst=False):
"""
Yield write_script() argument tuples for a distribution's entrypoints
"""
gen_class = cls.get_writer(wininst)
spec = str(dist.as_requirement())
header = get_script_header("", executable, wininst)
for group in 'console_scripts', 'gui_scripts':
for type_ in 'console', 'gui':
group = type_ + '_scripts'
for name, ep in dist.get_entry_map(group).items():
script_text = (
"# EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r\n"
"__requires__ = %(spec)r\n"
"import sys\n"
"from pkg_resources import load_entry_point\n"
"\n"
"if __name__ == '__main__':"
"\n"
" sys.exit(\n"
" load_entry_point(%(spec)r, %(group)r, %(name)r)()\n"
" )\n"
) % locals()
if sys.platform=='win32' or wininst:
# On Windows/wininst, add a .py extension and an .exe launcher
if group=='gui_scripts':
script_text = gen_class.template % locals()
for res in gen_class._get_script_args(type_, name, header,
script_text):
yield res
@classmethod
def get_writer(cls, force_windows):
if force_windows or sys.platform=='win32':
return WindowsScriptWriter.get_writer()
return cls
@classmethod
def _get_script_args(cls, type_, name, header, script_text):
# Simply write the stub with no extension.
yield (name, header+script_text)
class WindowsScriptWriter(ScriptWriter):
@classmethod
def get_writer(cls):
"""
Get a script writer suitable for Windows
"""
writer_lookup = dict(
executable=WindowsExecutableLauncherWriter,
natural=cls,
)
# for compatibility, use the executable launcher by default
launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable')
return writer_lookup[launcher]
@classmethod
def _get_script_args(cls, type_, name, header, script_text):
"For Windows, add a .py extension"
ext = dict(console='.pya', gui='.pyw')[type_]
if ext not in os.environ['PATHEXT'].lower().split(';'):
warnings.warn("%s not listed in PATHEXT; scripts will not be "
"recognized as executables." % ext, UserWarning)
old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe']
old.remove(ext)
header = cls._adjust_header(type_, header)
blockers = [name+x for x in old]
yield name+ext, header+script_text, 't', blockers
@staticmethod
def _adjust_header(type_, orig_header):
"""
Make sure 'pythonw' is used for gui and and 'python' is used for
console (regardless of what sys.executable is).
"""
pattern = 'pythonw.exe'
repl = 'python.exe'
if type_ == 'gui':
pattern, repl = repl, pattern
pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE)
new_header = pattern_ob.sub(string=orig_header, repl=repl)
clean_header = new_header[2:-1].strip('"')
if sys.platform == 'win32' and not os.path.exists(clean_header):
# the adjusted version doesn't exist, so return the original
return orig_header
return new_header
class WindowsExecutableLauncherWriter(WindowsScriptWriter):
@classmethod
def _get_script_args(cls, type_, name, header, script_text):
"""
For Windows, add a .py extension and an .exe launcher
"""
if type_=='gui':
launcher_type = 'gui'
ext = '-script.pyw'
old = ['.pyw']
new_header = re.sub('(?i)python.exe','pythonw.exe',header)
else:
launcher_type = 'cli'
ext = '-script.py'
old = ['.py','.pyc','.pyo']
new_header = re.sub('(?i)pythonw.exe','python.exe',header)
if os.path.exists(new_header[2:-1].strip('"')) or sys.platform!='win32':
hdr = new_header
else:
hdr = header
yield (name+ext, hdr+script_text, 't', [name+x for x in old])
hdr = cls._adjust_header(type_, header)
blockers = [name+x for x in old]
yield (name+ext, hdr+script_text, 't', blockers)
yield (
name+'.exe', get_win_launcher(launcher_type),
'b' # write in binary mode
......@@ -1884,10 +1814,9 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
# See Distribute #143 for details.
m_name = name + '.exe.manifest'
yield (m_name, load_launcher_manifest(name), 't')
else:
# On other platforms, we assume the right thing to do is to
# just write the stub with no extension.
yield (name, header+script_text)
# for backward-compatibility
get_script_args = ScriptWriter.get_script_args
def get_win_launcher(type):
"""
......@@ -1955,8 +1884,11 @@ def current_umask():
def bootstrap():
# This function is called when setuptools*.egg is run using /bin/sh
import setuptools; argv0 = os.path.dirname(setuptools.__path__[0])
sys.argv[0] = argv0; sys.argv.append(argv0); main()
import setuptools
argv0 = os.path.dirname(setuptools.__path__[0])
sys.argv[0] = argv0
sys.argv.append(argv0)
main()
def main(argv=None, **kw):
from setuptools import setup
......@@ -1968,9 +1900,10 @@ usage: %(script)s [options] requirement_or_url ...
or: %(script)s --help
"""
def gen_usage (script_name):
script = os.path.basename(script_name)
return USAGE % vars()
def gen_usage(script_name):
return USAGE % dict(
script=os.path.basename(script_name),
)
def with_ei_usage(f):
old_gen_usage = distutils.core.gen_usage
......@@ -1996,7 +1929,3 @@ usage: %(script)s [options] requirement_or_url ...
distclass=DistributionWithoutHelpCommands, **kw
)
)
import os
import re
import sys
from glob import glob
import pkg_resources
from distutils.command.sdist import sdist as _sdist
from distutils.util import convert_path
from distutils import log
from glob import glob
import os, re, sys, pkg_resources
from glob import glob
from setuptools import svn_utils
READMES = ('README', 'README.rst', 'README.txt')
......@@ -37,7 +40,6 @@ class re_finder(object):
#was an re_finder for calling unescape
path = postproc(path)
yield svn_utils.joinpath(dirname,path)
def __call__(self, dirname=''):
path = svn_utils.joinpath(dirname, self.path)
......@@ -64,16 +66,6 @@ finders = [
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
......@@ -128,11 +120,12 @@ class sdist(_sdist):
# Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
# has been fixed, so only override the method if we're using an earlier
# Python.
if (
has_leaky_handle = (
sys.version_info < (2,7,2)
or (3,0) <= sys.version_info < (3,1,4)
or (3,2) <= sys.version_info < (3,2,1)
):
)
if has_leaky_handle:
read_template = __read_template_hack
def add_defaults(self):
......@@ -197,7 +190,6 @@ class sdist(_sdist):
"standard file not found: should have one of " +', '.join(READMES)
)
def make_release_tree(self, base_dir, files):
_sdist.make_release_tree(self, base_dir, files)
......@@ -244,10 +236,3 @@ class sdist(_sdist):
continue
self.filelist.append(line)
manifest.close()
#
......@@ -2,10 +2,10 @@
Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
from distutils.errors import *
from distutils import errors
from distutils import log
from distutils.core import Command
from distutils.spawn import spawn
from distutils import log
try:
from hashlib import md5
except ImportError:
......@@ -45,7 +45,7 @@ class upload(Command):
def finalize_options(self):
if self.identity and not self.sign:
raise DistutilsOptionError(
raise errors.DistutilsOptionError(
"Must use --sign for --identity to have meaning"
)
if 'HOME' in os.environ:
......@@ -68,7 +68,7 @@ class upload(Command):
def run(self):
if not self.distribution.dist_files:
raise DistutilsOptionError("No dist file created in earlier command")
raise errors.DistutilsOptionError("No dist file created in earlier command")
for command, pyversion, filename in self.distribution.dist_files:
self.upload_file(command, pyversion, filename)
......@@ -119,10 +119,10 @@ class upload(Command):
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
sep_boundary = '\n--' + boundary
end_boundary = sep_boundary + '--'
body = StringIO.StringIO()
body = StringIO()
for key, value in data.items():
# handle multiple entries for the same name
if type(value) != type([]):
if not isinstance(value, list):
value = [value]
for value in value:
if type(value) is tuple:
......@@ -158,7 +158,6 @@ class upload(Command):
raise AssertionError("unsupported schema " + schema)
data = ''
loglevel = log.INFO
try:
http.connect()
http.putrequest("POST", url)
......
......@@ -27,10 +27,10 @@ if sys.version_info[0] < 3:
unichr = unichr
unicode = unicode
bytes = str
from urllib import url2pathname
from urllib import url2pathname, splittag
import urllib2
from urllib2 import urlopen, HTTPError, URLError, unquote, splituser
from urlparse import urlparse, urlunparse, urljoin
from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit
xrange = xrange
filterfalse = itertools.ifilterfalse
......@@ -74,7 +74,10 @@ else:
from urllib.error import HTTPError, URLError
import urllib.request as urllib2
from urllib.request import urlopen, url2pathname
from urllib.parse import urlparse, urlunparse, unquote, splituser, urljoin
from urllib.parse import (
urlparse, urlunparse, unquote, splituser, urljoin, urlsplit,
urlunsplit, splittag,
)
xrange = range
filterfalse = itertools.filterfalse
......@@ -83,7 +86,7 @@ else:
globs = globals()
if locs is None:
locs = globs
f = open(fn)
f = open(fn, 'rb')
try:
source = f.read()
finally:
......
__all__ = ['Distribution']
import re
import os
import sys
import warnings
import distutils.log
import distutils.core
import distutils.cmd
from distutils.core import Distribution as _Distribution
from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
DistutilsSetupError)
from setuptools.depends import Require
from setuptools.command.install import install
from setuptools.command.sdist import sdist
from setuptools.command.install_lib import install_lib
from setuptools.compat import numeric_types, basestring
from distutils.errors import DistutilsOptionError, DistutilsPlatformError
from distutils.errors import DistutilsSetupError
import setuptools, pkg_resources, distutils.core, distutils.dist, distutils.cmd
import os, distutils.log
import pkg_resources
def _get_unpatched(cls):
"""Protect against re-patching the distutils if reloaded
......@@ -134,38 +136,6 @@ def check_packages(dist, attr, value):
)
class Distribution(_Distribution):
"""Distribution with support for features, tests, and package data
......@@ -194,7 +164,8 @@ class Distribution(_Distribution):
EasyInstall and requests one of your extras, the corresponding
additional requirements will be installed if needed.
'features' -- a dictionary mapping option names to 'setuptools.Feature'
'features' **deprecated** -- a dictionary mapping option names to
'setuptools.Feature'
objects. Features are a portion of the distribution that can be
included or excluded based on user options, inter-feature dependencies,
and availability on the current system. Excluded features are omitted
......@@ -248,10 +219,13 @@ class Distribution(_Distribution):
dist._version = pkg_resources.safe_version(str(attrs['version']))
self._patched_dist = dist
def __init__ (self, attrs=None):
def __init__(self, attrs=None):
have_package_data = hasattr(self, "package_data")
if not have_package_data:
self.package_data = {}
_attrs_dict = attrs or {}
if 'features' in _attrs_dict or 'require_features' in _attrs_dict:
Feature.warn_deprecated()
self.require_features = []
self.features = {}
self.dist_files = []
......@@ -362,23 +336,6 @@ class Distribution(_Distribution):
self.global_options = self.feature_options = go + self.global_options
self.negative_opt = self.feature_negopt = no
def _finalize_features(self):
"""Add/remove features and resolve dependencies between them"""
......@@ -396,7 +353,6 @@ class Distribution(_Distribution):
feature.exclude_from(self)
self._set_feature(name,0)
def get_command_class(self, command):
"""Pluggable version of get_command_class()"""
if command in self.cmdclass:
......@@ -416,10 +372,6 @@ class Distribution(_Distribution):
self.cmdclass[ep.name] = cmdclass
return _Distribution.print_commands(self)
def _set_feature(self,name,status):
"""Set feature's inclusion status"""
setattr(self,self._feature_attrname(name),status)
......@@ -483,7 +435,6 @@ class Distribution(_Distribution):
if p.name != package and not p.name.startswith(pfx)
]
def has_contents_for(self,package):
"""Return true if 'exclude_package(package)' would do something"""
......@@ -493,15 +444,6 @@ class Distribution(_Distribution):
if p==package or p.startswith(pfx):
return True
def _exclude_misc(self,name,value):
"""Handle 'exclude()' for list/tuple attrs without a special handler"""
if not isinstance(value,sequence):
......@@ -573,17 +515,6 @@ class Distribution(_Distribution):
)
list(map(self.exclude_package, packages))
def _parse_command_opts(self, parser, args):
# Remove --with-X/--without-X options when processing command args
self.global_options = self.__class__.global_options
......@@ -610,21 +541,6 @@ class Distribution(_Distribution):
return nargs
def get_cmdline_options(self):
"""Return a '{cmd: {opt:val}}' map of all command-line options
......@@ -665,7 +581,6 @@ class Distribution(_Distribution):
return d
def iter_distribution_names(self):
"""Yield all packages, modules, and extension names in distribution"""
......@@ -684,7 +599,6 @@ class Distribution(_Distribution):
name = name[:-6]
yield name
def handle_display_options(self, option_order):
"""If there were any non-global "display-only" options
(--help-commands or the metadata display options) on the command
......@@ -726,26 +640,14 @@ for module in distutils.dist, distutils.core, distutils.cmd:
module.Distribution = Distribution
class Feature:
"""A subset of the distribution that can be excluded if unneeded/wanted
"""
**deprecated** -- The `Feature` facility was never completely implemented
or supported, `has reported issues
<https://bitbucket.org/pypa/setuptools/issue/58>`_ and will be removed in
a future version.
A subset of the distribution that can be excluded if unneeded/wanted
Features are created using these keyword arguments:
......@@ -794,9 +696,19 @@ class Feature:
Aside from the methods, the only feature attributes that distributions look
at are 'description' and 'optional'.
"""
@staticmethod
def warn_deprecated():
warnings.warn(
"Features are deprecated and will be removed in a future "
"version. See http://bitbucket.org/pypa/setuptools/65.",
DeprecationWarning,
stacklevel=3,
)
def __init__(self, description, standard=False, available=True,
optional=True, require_features=(), remove=(), **extras
):
optional=True, require_features=(), remove=(), **extras):
self.warn_deprecated()
self.description = description
self.standard = standard
......@@ -847,8 +759,6 @@ class Feature:
for f in self.require_features:
dist.include_feature(f)
def exclude_from(self,dist):
"""Ensure feature is excluded from distribution
......@@ -865,8 +775,6 @@ class Feature:
for item in self.remove:
dist.exclude_package(item)
def validate(self,dist):
"""Verify that feature makes sense in context of distribution
......@@ -886,7 +794,3 @@ class Feature:
" doesn't contain any packages or modules under %s"
% (self.description, item, item)
)
"""PyPI and direct package downloading"""
import sys, os.path, re, shutil, random, socket
import itertools
import sys
import os
import re
import shutil
import socket
import base64
from pkg_resources import (
CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST,
require, Environment, find_distributions, safe_name, safe_version,
to_filename, Requirement, DEVELOP_DIST,
)
from setuptools import ssl_support
from pkg_resources import *
from distutils import log
from distutils.errors import DistutilsError
from setuptools.compat import (urllib2, httplib, StringIO, HTTPError,
urlparse, urlunparse, unquote, splituser,
url2pathname, name2codepoint,
unichr, urljoin)
unichr, urljoin, urlsplit, urlunsplit)
from setuptools.compat import filterfalse
from fnmatch import translate
from setuptools.py24compat import hashlib
from setuptools.py24compat import wraps
from setuptools.py26compat import strip_fragment
from setuptools.py27compat import get_all_headers
EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$')
......@@ -105,9 +114,10 @@ def distros_for_filename(filename, metadata=None):
)
def interpret_distro_name(location, basename, metadata,
py_version=None, precedence=SOURCE_DIST, platform=None
):
def interpret_distro_name(
location, basename, metadata, py_version=None, precedence=SOURCE_DIST,
platform=None
):
"""Generate alternative interpretations of a source distro name
Note: if `location` is a filesystem filename, you should call
......@@ -222,6 +232,7 @@ class HashChecker(ContentChecker):
)
def __init__(self, hash_name, expected):
self.hash_name = hash_name
self.hash = hashlib.new(hash_name)
self.expected = expected
......@@ -242,30 +253,16 @@ class HashChecker(ContentChecker):
def is_valid(self):
return self.hash.hexdigest() == self.expected
def _get_hash_name(self):
"""
Python 2.4 implementation of MD5 doesn't supply a .name attribute
so provide that name.
When Python 2.4 is no longer required, replace invocations of this
method with simply 'self.hash.name'.
"""
try:
return self.hash.name
except AttributeError:
if 'md5' in str(type(self.hash)):
return 'md5'
raise
def report(self, reporter, template):
msg = template % self._get_hash_name()
msg = template % self.hash_name
return reporter(msg)
class PackageIndex(Environment):
"""A distribution index that scans web pages for download URLs"""
def __init__(self, index_url="https://pypi.python.org/simple", hosts=('*',),
def __init__(
self, index_url="https://pypi.python.org/simple", hosts=('*',),
ca_bundle=None, verify_ssl=True, *args, **kw
):
Environment.__init__(self,*args,**kw)
......@@ -347,7 +344,8 @@ class PackageIndex(Environment):
s = URL_SCHEME(url)
if (s and s.group(1).lower()=='file') or self.allows(urlparse(url)[1]):
return True
msg = "\nLink to % s ***BLOCKED*** by --allow-hosts\n"
msg = ("\nNote: Bypassing %s (disallowed host; see "
"http://bit.ly/1dg9ijs for details).\n")
if fatal:
raise DistutilsError(msg % url)
else:
......@@ -388,7 +386,7 @@ class PackageIndex(Environment):
# process an index page into the package-page index
for match in HREF.finditer(page):
try:
scan( urljoin(url, htmldecode(match.group(1))) )
scan(urljoin(url, htmldecode(match.group(1))))
except ValueError:
pass
......@@ -411,8 +409,6 @@ class PackageIndex(Environment):
else:
return "" # no sense double-scanning non-package pages
def need_version_info(self, url):
self.scan_all(
"Page at %s links to .py file(s) without version info; an index "
......@@ -443,17 +439,14 @@ class PackageIndex(Environment):
self.scan_url(url)
def obtain(self, requirement, installer=None):
self.prescan(); self.find_packages(requirement)
self.prescan()
self.find_packages(requirement)
for dist in self[requirement.key]:
if dist in requirement:
return dist
self.debug("%s does not match %s", requirement, dist)
return super(PackageIndex, self).obtain(requirement,installer)
def check_hash(self, checker, filename, tfp):
"""
checker is a ContentChecker
......@@ -539,10 +532,9 @@ class PackageIndex(Environment):
)
return getattr(self.fetch_distribution(spec, tmpdir),'location',None)
def fetch_distribution(self,
requirement, tmpdir, force_scan=False, source=False, develop_ok=False,
local_index=None
def fetch_distribution(
self, requirement, tmpdir, force_scan=False, source=False,
develop_ok=False, local_index=None
):
"""Obtain a distribution suitable for fulfilling `requirement`
......@@ -581,8 +573,6 @@ class PackageIndex(Environment):
if dist in req and (dist.precedence<=SOURCE_DIST or not source):
return dist
if force_scan:
self.prescan()
self.find_packages(requirement)
......@@ -609,7 +599,6 @@ class PackageIndex(Environment):
self.info("Best match: %s", dist)
return dist.clone(location=self.download(dist.location, tmpdir))
def fetch(self, requirement, tmpdir, force_scan=False, source=False):
"""Obtain a file suitable for fulfilling `requirement`
......@@ -623,10 +612,10 @@ class PackageIndex(Environment):
return dist.location
return None
def gen_setup(self, filename, fragment, tmpdir):
match = EGG_FRAGMENT.match(fragment)
dists = match and [d for d in
dists = match and [
d for d in
interpret_distro_name(filename, match.group(1), None) if d.version
] or []
......@@ -672,7 +661,7 @@ class PackageIndex(Environment):
fp, tfp, info = None, None, None
try:
checker = HashChecker.from_url(url)
fp = self.open_url(url)
fp = self.open_url(strip_fragment(url))
if isinstance(fp, HTTPError):
raise DistutilsError(
"Can't download %s: %s %s" % (url, fp.code,fp.msg)
......@@ -732,9 +721,11 @@ class PackageIndex(Environment):
if warning:
self.warn(warning, v.line)
else:
raise DistutilsError('%s returned a bad status line. '
'The server might be down, %s' % \
(url, v.line))
raise DistutilsError(
'%s returned a bad status line. The server might be '
'down, %s' %
(url, v.line)
)
except httplib.HTTPException:
v = sys.exc_info()[1]
if warning:
......@@ -775,7 +766,6 @@ class PackageIndex(Environment):
def scan_url(self, url):
self.process_url(url, True)
def _attempt_download(self, url, filename):
headers = self._download_to(url, filename)
if 'html' in headers.get('content-type','').lower():
......@@ -798,21 +788,6 @@ class PackageIndex(Environment):
os.unlink(filename)
raise DistutilsError("Unexpected HTML page found at "+url)
def _download_svn(self, url, filename):
url = url.split('#',1)[0] # remove any fragment for svn's sake
creds = ''
......@@ -833,7 +808,8 @@ class PackageIndex(Environment):
os.system("svn checkout%s -q %s %s" % (creds, url, filename))
return filename
def _vcs_split_rev_from_url(self, url, pop_prefix=False):
@staticmethod
def _vcs_split_rev_from_url(url, pop_prefix=False):
scheme, netloc, path, query, frag = urlsplit(url)
scheme = scheme.split('+', 1)[-1]
......@@ -891,18 +867,6 @@ class PackageIndex(Environment):
def warn(self, msg, *args):
log.warn(msg, *args)
# This pattern matches a character entity reference (a decimal numeric
# references, a hexadecimal numeric reference, or a named reference).
entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub
......@@ -927,20 +891,6 @@ def htmldecode(text):
"""Decode HTML entities in the given text."""
return entity_sub(decode_entity, text)
def socket_timeout(timeout=15):
def _socket_timeout(func):
def _socket_timeout(*args, **kwargs):
......@@ -1009,15 +959,6 @@ def open_with_auth(url, opener=urllib2.urlopen):
open_with_auth = socket_timeout(_SOCKET_TIMEOUT)(open_with_auth)
def fix_sf_url(url):
return url # backward compatibility
......@@ -1047,17 +988,3 @@ def local_open(url):
return HTTPError(url, status, message,
{'content-type':'text/html'}, StringIO(body))
# this line is a kludge to keep the trailing blank lines for pje's editor
"""
Compatibility Support for Python 2.6 and earlier
"""
import sys
from setuptools.compat import splittag
def strip_fragment(url):
"""
In `Python 8280 <http://bugs.python.org/issue8280>`_, Python 2.7 and
later was patched to disregard the fragment when making URL requests.
Do the same for Python 2.6 and earlier.
"""
url, fragment = splittag(url)
return url
if sys.version_info >= (2,7):
strip_fragment = lambda x: x
# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r
__requires__ = """%(spec)r"""
from pkg_resources import require; require("""%(spec)r""")
import sys
from pkg_resources import require
require("""%(spec)r""")
del require
__file__ = """%(dev_path)r"""
try:
if sys.version_info < (3, 0):
execfile(__file__)
except NameError:
else:
exec(compile(open(__file__).read(), __file__, 'exec'))
......@@ -194,6 +194,12 @@ class VerifyingHTTPSConn(HTTPSConnection):
sock = create_connection(
(self.host, self.port), getattr(self,'source_address',None)
)
# Handle the socket if a (proxy) tunnel is present
if hasattr(self, '_tunnel') and getattr(self, '_tunnel_host', None):
self.sock = sock
self._tunnel()
self.sock = ssl.wrap_socket(
sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_bundle
)
......
# -*- coding: utf-8 -*-
result = 'passed'
......@@ -14,7 +14,7 @@ import distutils.core
from setuptools.compat import StringIO, BytesIO, next, urlparse
from setuptools.sandbox import run_setup, SandboxViolation
from setuptools.command.easy_install import easy_install, fix_jython_executable, get_script_args
from setuptools.command.easy_install import easy_install, fix_jython_executable, get_script_args, nt_quote_arg
from setuptools.command.easy_install import PthDistributions
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
......@@ -52,7 +52,7 @@ if __name__ == '__main__':
sys.exit(
load_entry_point('spec', 'console_scripts', 'name')()
)
""" % fix_jython_executable(sys.executable, "")
""" % nt_quote_arg(fix_jython_executable(sys.executable, ""))
SETUP_PY = """\
from setuptools import setup
......
......@@ -142,6 +142,15 @@ class TestPackageIndex(unittest.TestCase):
self.assertEqual(setuptools.package_index.parse_bdist_wininst(
'reportlab-2.5.win-amd64.exe'), ('reportlab-2.5', None, 'win-amd64'))
def test__vcs_split_rev_from_url(self):
"""
Test the basic usage of _vcs_split_rev_from_url
"""
vsrfu = setuptools.package_index.PackageIndex._vcs_split_rev_from_url
url, rev = vsrfu('https://example.com/bar@2995')
self.assertEqual(url, 'https://example.com/bar')
self.assertEqual(rev, '2995')
class TestContentCheckers(unittest.TestCase):
def test_md5(self):
......@@ -169,11 +178,7 @@ class TestContentCheckers(unittest.TestCase):
def test_get_hash_name_md5(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
if sys.version_info >= (2,5):
self.assertEqual(checker.hash.name, 'md5')
else:
# Python 2.4 compatability
self.assertEqual(checker._get_hash_name(), 'md5')
self.assertEqual(checker.hash_name, 'md5')
def test_report(self):
checker = setuptools.package_index.HashChecker.from_url(
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
# NOTE: the shebang and encoding lines are for ScriptHeaderTests; do not remove
from unittest import TestCase, makeSuite; from pkg_resources import *
from setuptools.command.easy_install import get_script_header, is_sh
# NOTE: the shebang and encoding lines are for ScriptHeaderTests do not remove
import os
import sys
import tempfile
import shutil
from unittest import TestCase
import pkg_resources
from pkg_resources import (parse_requirements, VersionConflict, parse_version,
Distribution, EntryPoint, Requirement, safe_version, safe_name,
WorkingSet)
from setuptools.command.easy_install import (get_script_header, is_sh,
nt_quote_arg)
from setuptools.compat import StringIO, iteritems
import os, pkg_resources, sys, tempfile, shutil
try: frozenset
try:
frozenset
except NameError:
from sets import ImmutableSet as frozenset
......@@ -15,11 +28,11 @@ def safe_repr(obj, short=False):
result = repr(obj)
except Exception:
result = object.__repr__(obj)
if not short or len(result) < _MAX_LENGTH:
if not short or len(result) < pkg_resources._MAX_LENGTH:
return result
return result[:_MAX_LENGTH] + ' [truncated]...'
return result[:pkg_resources._MAX_LENGTH] + ' [truncated]...'
class Metadata(EmptyProvider):
class Metadata(pkg_resources.EmptyProvider):
"""Mock object to return metadata as if from an on-disk distribution"""
def __init__(self,*pairs):
......@@ -32,18 +45,20 @@ class Metadata(EmptyProvider):
return self.metadata[name]
def get_metadata_lines(self,name):
return yield_lines(self.get_metadata(name))
return pkg_resources.yield_lines(self.get_metadata(name))
dist_from_fn = pkg_resources.Distribution.from_filename
class DistroTests(TestCase):
def testCollection(self):
# empty path should produce no distributions
ad = Environment([], platform=None, python=None)
ad = pkg_resources.Environment([], platform=None, python=None)
self.assertEqual(list(ad), [])
self.assertEqual(ad['FooPkg'],[])
ad.add(Distribution.from_filename("FooPkg-1.3_1.egg"))
ad.add(Distribution.from_filename("FooPkg-1.4-py2.4-win32.egg"))
ad.add(Distribution.from_filename("FooPkg-1.2-py2.4.egg"))
ad.add(dist_from_fn("FooPkg-1.3_1.egg"))
ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg"))
ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg"))
# Name is in there now
self.assertTrue(ad['FooPkg'])
......@@ -60,27 +75,33 @@ class DistroTests(TestCase):
[dist.version for dist in ad['FooPkg']], ['1.4','1.2']
)
# And inserting adds them in order
ad.add(Distribution.from_filename("FooPkg-1.9.egg"))
ad.add(dist_from_fn("FooPkg-1.9.egg"))
self.assertEqual(
[dist.version for dist in ad['FooPkg']], ['1.9','1.4','1.2']
)
ws = WorkingSet([])
foo12 = Distribution.from_filename("FooPkg-1.2-py2.4.egg")
foo14 = Distribution.from_filename("FooPkg-1.4-py2.4-win32.egg")
foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg")
foo14 = dist_from_fn("FooPkg-1.4-py2.4-win32.egg")
req, = parse_requirements("FooPkg>=1.3")
# Nominal case: no distros on path, should yield all applicable
self.assertEqual(ad.best_match(req,ws).version, '1.9')
# If a matching distro is already installed, should return only that
ws.add(foo14); self.assertEqual(ad.best_match(req,ws).version, '1.4')
ws.add(foo14)
self.assertEqual(ad.best_match(req,ws).version, '1.4')
# If the first matching distro is unsuitable, it's a version conflict
ws = WorkingSet([]); ws.add(foo12); ws.add(foo14)
ws = WorkingSet([])
ws.add(foo12)
ws.add(foo14)
self.assertRaises(VersionConflict, ad.best_match, req, ws)
# If more than one match on the path, the first one takes precedence
ws = WorkingSet([]); ws.add(foo14); ws.add(foo12); ws.add(foo14);
ws = WorkingSet([])
ws.add(foo14)
ws.add(foo12)
ws.add(foo14)
self.assertEqual(ad.best_match(req,ws).version, '1.4')
def checkFooPkg(self,d):
......@@ -103,9 +124,9 @@ class DistroTests(TestCase):
self.assertEqual(d.platform, None)
def testDistroParse(self):
d = Distribution.from_filename("FooPkg-1.3_1-py2.4-win32.egg")
d = dist_from_fn("FooPkg-1.3_1-py2.4-win32.egg")
self.checkFooPkg(d)
d = Distribution.from_filename("FooPkg-1.3_1-py2.4-win32.egg-info")
d = dist_from_fn("FooPkg-1.3_1-py2.4-win32.egg-info")
self.checkFooPkg(d)
def testDistroMetadata(self):
......@@ -117,7 +138,6 @@ class DistroTests(TestCase):
)
self.checkFooPkg(d)
def distRequires(self, txt):
return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
......@@ -131,20 +151,21 @@ class DistroTests(TestCase):
for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0":
self.checkRequires(self.distRequires(v), v)
def testResolve(self):
ad = Environment([]); ws = WorkingSet([])
ad = pkg_resources.Environment([])
ws = WorkingSet([])
# Resolving no requirements -> nothing to install
self.assertEqual( list(ws.resolve([],ad)), [] )
self.assertEqual(list(ws.resolve([],ad)), [])
# Request something not in the collection -> DistributionNotFound
self.assertRaises(
DistributionNotFound, ws.resolve, parse_requirements("Foo"), ad
pkg_resources.DistributionNotFound, ws.resolve, parse_requirements("Foo"), ad
)
Foo = Distribution.from_filename(
"/foo_dir/Foo-1.2.egg",
metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0"))
)
ad.add(Foo); ad.add(Distribution.from_filename("Foo-0.9.egg"))
ad.add(Foo)
ad.add(Distribution.from_filename("Foo-0.9.egg"))
# Request thing(s) that are available -> list to activate
for i in range(3):
......@@ -157,7 +178,7 @@ class DistroTests(TestCase):
# Request an extra that causes an unresolved dependency for "Baz"
self.assertRaises(
DistributionNotFound, ws.resolve,parse_requirements("Foo[bar]"), ad
pkg_resources.DistributionNotFound, ws.resolve,parse_requirements("Foo[bar]"), ad
)
Baz = Distribution.from_filename(
"/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo"))
......@@ -169,9 +190,8 @@ class DistroTests(TestCase):
list(ws.resolve(parse_requirements("Foo[bar]"), ad)), [Foo,Baz]
)
# Requests for conflicting versions produce VersionConflict
self.assertRaises( VersionConflict,
ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad
)
self.assertRaises(VersionConflict,
ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
def testDistroDependsOptions(self):
d = self.distRequires("""
......@@ -196,7 +216,7 @@ class DistroTests(TestCase):
d,"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
["fastcgi", "docgen"]
)
self.assertRaises(UnknownExtra, d.requires, ["foo"])
self.assertRaises(pkg_resources.UnknownExtra, d.requires, ["foo"])
class EntryPointTests(TestCase):
......@@ -321,7 +341,6 @@ class RequirementsTests(TestCase):
for v in ('1.2c1','1.3.1','1.5','1.9.1','2.0','2.5','3.0','4.0'):
self.assertTrue(v not in r, (v,r))
def testOptionsAndHashing(self):
r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
......@@ -366,15 +385,6 @@ class RequirementsTests(TestCase):
Requirement.parse('setuptools >= 0.7').project_name, 'setuptools')
class ParseTests(TestCase):
def testEmptyParse(self):
......@@ -388,9 +398,7 @@ class ParseTests(TestCase):
self.assertEqual(list(pkg_resources.yield_lines(inp)),out)
def testSplitting(self):
self.assertEqual(
list(
pkg_resources.split_sections("""
sample = """
x
[Y]
z
......@@ -403,8 +411,7 @@ class ParseTests(TestCase):
[q]
v
"""
)
),
self.assertEqual(list(pkg_resources.split_sections(sample)),
[(None,["x"]), ("Y",["z","a"]), ("b",["c"]), ("d",[]), ("q",["v"])]
)
self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo"))
......@@ -455,7 +462,8 @@ class ParseTests(TestCase):
c('0pre1', '0.0c1')
c('0.0.0preview1', '0c1')
c('0.0c1', '0-rc1')
c('1.2a1', '1.2.a.1'); c('1.2...a', '1.2a')
c('1.2a1', '1.2.a.1')
c('1.2...a', '1.2a')
def testVersionOrdering(self):
def c(s1,s2):
......@@ -492,25 +500,25 @@ class ParseTests(TestCase):
c(v2,v1)
class ScriptHeaderTests(TestCase):
non_ascii_exe = '/Users/José/bin/python'
exe_with_spaces = r'C:\Program Files\Python33\python.exe'
def test_get_script_header(self):
if not sys.platform.startswith('java') or not is_sh(sys.executable):
# This test is for non-Jython platforms
expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable))
self.assertEqual(get_script_header('#!/usr/local/bin/python'),
'#!%s\n' % os.path.normpath(sys.executable))
expected)
expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable))
self.assertEqual(get_script_header('#!/usr/bin/python -x'),
'#!%s -x\n' % os.path.normpath(sys.executable))
expected)
self.assertEqual(get_script_header('#!/usr/bin/python',
executable=self.non_ascii_exe),
'#!%s -x\n' % self.non_ascii_exe)
candidate = get_script_header('#!/usr/bin/python',
executable=self.exe_with_spaces)
self.assertEqual(candidate, '#!"%s"\n' % self.exe_with_spaces)
def test_get_script_header_jython_workaround(self):
# This test doesn't work with Python 3 in some locales
......@@ -554,8 +562,6 @@ class ScriptHeaderTests(TestCase):
sys.stdout, sys.stderr = stdout, stderr
class NamespaceTests(TestCase):
def setUp(self):
......@@ -611,5 +617,4 @@ class NamespaceTests(TestCase):
# check the __path__ attribute contains both paths
self.assertEqual(pkg1.pkg2.__path__, [
os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"),
os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2") ])
os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2")])
......@@ -5,7 +5,10 @@ import os
import shutil
import unittest
import tempfile
import types
import pkg_resources
import setuptools.sandbox
from setuptools.sandbox import DirectorySandbox, SandboxViolation
def has_win32com():
......@@ -62,5 +65,15 @@ class TestSandbox(unittest.TestCase):
finally:
if os.path.exists(target): os.remove(target)
def test_setup_py_with_BOM(self):
"""
It should be possible to execute a setup.py with a Byte Order Mark
"""
target = pkg_resources.resource_filename(__name__,
'script-with-bom.py')
namespace = types.ModuleType('namespace')
setuptools.sandbox.execfile(target, vars(namespace))
assert namespace.result == 'passed'
if __name__ == '__main__':
unittest.main()
__version__ = '1.1.7'
......@@ -341,8 +341,8 @@ Environment Markers
>>> print(im("sys_platform"))
Comparison or logical expression expected
>>> print(im("sys_platform==")) # doctest: +ELLIPSIS
unexpected EOF while parsing (...line 1)
>>> print(im("sys_platform=="))
invalid syntax
>>> print(im("sys_platform=='win32'"))
False
......@@ -353,8 +353,8 @@ Environment Markers
>>> print(im("(extra)"))
Comparison or logical expression expected
>>> print(im("(extra")) # doctest: +ELLIPSIS
unexpected EOF while parsing (...line 1)
>>> print(im("(extra"))
invalid syntax
>>> print(im("os.open('foo')=='y'"))
Language feature not supported in environment markers
......
#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
raise NotImplementedError('Py3 not supported in this test yet')
import sys
import os
import shutil
import tempfile
import subprocess
from distutils.command.install import INSTALL_SCHEMES
from string import Template
from setuptools.compat import urlopen
try:
import subprocess
def _system_call(*args):
def _system_call(*args):
assert subprocess.call(args) == 0
except ImportError:
# Python 2.3
def _system_call(*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]
assert os.system(' '.join(args)) == 0
def tempdir(func):
def _tempdir(*args, **kwargs):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment