Commit 7a5642d5 authored by Jason R. Coombs's avatar Jason R. Coombs

Merge with master

parents 2c729473 d559b45b
# syntax: glob
bin
build
dist
include
lib
distribute.egg-info
setuptools.egg-info
.coverage
.tox
CHANGES (links).txt
*.egg
*.py[cod]
*.swp
*~
.hg*
syntax: glob
*.pyc
*~
*.swp
.coverage
distribute.egg-info
setuptools.egg-info
bin
build
dist
lib
bin
include
\.Python
*.swp
lib
distribute.egg-info
setuptools.egg-info
.coverage
.tox
CHANGES (links).txt
*.egg
*.py[cod]
*.swp
*~
.git*
......@@ -140,3 +140,9 @@ e94e768594a1405efde0b79cc60549dd8a4cda9a 3.6
2fa97c06cc013a9c82f4c1219711e72238d5b6e6 3.8
9b422fc0b8b97cdb62f02d754283f747adef7f83 3.7.1
40744de29b848f0e88139ba91d645c08a56855e9 3.8.1
84d936fd18a93d16c46e68ee2e39f5733f3cd863 5.0
871bd7b4326f48860ebe0baccdaea8fe4f8f8583 5.0.1
95996b713722376679c3168b15ab12ea8360dd5f 5.0.2
3a948b6d01e3449b478fcdc532c44eb3cea5ee10 5.1
f493e6c4ffd88951871110858c141385305e0077 5.2
1f9505cfd7524ce0c83ab31d139f47b39c56ccbe 5.3
......@@ -3,20 +3,77 @@ CHANGES
=======
---
3.9
5.4
---
* Issue #154: Cache the reading of the zip file index for cases where the
same zip-file is used for multiple packages (like PEX).
---------------
3.7.1 and 3.8.1
---------------
---
5.3
---
* Issue #185: Make svn tagging work on the new style SVN metadata.
Thanks cazabon!
* Prune revision control directories (e.g .svn) from base path
as well as sub-directories.
---
5.2
---
* Added a `Developer Guide
<https://pythonhosted.org/setuptools/developer-guide.html>`_ to the official
documentation.
* Some code refactoring and cleanup was done with no intended behavioral
changes.
* During install_egg_info, the generated lines for namespace package .pth
files are now processed even during a dry run.
---
5.1
---
* Issue #202: Implemented more robust cache invalidation for the ZipImporter,
building on the work in Issue #168. Special thanks to Jurko Gospodnetic and
PJE.
-----
5.0.2
-----
* Issue #220: Restored script templates.
-----
5.0.1
-----
* Renamed script templates to end with .tmpl now that they no longer need
to be processed by 2to3. Fixes spurious syntax errors during build/install.
---
5.0
---
* Issue #218: Re-release of 3.8.1 to signal that it supersedes 4.x.
* Incidentally, script templates were updated not to include the triple-quote
escaping.
-------------------------
3.7.1 and 3.8.1 and 4.0.1
-------------------------
* Issue #213: Use legacy StringIO behavior for compatibility under pbr.
* Issue #218: Setuptools 3.8.1 superseded 4.0.1, and 4.x was removed
from the available versions to install.
---
4.0
---
* Issue #210: ``setup.py develop`` now copies scripts in binary mode rather
than text mode, matching the behavior of the ``install`` command.
---
3.8
---
......
============================
Quick notes for contributors
============================
Setuptools is developed using the DVCS Mercurial.
Grab the code at bitbucket::
$ hg clone https://bitbucket.org/pypa/setuptools
If you want to contribute changes, we recommend you fork the repository on
bitbucket, commit the changes to your repository, and then make a pull request
on bitbucket. If you make some changes, don't forget to:
- add a note in CHANGES.txt
Please commit bug-fixes against the current maintenance branch and new
features to the default branch.
You can run the tests via::
$ python setup.py test
The canonical development guide can be found in docs/developer-guide.txt.
================================
Developer's Guide for Setuptools
================================
If you want to know more about contributing on Setuptools, this is the place.
.. contents:: **Table of Contents**
-------------------
Recommended Reading
-------------------
Please read `How to write the perfect pull request
<http://blog.jaraco.com/2014/04/how-to-write-perfect-pull-request.html>`_
for some tips on contributing to open source projects. Although the article
is not authoritative, it was authored by the maintainer of Setuptools, so
reflects his opinions and will improve the likelihood of acceptance and
quality of contribution.
------------------
Project Management
------------------
Setuptools is maintained primarily in Bitbucket at `this home
<https://bitbucket.org/pypa/setuptools>`_. Setuptools is maintained under the
Python Packaging Authority (PyPA) with several core contributors. All bugs
for Setuptools are filed and the canonical source is maintained in Bitbucket.
User support and discussions are done through the issue tracker (for specific)
issues, through the distutils-sig mailing list, or on IRC (Freenode) at
#pypa.
Discussions about development happen on the pypa-dev mailing list or on IRC
(Freenode) at #pypa-dev.
-----------------
Authoring Tickets
-----------------
Before authoring any source code, it's often prudent to file a ticket
describing the motivation behind making changes. First search to see if a
ticket already exists for your issue. If not, create one. Try to think from
the perspective of the reader. Explain what behavior you expected, what you
got instead, and what factors might have contributed to the unexpected
behavior. In Bitbucket, surround a block of code or traceback with the triple
backtick "```" so that it is formatted nicely.
Filing a ticket provides a forum for justification, discussion, and
clarification. The ticket provides a record of the purpose for the change and
any hard decisions that were made. It provides a single place for others to
reference when trying to understand why the software operates the way it does
or why certain changes were made.
Setuptools makes extensive use of hyperlinks to tickets in the changelog so
that system integrators and other users can get a quick summary, but then
jump to the in-depth discussion about any subject referenced.
-----------
Source Code
-----------
Grab the code at Bitbucket::
$ hg clone https://bitbucket.org/pypa/setuptools
If you want to contribute changes, we recommend you fork the repository on
Bitbucket, commit the changes to your repository, and then make a pull request
on Bitbucket. If you make some changes, don't forget to:
- add a note in CHANGES.txt
Please commit all changes in the 'default' branch against the latest available
commit or for bug-fixes, against an earlier commit or release in which the
bug occurred.
If you find yourself working on more than one issue at a time, Setuptools
generally prefers Git-style branches, so use Mercurial bookmarks or Git
branches or multiple forks to maintain separate efforts.
Setuptools also maintains an unofficial `Git mirror in Github
<https://github.com/jaraco/setuptools>`_. Contributors are welcome to submit
pull requests here, but because they are not integrated with the Bitbucket
Issue tracker, linking pull requests to tickets is more difficult. The
Continuous Integration tests that validate every release are run from this
mirror.
-------
Testing
-------
The primary tests are run using py.test. To run the tests::
$ python setup.py ptr
Or install py.test into your environment and run ``py.test``.
Under continuous integration, additional tests may be run. See the
``.travis.yml`` file for full details on the tests run under Travis-CI.
-------------------
Semantic Versioning
-------------------
Setuptools follows ``semver`` with some exceptions:
- Uses two-segment version when three segment version ends in zero
- Omits 'v' prefix for tags.
.. explain value of reflecting meaning in versions.
......@@ -30,6 +30,7 @@ setuptools changes. You have been warned.
.. toctree::
:maxdepth: 1
developer-guide
formats
releases
......@@ -12,7 +12,15 @@ the release process.
A Setuptools release manager must have maintainer access on PyPI to the
project and administrative access to the BitBucket project.
To make a release, run the following from a Mercurial checkout at the
revision slated for release::
python -m jaraco.packaging.release
Release Managers
----------------
Currently, the project has one release manager, Jason R. Coombs.
Jason R. Coombs is the primary release manager. Additionally, the following
people have access to create releases:
- Matthew Iversen (Ivoz)
......@@ -36,7 +36,7 @@ try:
except ImportError:
USER_SITE = None
DEFAULT_VERSION = "3.8.2"
DEFAULT_VERSION = "5.4"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args):
......
......@@ -22,3 +22,4 @@ universal=1
[pytest]
addopts=--ignore tests/manual_test.py --ignore tests/shlib_test
norecursedirs=dist build *.egg
......@@ -90,17 +90,18 @@ class test(_test):
readme_file = io.open('README.txt', encoding='utf-8')
# the release script adds hyperlinks to issues
if os.path.exists('CHANGES (links).txt'):
changes_file = open('CHANGES (links).txt')
else:
# but if the release script has not run, fall back to the source file
changes_file = open('CHANGES.txt')
# The release script adds hyperlinks to issues,
# but if the release script has not run, fall back to the source file
changes_names = 'CHANGES (links).txt', 'CHANGES.txt'
changes_fn = next(iter(filter(os.path.exists, changes_names)))
changes_file = io.open(changes_fn, encoding='utf-8')
with readme_file:
with changes_file:
long_description = readme_file.read() + '\n' + changes_file.read()
package_data = {'setuptools': ['site-patch.py']}
package_data = {
'setuptools': ['script (dev).tmpl', 'script.tmpl', 'site-patch.py']}
force_windows_specific_files = (
os.environ.get("SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES")
not in (None, "", "0")
......
......@@ -5,10 +5,11 @@ __all__ = [
'register', 'bdist_wininst', 'upload_docs',
]
from setuptools.command import install_scripts
from distutils.command.bdist import bdist
import sys
from distutils.command.bdist import bdist
from setuptools.command import install_scripts
if 'egg' not in bdist.format_commands:
bdist.format_command['egg'] = ('bdist_egg', "Python .egg file")
......
......@@ -2,10 +2,12 @@ from distutils.errors import DistutilsOptionError
from setuptools.command.setopt import edit_config, option_base, config_file
def shquote(arg):
"""Quote an argument for later parsing by shlex.split()"""
for c in '"', "'", "\\", "#":
if c in arg: return repr(arg)
if c in arg:
return repr(arg)
if arg.split() != [arg]:
return repr(arg)
return arg
......@@ -18,7 +20,7 @@ class alias(option_base):
command_consumes_arguments = True
user_options = [
('remove', 'r', 'remove (unset) the alias'),
('remove', 'r', 'remove (unset) the alias'),
] + option_base.user_options
boolean_options = option_base.boolean_options + ['remove']
......@@ -46,7 +48,7 @@ class alias(option_base):
print("setup.py alias", format_alias(alias, aliases))
return
elif len(self.args)==1:
elif len(self.args) == 1:
alias, = self.args
if self.remove:
command = None
......@@ -58,9 +60,9 @@ class alias(option_base):
return
else:
alias = self.args[0]
command = ' '.join(map(shquote,self.args[1:]))
command = ' '.join(map(shquote, self.args[1:]))
edit_config(self.filename, {'aliases': {alias:command}}, self.dry_run)
edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run)
def format_alias(name, aliases):
......@@ -73,4 +75,4 @@ def format_alias(name, aliases):
source = ''
else:
source = '--filename=%r' % source
return source+name+' '+command
return source + name + ' ' + command
This diff is collapsed.
import distutils.command.bdist_rpm as orig
class bdist_rpm(orig.bdist_rpm):
"""
Override the default bdist_rpm behavior to do the following:
......@@ -19,7 +20,7 @@ class bdist_rpm(orig.bdist_rpm):
def _make_spec_file(self):
version = self.distribution.get_version()
rpmversion = version.replace('-','_')
rpmversion = version.replace('-', '_')
spec = orig.bdist_rpm._make_spec_file(self)
line23 = '%define version ' + version
line24 = '%define version ' + rpmversion
......
import distutils.command.bdist_wininst as orig
class bdist_wininst(orig.bdist_wininst):
def reinitialize_command(self, command, reinit_subcommands=0):
"""
......
This diff is collapsed.
from glob import glob
from distutils.util import convert_path
import distutils.command.build_py as orig
import os
import sys
import fnmatch
import textwrap
import distutils.command.build_py as orig
from distutils.util import convert_path
from glob import glob
try:
from setuptools.lib2to3_ex import Mixin2to3
......@@ -13,6 +13,7 @@ except ImportError:
def run_2to3(self, files, doctests=True):
"do nothing"
class build_py(orig.build_py, Mixin2to3):
"""Enhanced 'build_py' command that includes data files with packages
......@@ -22,11 +23,14 @@ class build_py(orig.build_py, Mixin2to3):
Also, this version of the 'build_py' command allows you to specify both
'py_modules' and 'packages' in the same setup operation.
"""
def finalize_options(self):
orig.build_py.finalize_options(self)
self.package_data = self.distribution.package_data
self.exclude_package_data = self.distribution.exclude_package_data or {}
if 'data_files' in self.__dict__: del self.__dict__['data_files']
self.exclude_package_data = (self.distribution.exclude_package_data or
{})
if 'data_files' in self.__dict__:
del self.__dict__['data_files']
self.__updated_files = []
self.__doctests_2to3 = []
......@@ -51,13 +55,14 @@ class build_py(orig.build_py, Mixin2to3):
self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0))
def __getattr__(self, attr):
if attr=='data_files': # lazily compute data files
if attr == 'data_files': # lazily compute data files
self.data_files = files = self._get_data_files()
return files
return orig.build_py.__getattr__(self,attr)
return orig.build_py.__getattr__(self, attr)
def build_module(self, module, module_file, package):
outfile, copied = orig.build_py.build_module(self, module, module_file, package)
outfile, copied = orig.build_py.build_module(self, module, module_file,
package)
if copied:
self.__updated_files.append(outfile)
return outfile, copied
......@@ -74,12 +79,12 @@ class build_py(orig.build_py, Mixin2to3):
build_dir = os.path.join(*([self.build_lib] + package.split('.')))
# Length of path to strip from found files
plen = len(src_dir)+1
plen = len(src_dir) + 1
# Strip directory from globbed filenames
filenames = [
file[plen:] for file in self.find_data_files(package, src_dir)
]
]
data.append((package, src_dir, build_dir, filenames))
return data
......@@ -102,7 +107,8 @@ class build_py(orig.build_py, Mixin2to3):
srcfile = os.path.join(src_dir, filename)
outf, copied = self.copy_file(srcfile, target)
srcfile = os.path.abspath(srcfile)
if copied and srcfile in self.distribution.convert_2to3_doctests:
if (copied and
srcfile in self.distribution.convert_2to3_doctests):
self.__doctests_2to3.append(outf)
def analyze_manifest(self):
......@@ -117,21 +123,22 @@ class build_py(orig.build_py, Mixin2to3):
self.run_command('egg_info')
ei_cmd = self.get_finalized_command('egg_info')
for path in ei_cmd.filelist.files:
d,f = os.path.split(assert_relative(path))
d, f = os.path.split(assert_relative(path))
prev = None
oldf = f
while d and d!=prev and d not in src_dirs:
while d and d != prev and d not in src_dirs:
prev = d
d, df = os.path.split(d)
f = os.path.join(df, f)
if d in src_dirs:
if path.endswith('.py') and f==oldf:
continue # it's a module, not data
mf.setdefault(src_dirs[d],[]).append(path)
if path.endswith('.py') and f == oldf:
continue # it's a module, not data
mf.setdefault(src_dirs[d], []).append(path)
def get_data_files(self): pass # kludge 2.4 for lazy computation
def get_data_files(self):
pass # kludge 2.4 for lazy computation
if sys.version<"2.4": # Python 2.4 already has this code
if sys.version < "2.4": # Python 2.4 already has this code
def get_outputs(self, include_bytecode=1):
"""Return complete list of files copied to the build directory
......@@ -142,9 +149,9 @@ class build_py(orig.build_py, Mixin2to3):
"""
return orig.build_py.get_outputs(self, include_bytecode) + [
os.path.join(build_dir, filename)
for package, src_dir, build_dir,filenames in self.data_files
for package, src_dir, build_dir, filenames in self.data_files
for filename in filenames
]
]
def check_package(self, package, package_dir):
"""Check namespace packages' __init__ for declare_namespace"""
......@@ -160,25 +167,26 @@ class build_py(orig.build_py, Mixin2to3):
return init_py
for pkg in self.distribution.namespace_packages:
if pkg==package or pkg.startswith(package+'.'):
if pkg == package or pkg.startswith(package + '.'):
break
else:
return init_py
f = open(init_py,'rbU')
f = open(init_py, 'rbU')
if 'declare_namespace'.encode() not in f.read():
from distutils.errors import DistutilsError
raise DistutilsError(
"Namespace package problem: %s is a namespace package, but its\n"
"__init__.py does not call declare_namespace()! Please fix it.\n"
'(See the setuptools manual under "Namespace Packages" for '
"details.)\n" % (package,)
"Namespace package problem: %s is a namespace package, but "
"its\n__init__.py does not call declare_namespace()! Please "
'fix it.\n(See the setuptools manual under '
'"Namespace Packages" for details.)\n"' % (package,)
)
f.close()
return init_py
def initialize_options(self):
self.packages_checked={}
self.packages_checked = {}
orig.build_py.initialize_options(self)
def get_package_dir(self, package):
......@@ -202,7 +210,7 @@ class build_py(orig.build_py, Mixin2to3):
seen = {}
return [
f for f in files if f not in bad
and f not in seen and seen.setdefault(f,1) # ditch dupes
and f not in seen and seen.setdefault(f, 1) # ditch dupes
]
......@@ -210,6 +218,7 @@ def assert_relative(path):
if not os.path.isabs(path):
return path
from distutils.errors import DistutilsSetupError
msg = textwrap.dedent("""
Error: setup script specifies an absolute path:
......
import os
import glob
from distutils.util import convert_path
from distutils import log
from distutils.errors import DistutilsError, DistutilsOptionError
import os
import glob
import setuptools
from pkg_resources import Distribution, PathMetadata, normalize_path
from setuptools.command.easy_install import easy_install
from setuptools.compat import PY3
import setuptools
class develop(easy_install):
"""Set up package for development"""
......@@ -36,7 +37,7 @@ class develop(easy_install):
self.egg_path = None
easy_install.initialize_options(self)
self.setup_path = None
self.always_copy_from = '.' # always copy eggs installed in curdir
self.always_copy_from = '.' # always copy eggs installed in curdir
def finalize_options(self):
ei = self.get_finalized_command("egg_info")
......@@ -52,29 +53,31 @@ class develop(easy_install):
# pick up setup-dir .egg files only: no .egg-info
self.package_index.scan(glob.glob('*.egg'))
self.egg_link = os.path.join(self.install_dir, ei.egg_name+'.egg-link')
self.egg_link = os.path.join(self.install_dir, ei.egg_name +
'.egg-link')
self.egg_base = ei.egg_base
if self.egg_path is None:
self.egg_path = os.path.abspath(ei.egg_base)
target = normalize_path(self.egg_base)
egg_path = normalize_path(os.path.join(self.install_dir, self.egg_path))
egg_path = normalize_path(os.path.join(self.install_dir,
self.egg_path))
if egg_path != target:
raise DistutilsOptionError(
"--egg-path must be a relative path from the install"
" directory to "+target
" directory to " + target
)
# Make a distribution for the package's source
self.dist = Distribution(
target,
PathMetadata(target, os.path.abspath(ei.egg_info)),
project_name = ei.egg_name
project_name=ei.egg_name
)
p = self.egg_base.replace(os.sep,'/')
if p!= os.curdir:
p = '../' * (p.count('/')+1)
p = self.egg_base.replace(os.sep, '/')
if p != os.curdir:
p = '../' * (p.count('/') + 1)
self.setup_path = p
p = normalize_path(os.path.join(self.install_dir, self.egg_path, p))
if p != normalize_path(os.curdir):
......@@ -103,7 +106,8 @@ class develop(easy_install):
ei_cmd = self.get_finalized_command("egg_info")
self.egg_path = build_path
self.dist.location = build_path
self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info) # XXX
# XXX
self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info)
else:
# Without 2to3 inplace works fine:
self.run_command('egg_info')
......@@ -120,7 +124,7 @@ class develop(easy_install):
# create an .egg-link in the installation dir, pointing to our egg
log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
if not self.dry_run:
f = open(self.egg_link,"w")
f = open(self.egg_link, "w")
f.write(self.egg_path + "\n" + self.setup_path)
f.close()
# postprocess the installed distro, fixing up .pth, installing scripts,
......@@ -133,7 +137,8 @@ class develop(easy_install):
egg_link_file = open(self.egg_link)
contents = [line.rstrip() for line in egg_link_file]
egg_link_file.close()
if contents not in ([self.egg_path], [self.egg_path, self.setup_path]):
if contents not in ([self.egg_path],
[self.egg_path, self.setup_path]):
log.warn("Link points to %s: uninstall aborted", contents)
return
if not self.dry_run:
......@@ -147,7 +152,7 @@ class develop(easy_install):
def install_egg_scripts(self, dist):
if dist is not self.dist:
# Installing a dependency, so fall back to normal behavior
return easy_install.install_egg_scripts(self,dist)
return easy_install.install_egg_scripts(self, dist)
# create wrapper scripts in the script dir, pointing to dist.scripts
......@@ -158,7 +163,7 @@ class develop(easy_install):
for script_name in self.distribution.scripts or []:
script_path = os.path.abspath(convert_path(script_name))
script_name = os.path.basename(script_path)
f = open(script_path,'rU')
f = open(script_path, 'rU')
script_text = f.read()
f.close()
self.install_script(dist, script_name, script_text, script_path)
This diff is collapsed.
This diff is collapsed.
import setuptools
from distutils.errors import DistutilsArgError
import inspect
import glob
import warnings
import platform
import distutils.command.install as orig
from distutils.errors import DistutilsArgError
import setuptools
# Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for
# now. See https://bitbucket.org/pypa/setuptools/issue/199/
# now. See https://bitbucket.org/pypa/setuptools/issue/199/
_install = orig.install
class install(orig.install):
"""Use easy_install to install the package, w/dependencies"""
user_options = orig.install.user_options + [
('old-and-unmanageable', None, "Try not to use this!"),
('single-version-externally-managed', None,
"used by system package builders to create 'flat' eggs"),
"used by system package builders to create 'flat' eggs"),
]
boolean_options = orig.install.boolean_options + [
'old-and-unmanageable', 'single-version-externally-managed',
......@@ -115,7 +117,9 @@ class install(orig.install):
cmd.run()
setuptools.bootstrap_install_from = None
# XXX Python 3.1 doesn't see _nc if this is inside the class
install.sub_commands = [
cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc
] + install.new_commands
install.sub_commands = (
[cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] +
install.new_commands
)
from distutils import log, dir_util
import os
from setuptools import Command
from setuptools.archive_util import unpack_archive
from distutils import log, dir_util
import os, pkg_resources
import pkg_resources
class install_egg_info(Command):
"""Install an .egg-info directory for the package"""
......@@ -16,26 +19,26 @@ class install_egg_info(Command):
self.install_dir = None
def finalize_options(self):
self.set_undefined_options('install_lib',('install_dir','install_dir'))
self.set_undefined_options('install_lib',
('install_dir', 'install_dir'))
ei_cmd = self.get_finalized_command("egg_info")
basename = pkg_resources.Distribution(
None, None, ei_cmd.egg_name, ei_cmd.egg_version
).egg_name()+'.egg-info'
).egg_name() + '.egg-info'
self.source = ei_cmd.egg_info
self.target = os.path.join(self.install_dir, basename)
self.outputs = [self.target]
def run(self):
self.run_command('egg_info')
target = self.target
if os.path.isdir(self.target) and not os.path.islink(self.target):
dir_util.remove_tree(self.target, dry_run=self.dry_run)
elif os.path.exists(self.target):
self.execute(os.unlink,(self.target,),"Removing "+self.target)
self.execute(os.unlink, (self.target,), "Removing " + self.target)
if not self.dry_run:
pkg_resources.ensure_directory(self.target)
self.execute(self.copytree, (),
"Copying %s to %s" % (self.source, self.target)
self.execute(
self.copytree, (), "Copying %s to %s" % (self.source, self.target)
)
self.install_namespaces()
......@@ -44,82 +47,70 @@ class install_egg_info(Command):
def copytree(self):
# Copy the .egg-info tree to site-packages
def skimmer(src,dst):
def skimmer(src, dst):
# filter out source-control directories; note that 'src' is always
# a '/'-separated path, regardless of platform. 'dst' is a
# platform-specific path.
for skip in '.svn/','CVS/':
if src.startswith(skip) or '/'+skip in src:
for skip in '.svn/', 'CVS/':
if src.startswith(skip) or '/' + skip in src:
return None
self.outputs.append(dst)
log.debug("Copying %s to %s", src, dst)
return dst
unpack_archive(self.source, self.target, skimmer)
unpack_archive(self.source, self.target, skimmer)
def install_namespaces(self):
nsp = self._get_all_ns_packages()
if not nsp: return
filename,ext = os.path.splitext(self.target)
filename += '-nspkg.pth'; self.outputs.append(filename)
log.info("Installing %s",filename)
if not self.dry_run:
f = open(filename,'wt')
for pkg in nsp:
# ensure pkg is not a unicode string under Python 2.7
pkg = str(pkg)
pth = tuple(pkg.split('.'))
trailer = '\n'
if '.' in pkg:
trailer = (
"; m and setattr(sys.modules[%r], %r, m)\n"
% ('.'.join(pth[:-1]), pth[-1])
)
f.write(
"import sys,types,os; "
"p = os.path.join(sys._getframe(1).f_locals['sitedir'], "
"*%(pth)r); "
"ie = os.path.exists(os.path.join(p,'__init__.py')); "
"m = not ie and "
"sys.modules.setdefault(%(pkg)r,types.ModuleType(%(pkg)r)); "
"mp = (m or []) and m.__dict__.setdefault('__path__',[]); "
"(p not in mp) and mp.append(p)%(trailer)s"
% locals()
)
f.close()
if not nsp:
return
filename, ext = os.path.splitext(self.target)
filename += '-nspkg.pth'
self.outputs.append(filename)
log.info("Installing %s", filename)
lines = map(self._gen_nspkg_line, nsp)
if self.dry_run:
# always generate the lines, even in dry run
list(lines)
return
with open(filename, 'wt') as f:
f.writelines(lines)
_nspkg_tmpl = (
"import sys, types, os",
"p = os.path.join(sys._getframe(1).f_locals['sitedir'], *%(pth)r)",
"ie = os.path.exists(os.path.join(p,'__init__.py'))",
"m = not ie and "
"sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))",
"mp = (m or []) and m.__dict__.setdefault('__path__',[])",
"(p not in mp) and mp.append(p)",
)
"lines for the namespace installer"
_nspkg_tmpl_multi = (
'm and setattr(sys.modules[%(parent)r], %(child)r, m)',
)
"additional line(s) when a parent package is indicated"
@classmethod
def _gen_nspkg_line(cls, pkg):
# ensure pkg is not a unicode string under Python 2.7
pkg = str(pkg)
pth = tuple(pkg.split('.'))
tmpl_lines = cls._nspkg_tmpl
parent, sep, child = pkg.rpartition('.')
if parent:
tmpl_lines += cls._nspkg_tmpl_multi
return ';'.join(tmpl_lines) % locals() + '\n'
def _get_all_ns_packages(self):
nsp = {}
"""Return sorted list of all package namespaces"""
nsp = set()
for pkg in self.distribution.namespace_packages or []:
pkg = pkg.split('.')
while pkg:
nsp['.'.join(pkg)] = 1
nsp.add('.'.join(pkg))
pkg.pop()
nsp=list(nsp)
nsp.sort() # set up shorter names first
return nsp
return sorted(nsp)
import distutils.command.install_lib as orig
import os
class install_lib(orig.install_lib):
"""Don't add compiled flags to filenames of non-Python files"""
......@@ -15,20 +16,20 @@ class install_lib(orig.install_lib):
exclude = {}
nsp = self.distribution.namespace_packages
svem = (nsp and self.get_finalized_command('install')
.single_version_externally_managed)
.single_version_externally_managed)
if svem:
for pkg in nsp:
parts = pkg.split('.')
while parts:
pkgdir = os.path.join(self.install_dir, *parts)
for f in '__init__.py', '__init__.pyc', '__init__.pyo':
exclude[os.path.join(pkgdir,f)] = 1
exclude[os.path.join(pkgdir, f)] = 1
parts.pop()
return exclude
def copy_tree(
self, infile, outfile,
preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1
self, infile, outfile,
preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1
):
assert preserve_mode and preserve_times and not preserve_symlinks
exclude = self.get_exclusions()
......@@ -45,7 +46,8 @@ class install_lib(orig.install_lib):
def pf(src, dst):
if dst in exclude:
log.warn("Skipping installation of %s (namespace package)",dst)
log.warn("Skipping installation of %s (namespace package)",
dst)
return False
log.info("copying %s -> %s", src, os.path.dirname(dst))
......
from distutils import log
import distutils.command.install_scripts as orig
from pkg_resources import Distribution, PathMetadata, ensure_directory
import os
from distutils import log
from pkg_resources import Distribution, PathMetadata, ensure_directory
class install_scripts(orig.install_scripts):
"""Do normal script install, plus any egg_info wrapper scripts"""
......@@ -29,7 +31,7 @@ class install_scripts(orig.install_scripts):
ei_cmd.egg_name, ei_cmd.egg_version,
)
bs_cmd = self.get_finalized_command('build_scripts')
executable = getattr(bs_cmd,'executable',sys_executable)
executable = getattr(bs_cmd, 'executable', sys_executable)
is_wininst = getattr(
self.get_finalized_command("bdist_wininst"), '_is_running', False
)
......@@ -39,6 +41,7 @@ class install_scripts(orig.install_scripts):
def write_script(self, script_name, contents, mode="t", *ignored):
"""Write an executable file to the scripts directory"""
from setuptools.command.easy_install import chmod, current_umask
log.info("Installing %s script to %s", script_name, self.install_dir)
target = os.path.join(self.install_dir, script_name)
self.outfiles.append(target)
......@@ -46,7 +49,7 @@ class install_scripts(orig.install_scripts):
mask = current_umask()
if not self.dry_run:
ensure_directory(target)
f = open(target,"w"+mode)
f = open(target, "w" + mode)
f.write(contents)
f.close()
chmod(target, 0o777-mask)
chmod(target, 0o777 - mask)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="%(name)s"
type="win32"/>
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="%(name)s"
type="win32"/>
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
import distutils.command.register as orig
class register(orig.register):
__doc__ = orig.register.__doc__
......
import os
from setuptools import Command
from setuptools.compat import basestring
from distutils.util import convert_path
from distutils import log
from distutils.errors import DistutilsOptionError
import os
from setuptools import Command
from setuptools.compat import basestring
class rotate(Command):
"""Delete older distributions"""
description = "delete older distributions, keeping N newest files"
user_options = [
('match=', 'm', "patterns to match (required)"),
('match=', 'm', "patterns to match (required)"),
('dist-dir=', 'd', "directory where the distributions are"),
('keep=', 'k', "number of matching distributions to keep"),
('keep=', 'k', "number of matching distributions to keep"),
]
boolean_options = []
......@@ -38,21 +40,22 @@ class rotate(Command):
self.match = [
convert_path(p.strip()) for p in self.match.split(',')
]
self.set_undefined_options('bdist',('dist_dir', 'dist_dir'))
self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
def run(self):
self.run_command("egg_info")
from glob import glob
for pattern in self.match:
pattern = self.distribution.get_name()+'*'+pattern
files = glob(os.path.join(self.dist_dir,pattern))
files = [(os.path.getmtime(f),f) for f in files]
pattern = self.distribution.get_name() + '*' + pattern
files = glob(os.path.join(self.dist_dir, pattern))
files = [(os.path.getmtime(f), f) for f in files]
files.sort()
files.reverse()
log.info("%d file(s) matching %s", len(files), pattern)
files = files[self.keep:]
for (t,f) in files:
for (t, f) in files:
log.info("Deleting %s", f)
if not self.dry_run:
os.unlink(f)
import distutils, os
from setuptools import Command
from setuptools.command.setopt import edit_config, option_base
class saveopts(option_base):
"""Save command-line options to a file"""
......@@ -13,12 +12,11 @@ class saveopts(option_base):
for cmd in dist.command_options:
if cmd=='saveopts':
continue # don't save our own options!
if cmd == 'saveopts':
continue # don't save our own options!
for opt,(src,val) in dist.get_option_dict(cmd).items():
if src=="command line":
settings.setdefault(cmd,{})[opt] = val
for opt, (src, val) in dist.get_option_dict(cmd).items():
if src == "command line":
settings.setdefault(cmd, {})[opt] = val
edit_config(self.filename, settings, self.dry_run)
from glob import glob
from distutils.util import convert_path
from distutils import log
import distutils.command.sdist as orig
import os
import re
import sys
from glob import glob
import pkg_resources
import distutils.command.sdist as orig
from distutils.util import convert_path
from distutils import log
from setuptools import svn_utils
from setuptools.compat import PY3
import pkg_resources
READMES = ('README', 'README.rst', 'README.txt')
......@@ -20,7 +20,7 @@ def walk_revctrl(dirname=''):
yield item
#TODO will need test case
# TODO will need test case
class re_finder(object):
"""
Finder that locates files based on entries in a file matched by a
......@@ -33,7 +33,7 @@ class re_finder(object):
self.entries_path = convert_path(path)
def _finder(self, dirname, filename):
f = open(filename,'rU')
f = open(filename, 'rU')
try:
data = f.read()
finally:
......@@ -51,12 +51,13 @@ class re_finder(object):
if not os.path.isfile(path):
# entries file doesn't exist
return
for path in self._finder(dirname,path):
for path in self._finder(dirname, path):
if os.path.isfile(path):
yield path
elif os.path.isdir(path):
for item in self.find(path):
yield item
__call__ = find
......@@ -85,7 +86,7 @@ class sdist(orig.sdist):
('dist-dir=', 'd',
"directory to put the source distribution archive(s) in "
"[default: dist]"),
]
]
negative_opt = {}
......@@ -93,7 +94,7 @@ class sdist(orig.sdist):
self.run_command('egg_info')
ei_cmd = self.get_finalized_command('egg_info')
self.filelist = ei_cmd.filelist
self.filelist.append(os.path.join(ei_cmd.egg_info,'SOURCES.txt'))
self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))
self.check_readme()
# Run sub commands
......@@ -103,12 +104,13 @@ class sdist(orig.sdist):
# Call check_metadata only if no 'check' command
# (distutils <= 2.6)
import distutils.command
if 'check' not in distutils.command.__all__:
self.check_metadata()
self.make_distribution()
dist_files = getattr(self.distribution,'dist_files',[])
dist_files = getattr(self.distribution, 'dist_files', [])
for file in self.archive_files:
data = ('sdist', '', file)
if data not in dist_files:
......@@ -124,13 +126,14 @@ class sdist(orig.sdist):
except:
sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close()
raise
# 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.
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)
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
......@@ -194,7 +197,8 @@ class sdist(orig.sdist):
return
else:
self.warn(
"standard file not found: should have one of " +', '.join(READMES)
"standard file not found: should have one of " +
', '.join(READMES)
)
def make_release_tree(self, base_dir, files):
......@@ -202,7 +206,7 @@ class sdist(orig.sdist):
# Save any egg_info command line options used to create this sdist
dest = os.path.join(base_dir, 'setup.cfg')
if hasattr(os,'link') and os.path.exists(dest):
if hasattr(os, 'link') and os.path.exists(dest):
# unlink and re-copy, since it might be hard-linked, and
# we don't want to change the source version
os.unlink(dest)
......@@ -220,7 +224,8 @@ class sdist(orig.sdist):
first_line = fp.readline()
finally:
fp.close()
return first_line != '# file GENERATED by distutils, do NOT edit\n'.encode()
return (first_line !=
'# file GENERATED by distutils, do NOT edit\n'.encode())
def read_manifest(self):
"""Read the manifest file (named by 'self.manifest') and use it to
......
import os
import distutils
from setuptools import Command
from distutils.util import convert_path
from distutils import log
from distutils.errors import DistutilsOptionError
import distutils
import os
from setuptools import Command
__all__ = ['config_file', 'edit_config', 'option_base', 'setopt']
......@@ -13,19 +15,20 @@ def config_file(kind="local"):
`kind` must be one of "local", "global", or "user"
"""
if kind=='local':
if kind == 'local':
return 'setup.cfg'
if kind=='global':
if kind == 'global':
return os.path.join(
os.path.dirname(distutils.__file__),'distutils.cfg'
os.path.dirname(distutils.__file__), 'distutils.cfg'
)
if kind=='user':
dot = os.name=='posix' and '.' or ''
if kind == 'user':
dot = os.name == 'posix' and '.' or ''
return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot))
raise ValueError(
"config_file() type must be 'local', 'global', or 'user'", kind
)
def edit_config(filename, settings, dry_run=False):
"""Edit a configuration file to include `settings`
......@@ -35,6 +38,7 @@ def edit_config(filename, settings, dry_run=False):
A setting of ``None`` means to delete that setting.
"""
from setuptools.compat import ConfigParser
log.debug("Reading configuration from %s", filename)
opts = ConfigParser.RawConfigParser()
opts.read([filename])
......@@ -46,39 +50,40 @@ def edit_config(filename, settings, dry_run=False):
if not opts.has_section(section):
log.debug("Adding new section [%s] to %s", section, filename)
opts.add_section(section)
for option,value in options.items():
for option, value in options.items():
if value is None:
log.debug(
"Deleting %s.%s from %s",
section, option, filename
)
opts.remove_option(section,option)
opts.remove_option(section, option)
if not opts.options(section):
log.info("Deleting empty [%s] section from %s",
section, filename)
section, filename)
opts.remove_section(section)
else:
log.debug(
"Setting %s.%s to %r in %s",
section, option, value, filename
)
opts.set(section,option,value)
opts.set(section, option, value)
log.info("Writing %s", filename)
if not dry_run:
with open(filename, 'w') as f:
opts.write(f)
class option_base(Command):
"""Abstract base class for commands that mess with config files"""
user_options = [
('global-config', 'g',
"save options to the site-wide distutils.cfg file"),
"save options to the site-wide distutils.cfg file"),
('user-config', 'u',
"save options to the current user's pydistutils.cfg file"),
"save options to the current user's pydistutils.cfg file"),
('filename=', 'f',
"configuration file to use (default=setup.cfg)"),
"configuration file to use (default=setup.cfg)"),
]
boolean_options = [
......@@ -100,7 +105,7 @@ class option_base(Command):
filenames.append(self.filename)
if not filenames:
filenames.append(config_file('local'))
if len(filenames)>1:
if len(filenames) > 1:
raise DistutilsOptionError(
"Must specify only one configuration file option",
filenames
......@@ -115,9 +120,9 @@ class setopt(option_base):
user_options = [
('command=', 'c', 'command to set an option for'),
('option=', 'o', 'option to set'),
('set-value=', 's', 'value of the option'),
('remove', 'r', 'remove (unset) the value'),
('option=', 'o', 'option to set'),
('set-value=', 's', 'value of the option'),
('remove', 'r', 'remove (unset) the value'),
] + option_base.user_options
boolean_options = option_base.boolean_options + ['remove']
......@@ -139,7 +144,7 @@ class setopt(option_base):
def run(self):
edit_config(
self.filename, {
self.command: {self.option.replace('-','_'):self.set_value}
self.command: {self.option.replace('-', '_'): self.set_value}
},
self.dry_run
)
import unittest
from unittest import TestLoader
from setuptools import Command
from distutils.errors import DistutilsOptionError
from unittest import TestLoader
import unittest
import sys
from pkg_resources import (resource_listdir, resource_exists,
normalize_path, working_set, _namespace_packages, add_activation_listener,
require, EntryPoint)
from pkg_resources import (resource_listdir, resource_exists, normalize_path,
working_set, _namespace_packages,
add_activation_listener, require, EntryPoint)
from setuptools import Command
from setuptools.compat import PY3
from setuptools.py31compat import unittest_main
class ScanningLoader(TestLoader):
def loadTestsFromModule(self, module):
"""Return a suite of all tests cases contained in the given module
......@@ -34,7 +32,7 @@ class ScanningLoader(TestLoader):
submodule = module.__name__ + '.' + file[:-3]
else:
if resource_exists(module.__name__, file + '/__init__.py'):
submodule = module.__name__+'.'+file
submodule = module.__name__ + '.' + file
else:
continue
tests.append(self.loadTestsFromName(submodule))
......@@ -42,19 +40,18 @@ class ScanningLoader(TestLoader):
if len(tests) != 1:
return self.suiteClass(tests)
else:
return tests[0] # don't create a nested suite for only one return
return tests[0] # don't create a nested suite for only one return
class test(Command):
"""Command to run unit tests after in-place build"""
description = "run unit tests after in-place build"
user_options = [
('test-module=','m', "Run 'test_suite' in specified module"),
('test-suite=','s',
"Test suite to run (e.g. 'some_module.test_suite')"),
('test-module=', 'm', "Run 'test_suite' in specified module"),
('test-suite=', 's',
"Test suite to run (e.g. 'some_module.test_suite')"),
('test-runner=', 'r', "Test runner to use"),
]
......@@ -79,7 +76,7 @@ class test(Command):
self.test_args = [self.test_suite]
if self.verbose:
self.test_args.insert(0,'--verbose')
self.test_args.insert(0, '--verbose')
if self.test_loader is None:
self.test_loader = getattr(self.distribution, 'test_loader', None)
if self.test_loader is None:
......@@ -132,7 +129,8 @@ class test(Command):
def run(self):
if self.distribution.install_requires:
self.distribution.fetch_build_eggs(self.distribution.install_requires)
self.distribution.fetch_build_eggs(
self.distribution.install_requires)
if self.distribution.tests_require:
self.distribution.fetch_build_eggs(self.distribution.tests_require)
......@@ -161,7 +159,7 @@ class test(Command):
list(map(sys.modules.__delitem__, del_modules))
unittest_main(
None, None, [unittest.__file__]+self.test_args,
None, None, [unittest.__file__] + self.test_args,
testLoader=self._resolve_as_ep(self.test_loader),
testRunner=self._resolve_as_ep(self.test_runner),
)
......
......@@ -5,6 +5,10 @@ Implements a Distutils 'upload_docs' subcommand (upload documentation to
PyPI's pythonhosted.org).
"""
from base64 import standard_b64encode
from distutils import log
from distutils.errors import DistutilsOptionError
from distutils.command.upload import upload
import os
import socket
import zipfile
......@@ -12,14 +16,9 @@ import tempfile
import sys
import shutil
from base64 import standard_b64encode
from setuptools.compat import httplib, urlparse, unicode, iteritems, PY3
from pkg_resources import iter_entry_points
from distutils import log
from distutils.errors import DistutilsOptionError
from distutils.command.upload import upload
from setuptools.compat import httplib, urlparse, unicode, iteritems, PY3
errors = 'surrogateescape' if PY3 else 'strict'
......@@ -33,7 +32,6 @@ def b(s, encoding='utf-8'):
class upload_docs(upload):
description = 'Upload documentation to PyPI'
user_options = [
......@@ -42,7 +40,7 @@ class upload_docs(upload):
('show-response', None,
'display full response text from server'),
('upload-dir=', None, 'directory to upload'),
]
]
boolean_options = upload.boolean_options
def has_sphinx(self):
......@@ -159,7 +157,7 @@ class upload_docs(upload):
elif schema == 'https':
conn = httplib.HTTPSConnection(netloc)
else:
raise AssertionError("unsupported schema "+schema)
raise AssertionError("unsupported schema " + schema)
data = ''
try:
......@@ -190,4 +188,4 @@ class upload_docs(upload):
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
print('-'*75, r.read(), '-'*75)
print('-' * 75, r.read(), '-' * 75)
......@@ -280,12 +280,13 @@ class Distribution(_Distribution):
def fetch_build_eggs(self, requires):
"""Resolve pre-setup requirements"""
from pkg_resources import working_set, parse_requirements
for dist in working_set.resolve(
parse_requirements(requires), installer=self.fetch_build_egg,
replace_conflicting=True
):
working_set.add(dist, replace=True)
resolved_dists = pkg_resources.working_set.resolve(
pkg_resources.parse_requirements(requires),
installer=self.fetch_build_egg,
replace_conflicting=True,
)
for dist in resolved_dists:
pkg_resources.working_set.add(dist, replace=True)
def finalize_options(self):
_Distribution.finalize_options(self)
......
......@@ -9,8 +9,6 @@ import unittest
from distutils.errors import DistutilsError
from setuptools.command.develop import develop
from setuptools.command import easy_install as easy_install_pkg
from setuptools.compat import StringIO
from setuptools.dist import Distribution
SETUP_PY = """\
......@@ -114,11 +112,11 @@ class TestDevelopTest(unittest.TestCase):
os.chdir(self.dir)
try:
try:
dist = Distribution({'setup_requires': ['I_DONT_EXIST']})
Distribution({'setup_requires': ['I_DONT_EXIST']})
except DistutilsError:
e = sys.exc_info()[1]
error = str(e)
if error == wanted:
if error == wanted:
pass
finally:
os.chdir(old_dir)
......@@ -138,6 +138,43 @@ class TestSvnDummy(environment.ZippedEnvironment):
return data
@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",
"--tag-svn-revision"],
pypath=self.old_cwd,
data_stream=1)
if code:
raise AssertionError(data)
pkginfo = os.path.join('dummy.egg-info', 'PKG-INFO')
infile = open(pkginfo, 'r')
try:
read_contents = infile.readlines()
finally:
infile.close()
del infile
self.assertTrue("Version: 0.1.1-r1\n" in read_contents)
@skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
def test_no_tags(self):
code, data = environment.run_setup_py(["egg_info"],
pypath=self.old_cwd,
data_stream=1)
if code:
raise AssertionError(data)
pkginfo = os.path.join('dummy.egg-info', 'PKG-INFO')
infile = open(pkginfo, 'r')
try:
read_contents = infile.readlines()
finally:
infile.close()
del infile
self.assertTrue("Version: 0.1.1\n" in read_contents)
class TestSvnDummyLegacy(environment.ZippedEnvironment):
......
"""Run some integration tests.
Try to install a few packages.
"""
import glob
import os
import sys
import pytest
from setuptools.command.easy_install import easy_install
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
@pytest.fixture
def install_context(request, tmpdir, monkeypatch):
"""Fixture to set up temporary installation directory.
"""
# Save old values so we can restore them.
new_cwd = tmpdir.mkdir('cwd')
user_base = tmpdir.mkdir('user_base')
user_site = tmpdir.mkdir('user_site')
install_dir = tmpdir.mkdir('install_dir')
def fin():
new_cwd.remove()
user_base.remove()
user_site.remove()
install_dir.remove()
request.addfinalizer(fin)
# Change the environment and site settings to control where the
# files are installed and ensure we do not overwrite anything.
monkeypatch.chdir(new_cwd)
monkeypatch.setattr(easy_install_pkg, '__file__', user_site.strpath)
monkeypatch.setattr('site.USER_BASE', user_base.strpath)
monkeypatch.setattr('site.USER_SITE', user_site.strpath)
monkeypatch.setattr('sys.path', sys.path + [install_dir.strpath])
monkeypatch.setenv('PYTHONPATH', os.path.pathsep.join(sys.path))
# Set up the command for performing the installation.
dist = Distribution()
cmd = easy_install(dist)
cmd.install_dir = install_dir.strpath
return cmd
def _install_one(requirement, cmd, pkgname, modulename):
cmd.args = [requirement]
cmd.ensure_finalized()
cmd.run()
target = cmd.install_dir
dest_path = glob.glob(os.path.join(target, pkgname + '*.egg'))
assert dest_path
assert os.path.exists(os.path.join(dest_path[0], pkgname, modulename))
def test_stevedore(install_context):
_install_one('stevedore', install_context,
'stevedore', 'extension.py')
@pytest.mark.xfail
def test_virtualenvwrapper(install_context):
_install_one('virtualenvwrapper', install_context,
'virtualenvwrapper', 'hook_loader.py')
@pytest.mark.xfail
def test_pbr(install_context):
_install_one('pbr', install_context,
'pbr', 'core.py')
@pytest.mark.xfail
def test_python_novaclient(install_context):
_install_one('python-novaclient', install_context,
'novaclient', 'base.py')
__version__ = '3.8.2'
__version__ = '5.4'
#!/bin/sh
echo -n "Running tests for Python 2.4..."
python2.4 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
echo -n "Running tests for Python 2.5..."
python2.5 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
echo -n "Running tests for Python 2.6..."
python2.6 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
echo -n "Running tests for Python 2.7..."
python2.7 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
rm -rf build
echo -n "Running tests for Python 3.1..."
python3.1 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
rm -rf build
echo -n "Running tests for Python 3.2..."
python3.2 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
rm -rf build
echo -n "Running tests for Python 3.3..."
python3.3 setup.py -q test > /dev/null 2> /dev/null
if [ $? -ne 0 ];then
echo "Failed"
exit $1
else
echo "Success"
fi
[tox]
envlist = py26,py27,py31,py32,py33,py34
[testenv]
deps=pytest
commands=py.test
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