Commit 4d4dbd3c authored by Jason R. Coombs's avatar Jason R. Coombs

Merge with master

--HG--
branch : feature/issue-229
parents c5fa0382 2c33dad0
......@@ -157,3 +157,6 @@ a1fc0220bfa3581158688789f6dfdc00672eb99b 5.6
755cbfd3743ffb186cdf7e20be8e61dbdaa22503 6.0
bc6655b4acf205dd9f25c702955645656077398a 6.0.1
1ae2a75724bbba56373784f185a7f235ed0f24a4 6.0.2b1
01271e84e5125fcc4f0f368a6e21116a5722953c 6.0.2
7ea80190d494a766c6356fce85c844703964b6cc 6.1
df26609c2f614f5fc9110342e4003ee8bd95cf84 7.0
......@@ -9,8 +9,7 @@ python:
# command to run tests
script:
- export PYTHONPATH=`pwd`/six-*.egg
# testing fix for https://bitbucket.org/hpk42/pytest/issue/555
- pip install --pre -i https://devpi.net/hpk/dev/ --upgrade pytest
- python setup.py egg_info
- python setup.py test
- python setup.py ptr
- python ez_setup.py --version 5.4.1
......@@ -2,6 +2,30 @@
CHANGES
=======
---
7.0
---
* Issue #80, Issue #209: Eggs that are downloaded for ``setup_requires``,
``test_requires``, etc. are now placed in a ``./.eggs`` directory instead of
directly in the current directory. This choice of location means the files
can be readily managed (removed, ignored). Additionally,
later phases or invocations of setuptools will not detect the package as
already installed and ignore it for permanent install (See #209).
This change is indicated as backward-incompatible as installations that
depend on the installation in the current directory will need to account for
the new location. Systems that ignore ``*.egg`` will probably need to be
adapted to ignore ``.eggs``. The files will need to be manually moved or
will be retrieved again. Most use cases will require no attention.
---
6.1
---
* Issue #268: When resolving package versions, a VersionConflict now reports
which package previously required the conflicting version.
-----
6.0.2
-----
......
......@@ -153,7 +153,6 @@ learning about Setuptools, Python Eggs, and EasyInstall:
* `The EasyInstall user's guide and reference manual`_
* `The setuptools Developer's Guide`_
* `The pkg_resources API reference`_
* `Package Compatibility Notes`_ (user-maintained)
* `The Internal Structure of Python Eggs`_
Questions, comments, and bug reports should be directed to the `distutils-sig
......@@ -164,7 +163,6 @@ them there, so this reference list can be updated. If you have working,
the `setuptools bug tracker`_.
.. _setuptools bug tracker: https://bitbucket.org/pypa/setuptools/issues
.. _Package Compatibility Notes: https://pythonhosted.org/setuptools/PackageNotes
.. _The Internal Structure of Python Eggs: https://pythonhosted.org/setuptools/formats.html
.. _The setuptools Developer's Guide: https://pythonhosted.org/setuptools/setuptools.html
.. _The pkg_resources API reference: https://pythonhosted.org/setuptools/pkg_resources.html
......
"""
If setuptools is not already installed in the environment, it's not possible
to invoke setuptools' own commands. This routine will bootstrap this local
environment by creating a minimal egg-info directory and then invoking the
egg-info command to flesh out the egg-info directory.
"""
import os
import sys
import textwrap
import subprocess
minimal_egg_info = textwrap.dedent("""
[distutils.commands]
egg_info = setuptools.command.egg_info:egg_info
[distutils.setup_keywords]
include_package_data = setuptools.dist:assert_bool
install_requires = setuptools.dist:check_requirements
extras_require = setuptools.dist:check_extras
entry_points = setuptools.dist:check_entry_points
[egg_info.writers]
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
""")
def ensure_egg_info():
if not os.path.exists('setuptools.egg-info'):
build_egg_info()
def build_egg_info():
"""
Build a minimal egg-info, enough to invoke egg_info
"""
os.mkdir('setuptools.egg-info')
with open('setuptools.egg-info/entry_points.txt', 'w') as ep:
ep.write(minimal_egg_info)
def run_egg_info():
subprocess.check_call([sys.executable, 'setup.py', 'egg_info'])
if __name__ == '__main__':
ensure_egg_info()
run_egg_info()
......@@ -473,7 +473,7 @@ script called ``baz``, you might do something like this::
setup(
# other arguments here...
entry_points = {
entry_points={
'console_scripts': [
'foo = my_package.some_module:main_func',
'bar = other_module:some_func',
......
......@@ -36,7 +36,7 @@ try:
except ImportError:
USER_SITE = None
DEFAULT_VERSION = "6.0.2"
DEFAULT_VERSION = "7.1"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args):
......
......@@ -590,6 +590,10 @@ class WorkingSet(object):
best = {}
to_activate = []
# Mapping of requirement to set of distributions that required it;
# useful for reporting info about conflicts.
required_by = collections.defaultdict(set)
while requirements:
# process dependencies breadth-first
req = requirements.pop(0)
......@@ -623,9 +627,18 @@ class WorkingSet(object):
to_activate.append(dist)
if dist not in req:
# Oops, the "best" so far conflicts with a dependency
# XXX put more info here
raise VersionConflict(dist, req)
requirements.extend(dist.requires(req.extras)[::-1])
tmpl = "%s is installed but %s is required by %s"
args = dist, req, list(required_by.get(req, []))
raise VersionConflict(tmpl % args)
# push the new requirements onto the stack
new_requirements = dist.requires(req.extras)[::-1]
requirements.extend(new_requirements)
# Register the new requirements needed by req
for new_requirement in new_requirements:
required_by[new_requirement].add(req.project_name)
processed[req] = True
# return list of distros to activate
......
https://pypi.python.org/packages/source/c/certifi/certifi-1.0.1.tar.gz#md5=45f5cb94b8af9e1df0f9450a8f61b790
https://pypi.python.org/packages/source/w/wincertstore/wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2
[console_scripts]
easy_install = setuptools.command.easy_install:main
easy_install-3.4 = setuptools.command.easy_install:main
[distutils.commands]
alias = setuptools.command.alias:alias
bdist_egg = setuptools.command.bdist_egg:bdist_egg
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst
build_ext = setuptools.command.build_ext:build_ext
build_py = setuptools.command.build_py:build_py
develop = setuptools.command.develop:develop
easy_install = setuptools.command.easy_install:easy_install
egg_info = setuptools.command.egg_info:egg_info
install = setuptools.command.install:install
install_egg_info = setuptools.command.install_egg_info:install_egg_info
install_lib = setuptools.command.install_lib:install_lib
install_scripts = setuptools.command.install_scripts:install_scripts
register = setuptools.command.register:register
rotate = setuptools.command.rotate:rotate
saveopts = setuptools.command.saveopts:saveopts
sdist = setuptools.command.sdist:sdist
setopt = setuptools.command.setopt:setopt
test = setuptools.command.test:test
upload_docs = setuptools.command.upload_docs:upload_docs
[distutils.setup_keywords]
convert_2to3_doctests = setuptools.dist:assert_string_list
dependency_links = setuptools.dist:assert_string_list
eager_resources = setuptools.dist:assert_string_list
entry_points = setuptools.dist:check_entry_points
exclude_package_data = setuptools.dist:check_package_data
extras_require = setuptools.dist:check_extras
include_package_data = setuptools.dist:assert_bool
install_requires = setuptools.dist:check_requirements
namespace_packages = setuptools.dist:check_nsp
package_data = setuptools.dist:check_package_data
packages = setuptools.dist:check_packages
setup_requires = setuptools.dist:check_requirements
test_loader = setuptools.dist:check_importable
test_runner = setuptools.dist:check_importable
test_suite = setuptools.dist:check_test_suite
tests_require = setuptools.dist:check_requirements
use_2to3 = setuptools.dist:assert_bool
use_2to3_exclude_fixers = setuptools.dist:assert_string_list
use_2to3_fixers = setuptools.dist:assert_string_list
zip_safe = setuptools.dist:assert_bool
[egg_info.writers]
PKG-INFO = setuptools.command.egg_info:write_pkg_info
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
depends.txt = setuptools.command.egg_info:warn_depends_obsolete
eager_resources.txt = setuptools.command.egg_info:overwrite_arg
entry_points.txt = setuptools.command.egg_info:write_entries
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
requires.txt = setuptools.command.egg_info:write_requirements
top_level.txt = setuptools.command.egg_info:write_toplevel_names
[setuptools.file_finders]
svn_cvs = setuptools.command.sdist:_default_revctrl
[setuptools.installation]
eggsecutable = setuptools.command.easy_install:bootstrap
six>=1.5
[certs]
certifi==1.0.1
[ssl:sys_platform=='win32']
wincertstore==0.2
......@@ -140,7 +140,7 @@ def findall(dir = os.curdir):
(relative to 'dir').
"""
all_files = []
for base, dirs, files in os.walk(dir):
for base, dirs, files in os.walk(dir, followlinks=True):
if base==os.curdir or base.startswith(os.curdir+os.sep):
base = base[2:]
if base:
......@@ -149,7 +149,3 @@ def findall(dir = os.curdir):
return all_files
distutils.filelist.findall = findall # fix findall bug in distutils.
# sys.dont_write_bytecode was introduced in Python 2.6.
_dont_write_bytecode = getattr(sys, 'dont_write_bytecode',
bool(os.environ.get("PYTHONDONTWRITEBYTECODE")))
......@@ -38,7 +38,7 @@ import struct
import six
from six.moves import configparser
from setuptools import Command, _dont_write_bytecode
from setuptools import Command
from setuptools.sandbox import run_setup
from setuptools.py31compat import get_path, get_config_vars
from setuptools.command import setopt
......@@ -1153,7 +1153,7 @@ See the setuptools documentation for the "develop" command for more info.
chmod(f, mode)
def byte_compile(self, to_compile):
if _dont_write_bytecode:
if sys.dont_write_bytecode:
self.warn('byte-compiling is disabled, skipping.')
return
......
......@@ -16,6 +16,7 @@ from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
import six
from setuptools.depends import Require
from setuptools import windows_support
import pkg_resources
def _get_unpatched(cls):
......@@ -306,6 +307,21 @@ class Distribution(_Distribution):
else:
self.convert_2to3_doctests = []
def get_egg_cache_dir(self):
egg_cache_dir = os.path.join(os.curdir, '.eggs')
if not os.path.exists(egg_cache_dir):
os.mkdir(egg_cache_dir)
windows_support.hide_file(egg_cache_dir)
readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt')
with open(readme_txt_filename, 'w') as f:
f.write('This directory contains eggs that were downloaded '
'by setuptools to build, test, and run plug-ins.\n\n')
f.write('This directory caches those eggs to prevent '
'repeated downloads.\n\n')
f.write('However, it is safe to delete this directory.\n\n')
return egg_cache_dir
def fetch_build_egg(self, req):
"""Fetch an egg needed for building"""
......@@ -329,8 +345,9 @@ class Distribution(_Distribution):
if 'find_links' in opts:
links = opts['find_links'][1].split() + links
opts['find_links'] = ('setup', links)
install_dir = self.get_egg_cache_dir()
cmd = easy_install(
dist, args=["x"], install_dir=os.curdir, exclude_scripts=True,
dist, args=["x"], install_dir=install_dir, exclude_scripts=True,
always_copy=False, build_directory=None, editable=False,
upgrade=False, multi_version=True, no_report=True, user=False
)
......
......@@ -299,7 +299,7 @@ class SvnInfo(object):
self._externals = None
def get_revision(self):
'Retrieve the directory revision informatino using svnversion'
'Retrieve the directory revision information using svnversion'
code, data = _run_command(['svnversion', '-c', self.path])
if code:
log.warn("svnversion failed")
......
......@@ -10,57 +10,6 @@ import unicodedata
from subprocess import Popen as _Popen, PIPE as _PIPE
def _extract(self, member, path=None, pwd=None):
"""for zipfile py2.5 borrowed from cpython"""
if not isinstance(member, zipfile.ZipInfo):
member = self.getinfo(member)
if path is None:
path = os.getcwd()
return _extract_member(self, member, path, pwd)
def _extract_from_zip(self, name, dest_path):
dest_file = open(dest_path, 'wb')
try:
dest_file.write(self.read(name))
finally:
dest_file.close()
def _extract_member(self, member, targetpath, pwd):
"""for zipfile py2.5 borrowed from cpython"""
# build the destination pathname, replacing
# forward slashes to platform specific separators.
# Strip trailing path separator, unless it represents the root.
if (targetpath[-1:] in (os.path.sep, os.path.altsep)
and len(os.path.splitdrive(targetpath)[1]) > 1):
targetpath = targetpath[:-1]
# don't include leading "/" from file name if present
if member.filename[0] == '/':
targetpath = os.path.join(targetpath, member.filename[1:])
else:
targetpath = os.path.join(targetpath, member.filename)
targetpath = os.path.normpath(targetpath)
# Create all upper directories if necessary.
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
if member.filename[-1] == '/':
if not os.path.isdir(targetpath):
os.mkdir(targetpath)
return targetpath
_extract_from_zip(self, member.filename, targetpath)
return targetpath
def _remove_dir(target):
#on windows this seems to a problem
......@@ -92,7 +41,7 @@ class ZippedEnvironment(unittest.TestCase):
try:
zip_file = zipfile.ZipFile(self.datafile)
for files in zip_file.namelist():
_extract(zip_file, files, self.temp_dir)
zip_file.extract(files, self.temp_dir)
finally:
if zip_file:
zip_file.close()
......@@ -147,10 +96,13 @@ def run_setup_py(cmd, pypath=None, path=None,
cmd = [sys.executable, "setup.py"] + list(cmd)
#regarding the shell argument, see: http://bugs.python.org/issue8557
# http://bugs.python.org/issue8557
shell = sys.platform == 'win32'
try:
proc = _Popen(cmd, stdout=_PIPE, stderr=_PIPE,
shell=(sys.platform == 'win32'), env=env)
proc = _Popen(
cmd, stdout=_PIPE, stderr=_PIPE, shell=shell, env=env,
)
data = proc.communicate()[data_stream]
except OSError:
......@@ -158,7 +110,8 @@ def run_setup_py(cmd, pypath=None, path=None,
#decode the console string if needed
if hasattr(data, "decode"):
data = data.decode() # should use the preffered encoding
# use the default encoding
data = data.decode()
data = unicodedata.normalize('NFC', data)
#communciate calls wait()
......
......@@ -34,7 +34,7 @@ class TestEggInfo(unittest.TestCase):
entries_f = open(fn, 'wb')
entries_f.write(entries)
entries_f.close()
@skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
def test_version_10_format(self):
"""
......@@ -140,7 +140,7 @@ class TestSvnDummy(environment.ZippedEnvironment):
@skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
def test_svn_tags(self):
code, data = environment.run_setup_py(["egg_info",
code, data = environment.run_setup_py(["egg_info",
"--tag-svn-revision"],
pypath=self.old_cwd,
data_stream=1)
......
__version__ = '6.0.2'
__version__ = '7.1'
import platform
import ctypes
def windows_only(func):
if platform.system() != 'Windows':
return lambda *args, **kwargs: None
return func
@windows_only
def hide_file(path):
"""
Set the hidden attribute on a file or directory.
From http://stackoverflow.com/questions/19622133/
`path` must be text.
"""
__import__('ctypes.wintypes')
SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW
SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD
SetFileAttributes.restype = ctypes.wintypes.BOOL
FILE_ATTRIBUTE_HIDDEN = 0x02
ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN)
if not ret:
raise ctypes.WinError()
......@@ -2,4 +2,4 @@
envlist = py26,py27,py31,py32,py33,py34
[testenv]
deps=pytest
commands=py.test
commands=py.test {posargs}
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