Commit 3dd506f0 authored by Jason R. Coombs's avatar Jason R. Coombs

Merge branch 'master' into develop-nspkg-always

parents 2268fb98 5c940698
......@@ -8,7 +8,6 @@ python:
- "3.6-dev"
- nightly
- pypy
- pypy3
env:
- ""
- LC_ALL=C LC_CTYPE=C
......@@ -24,8 +23,6 @@ script:
#- python -m tox
- tox
before_deploy:
- export SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES=1
deploy:
provider: pypi
# Also update server in setup.cfg
......
=======
CHANGES
=======
v30.4.0
-------
* #879: For declarative config:
- read_configuration() now accepts ignore_option_errors argument. This allows scraping tools to read metadata without a need to download entire packages. E.g. we can gather some stats right from GitHub repos just by downloading setup.cfg.
- packages find: directive now supports fine tuning from a subsection. The same arguments as for find() are accepted.
v30.3.0
-------
* #394 via #862: Added support for `declarative package
config in a setup.cfg file
<http://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_.
v30.2.1
-------
* #850: In test command, invoke unittest.main with
indication not to exit the process.
v30.2.0
-------
* #854: Bump to vendored Packaging 16.8.
v30.1.0
-------
* #846: Also trap 'socket.error' when opening URLs in
package_index.
* #849: Manifest processing now matches the filename
pattern anywhere in the filename and not just at the
start. Restores behavior found prior to 28.5.0.
v30.0.0
-------
* #864: Drop support for Python 3.2. Systems requiring
Python 3.2 support must use 'setuptools < 30'.
* #825: Suppress warnings for single files.
* #830 via #843: Once again restored inclusion of data
files to sdists, but now trap TypeError caused by
techniques employed rjsmin and similar.
v29.0.1
-------
* #861: Re-release of v29.0.1 with the executable script
launchers bundled. Now, launchers are included by default
and users that want to disable this behavior must set the
environment variable
'SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES' to
a false value like "false" or "0".
v29.0.0
-------
* #841: Drop special exception for packages invoking
win32com during the build/install process. See
Distribute #118 for history.
v28.8.0
-------
......
......@@ -139,10 +139,10 @@ Package Index`_. Scroll to the very bottom of the page to find the links.
.. _the project's home page in the Python Package Index: https://pypi.python.org/pypi/setuptools
In addition to the PyPI downloads, the development version of ``setuptools``
is available from the `Bitbucket repo`_, and in-development versions of the
is available from the `GitHub repo`_, and in-development versions of the
`0.6 branch`_ are available as well.
.. _Bitbucket repo: https://bitbucket.org/pypa/setuptools/get/default.tar.gz#egg=setuptools-dev
.. _GitHub repo: https://github.com/pypa/setuptools/archive/master.tar.gz#egg=setuptools-dev
.. _0.6 branch: http://svn.python.org/projects/sandbox/branches/setuptools-0.6/#egg=setuptools-dev06
Uninstalling
......
environment:
APPVEYOR: true
matrix:
- PYTHON: "C:\\Python35-x64"
- PYTHON: "C:\\Python27-x64"
......
import pytest
pytest_plugins = 'setuptools.tests.fixtures'
def pytest_addoption(parser):
parser.addoption("--package_name", action="append", default=[],
help="list of package_name to pass to test functions")
def pytest_addoption(parser):
parser.addoption(
"--package_name", action="append", default=[],
help="list of package_name to pass to test functions",
)
......@@ -5,4 +5,4 @@
<h3>Questions? Suggestions? Contributions?</h3>
<p>Visit the <a href="https://bitbucket.org/pypa/setuptools">Setuptools project page</a> </p>
<p>Visit the <a href="https://github.com/pypa/setuptools">Setuptools project page</a> </p>
......@@ -16,10 +16,10 @@ Documentation content:
.. toctree::
:maxdepth: 2
history
roadmap
python3
setuptools
easy_install
pkg_resources
python3
development
roadmap
history
......@@ -831,10 +831,9 @@ correspond exactly to the constructor argument names: ``name``,
``module_name``, ``attrs``, ``extras``, and ``dist`` are all available. In
addition, the following methods are provided:
``load(require=True, env=None, installer=None)``
Load the entry point, returning the advertised Python object, or raise
``ImportError`` if it cannot be obtained. If `require` is a true value,
then ``require(env, installer)`` is called before attempting the import.
``load()``
Load the entry point, returning the advertised Python object. Effectively
calls ``self.require()`` then returns ``self.resolve()``.
``require(env=None, installer=None)``
Ensure that any "extras" needed by the entry point are available on
......@@ -846,6 +845,10 @@ addition, the following methods are provided:
taking a ``Requirement`` instance and returning a matching importable
``Distribution`` instance or None.
``resolve()``
Resolve the entry point from its module and attrs, returning the advertised
Python object. Raises ``ImportError`` if it cannot be obtained.
``__str__()``
The string form of an ``EntryPoint`` is a string that could be passed to
``EntryPoint.parse()`` to produce an equivalent ``EntryPoint``.
......
......@@ -2398,6 +2398,211 @@ The ``upload_docs`` command has the following options:
https://pypi.python.org/pypi (i.e., the main PyPI installation).
-----------------------------------------
Configuring setup() using setup.cfg files
-----------------------------------------
``Setuptools`` allows using configuration files (usually `setup.cfg`)
to define package’s metadata and other options which are normally supplied
to ``setup()`` function.
This approach not only allows automation scenarios, but also reduces
boilerplate code in some cases.
.. note::
Implementation presents limited compatibility with distutils2-like
``setup.cfg`` sections (used by ``pbr`` and ``d2to1`` packages).
Namely: only metadata related keys from ``metadata`` section are supported
(except for ``description-file``); keys from ``files``, ``entry_points``
and ``backwards_compat`` are not supported.
.. code-block:: ini
[metadata]
name = my_package
version = attr: src.VERSION
description = My package description
long_description = file: README.rst
keywords = one, two
license = BSD 3-Clause License
[metadata.classifiers]
Framework :: Django
Programming Language :: Python :: 3.5
[options]
zip_safe = False
include_package_data = True
packages = find:
scripts =
bin/first.py
bin/second.py
[options.package_data]
* = *.txt, *.rst
hello = *.msg
[options.extras_require]
pdf = ReportLab>=1.2; RXP
rest = docutils>=0.3; pack ==1.1, ==1.3
[options.packages.find]
exclude =
src.subpackage1
src.subpackage2
Metadata and options could be set in sections with the same names.
* Keys are the same as keyword arguments one provides to ``setup()`` function.
* Complex values could be placed comma-separated or one per line
in *dangling* sections. The following are the same:
.. code-block:: ini
[metadata]
keywords = one, two
[metadata]
keywords =
one
two
* In some cases complex values could be provided in subsections for clarity.
* Some keys allow ``file:``, ``attr:`` and ``find:`` directives to cover
common usecases.
* Unknown keys are ignored.
Specifying values
=================
Some values are treated as simple strings, some allow more logic.
Type names used below:
* ``str`` - simple string
* ``list-comma`` - dangling list or comma-separated values string
* ``list-semi`` - dangling list or semicolon-separated values string
* ``bool`` - ``True`` is 1, yes, true
* ``dict`` - list-comma where keys from values are separated by =
* ``section`` - values could be read from a dedicated (sub)section
Special directives:
* ``attr:`` - value could be read from module attribute
* ``file:`` - value could be read from a file
.. note::
``file:`` directive is sandboxed and won't reach anything outside
directory with ``setup.py``.
Metadata
--------
.. note::
Aliases given below are supported for compatibility reasons,
but not advised.
================= ================= =====
Key Aliases Accepted value type
================= ================= =====
name str
version attr:, str
url home-page str
download_url download-url str
author str
author_email author-email str
maintainer str
maintainer_email maintainer-email str
classifiers classifier file:, section, list-comma
license file:, str
description summary file:, str
long_description long-description file:, str
keywords list-comma
platforms platform list-comma
provides list-comma
requires list-comma
obsoletes list-comma
================= ================= =====
.. note::
**version** - ``attr:`` supports callables; supports iterables;
unsupported types are casted using ``str()``.
Options
-------
======================= =====
Key Accepted value type
======================= =====
zip_safe bool
setup_requires list-semi
install_requires list-semi
extras_require section
entry_points file:, section
use_2to3 bool
use_2to3_fixers list-comma
use_2to3_exclude_fixers list-comma
convert_2to3_doctests list-comma
scripts list-comma
eager_resources list-comma
dependency_links list-comma
tests_require list-semi
include_package_data bool
packages find:, list-comma
package_dir dict
package_data section
exclude_package_data section
namespace_packages list-comma
======================= =====
.. note::
**packages** - ``find:`` directive can be further configured
in a dedicated subsection `options.packages.find`. This subsection
accepts the same keys as `setuptools.find` function:
`where`, `include`, `exclude`.
Configuration API
=================
Some automation tools may wish to access data from a configuration file.
``Setuptools`` exposes ``read_configuration()`` function allowing
parsing ``metadata`` and ``options`` sections into a dictionary.
.. code-block:: python
from setuptools.config import read_configuration
conf_dict = read_configuration('/home/user/dev/package/setup.cfg')
By default ``read_configuration()`` will read only file provided
in the first argument. To include values from other configuration files
which could be in various places set `find_others` function argument
to ``True``.
If you have only a configuration file but not the whole package you can still
try to get data out of it with the help of `ignore_option_errors` function
argument. When it is set to ``True`` all options with errors possibly produced
by directives, such as ``attr:`` and others will be silently ignored.
As a consequence the resulting dictionary will include no such options.
--------------------------------
Extending and Reusing Setuptools
--------------------------------
......
......@@ -75,11 +75,7 @@ __import__('pkg_resources.extern.packaging.requirements')
__import__('pkg_resources.extern.packaging.markers')
if (3, 0) < sys.version_info < (3, 3):
msg = (
"Support for Python 3.0-3.2 has been dropped. Future versions "
"will fail here."
)
warnings.warn(msg)
raise RuntimeError("Python 3.3 or later is required")
# declare some globals that will be defined later to
# satisfy the linters.
......@@ -3009,9 +3005,11 @@ def _initialize(g=globals()):
"Set up global resource manager (deliberately not state-saved)"
manager = ResourceManager()
g['_manager'] = manager
for name in dir(manager):
if not name.startswith('_'):
g[name] = getattr(manager, name)
g.update(
(name, getattr(manager, name))
for name in dir(manager)
if not name.startswith('_')
)
@_call_aside
......@@ -3040,10 +3038,10 @@ def _initialize_master_working_set():
# ensure that all distributions added to the working set in the future
# (e.g. by calling ``require()``) will get activated as well,
# with higher priority (replace=True).
dist = None # ensure dist is defined for del dist below
for dist in working_set:
tuple(
dist.activate(replace=False)
del dist
for dist in working_set
)
add_activation_listener(lambda dist: dist.activate(replace=True), existing=False)
working_set.entries = []
# match order
......
......@@ -12,7 +12,7 @@ __title__ = "packaging"
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
__version__ = "16.7"
__version__ = "16.8"
__author__ = "Donald Stufft and individual contributors"
__email__ = "donald@stufft.io"
......
......@@ -52,13 +52,26 @@ class Node(object):
def __repr__(self):
return "<{0}({1!r})>".format(self.__class__.__name__, str(self))
def serialize(self):
raise NotImplementedError
class Variable(Node):
pass
def serialize(self):
return str(self)
class Value(Node):
pass
def serialize(self):
return '"{0}"'.format(self)
class Op(Node):
def serialize(self):
return str(self)
VARIABLE = (
......@@ -103,6 +116,7 @@ VERSION_CMP = (
)
MARKER_OP = VERSION_CMP | L("not in") | L("in")
MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))
MARKER_VALUE = QuotedString("'") | QuotedString('"')
MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))
......@@ -149,7 +163,7 @@ def _format_marker(marker, first=True):
else:
return "(" + " ".join(inner) + ")"
elif isinstance(marker, tuple):
return '{0} {1} "{2}"'.format(*marker)
return " ".join([m.serialize() for m in marker])
else:
return marker
......@@ -168,13 +182,13 @@ _operators = {
def _eval_op(lhs, op, rhs):
try:
spec = Specifier("".join([op, rhs]))
spec = Specifier("".join([op.serialize(), rhs]))
except InvalidSpecifier:
pass
else:
return spec.contains(lhs)
oper = _operators.get(op)
oper = _operators.get(op.serialize())
if oper is None:
raise UndefinedComparison(
"Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
......
packaging==16.7
packaging==16.8
pyparsing==2.1.10
six==1.10.0
appdirs==1.4.0
[bumpversion]
current_version = 28.8.0
current_version = 30.4.0
commit = True
tag = True
......
......@@ -54,8 +54,8 @@ package_data = dict(
)
force_windows_specific_files = (
os.environ.get("SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES")
not in (None, "", "0")
os.environ.get("SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES", "1").lower()
not in ("", "0", "false", "no")
)
include_windows_files = (
......@@ -85,7 +85,7 @@ def pypi_link(pkg_filename):
setup_params = dict(
name="setuptools",
version="28.8.0",
version="30.4.0",
description="Easily download, build, install, upgrade, and uninstall "
"Python packages",
author="Python Packaging Authority",
......@@ -156,6 +156,7 @@ setup_params = dict(
Topic :: System :: Systems Administration
Topic :: Utilities
""").strip().splitlines(),
python_requires='>=2.6,!=3.0.*,!=3.1.*,!=3.2.*',
extras_require={
"ssl:sys_platform=='win32'": "wincertstore==0.2",
"certs": "certifi==2016.9.26",
......
......@@ -219,7 +219,7 @@ class build_py(orig.build_py, Mixin2to3):
@staticmethod
def _get_platform_patterns(spec, package, src_dir):
"""
yield platfrom-specific path patterns (suitable for glob
yield platform-specific path patterns (suitable for glob
or fn_match) from a glob-based spec (such as
self.package_data or self.exclude_package_data)
matching package in src_dir.
......
......@@ -457,7 +457,7 @@ class FileList(_FileList):
"""
if self.allfiles is None:
self.findall()
match = translate_pattern(os.path.join('**', pattern))
match = translate_pattern(os.path.join('**', '*' + pattern))
found = [f for f in self.allfiles if match.match(f)]
self.extend(found)
return bool(found)
......@@ -466,7 +466,7 @@ class FileList(_FileList):
"""
Exclude all files anywhere that match the pattern.
"""
match = translate_pattern(os.path.join('**', pattern))
match = translate_pattern(os.path.join('**', '*' + pattern))
return self._remove_files(match.match)
def append(self, item):
......@@ -554,10 +554,17 @@ class manifest_maker(sdist):
msg = "writing manifest file '%s'" % self.manifest
self.execute(write_file, (self.manifest, files), msg)
def warn(self, msg): # suppress missing-file warnings from sdist
if not msg.startswith("standard file not found:"):
def warn(self, msg):
if not self._should_suppress_warning(msg):
sdist.warn(self, msg)
@staticmethod
def _should_suppress_warning(msg):
"""
suppress missing-file warnings from sdist
"""
return re.match(r"standard file .*not found", msg)
def add_defaults(self):
sdist.add_defaults(self)
self.filelist.append(self.template)
......
......@@ -142,9 +142,13 @@ class sdist(sdist_add_defaults, orig.sdist):
for filename in filenames])
def _add_defaults_data_files(self):
"""
Don't add any data files, but why?
"""
try:
if six.PY2:
sdist_add_defaults._add_defaults_data_files(self)
else:
super()._add_defaults_data_files()
except TypeError:
log.warn("data_files contains unexpected objects")
def check_readme(self):
for f in self.READMES:
......
......@@ -225,10 +225,12 @@ class test(Command):
del_modules.append(name)
list(map(sys.modules.__delitem__, del_modules))
exit_kwarg = {} if sys.version_info < (2, 7) else {"exit": False}
unittest_main(
None, None, self._argv,
testLoader=self._resolve_as_ep(self.test_loader),
testRunner=self._resolve_as_ep(self.test_runner),
**exit_kwarg
)
@property
......
This diff is collapsed.
......@@ -19,6 +19,7 @@ from pkg_resources.extern import packaging
from setuptools.depends import Require
from setuptools import windows_support
from setuptools.monkey import get_unpatched
from setuptools.config import parse_configuration
import pkg_resources
......@@ -342,6 +343,15 @@ class Distribution(_Distribution):
if getattr(self, 'python_requires', None):
self.metadata.python_requires = self.python_requires
def parse_config_files(self, filenames=None):
"""Parses configuration files from various levels
and loads configuration.
"""
_Distribution.parse_config_files(self, filenames=filenames)
parse_configuration(self, self.command_options)
def parse_command_line(self):
"""Process features after parsing command line options"""
result = _Distribution.parse_command_line(self)
......
......@@ -768,7 +768,7 @@ class PackageIndex(Environment):
'down, %s' %
(url, v.line)
)
except http_client.HTTPException as v:
except (http_client.HTTPException, socket.error) as v:
if warning:
self.warn(warning, v)
else:
......
......@@ -373,14 +373,6 @@ if hasattr(os, 'devnull'):
else:
_EXCEPTIONS = []
try:
from win32com.client.gencache import GetGeneratePath
_EXCEPTIONS.append(GetGeneratePath())
del GetGeneratePath
except ImportError:
# it appears pywin32 is not installed, so no need to exclude.
pass
class DirectorySandbox(AbstractSandbox):
"""Restrict operations to a single subdirectory - pseudo-chroot"""
......
......@@ -56,5 +56,5 @@ def run_setup_py(cmd, pypath=None, path=None,
data = data.decode()
data = unicodedata.normalize('NFC', data)
# communciate calls wait()
# communicate calls wait()
return proc.returncode, data
from __future__ import absolute_import, unicode_literals
import textwrap
def build_namespace_package(tmpdir, name):
src_dir = tmpdir / name
src_dir.mkdir()
setup_py = src_dir / 'setup.py'
namespace, sep, rest = name.partition('.')
script = textwrap.dedent("""
import setuptools
setuptools.setup(
name={name!r},
version="1.0",
namespace_packages=[{namespace!r}],
packages=[{namespace!r}],
)
""").format(**locals())
setup_py.write_text(script, encoding='utf-8')
ns_pkg_dir = src_dir / namespace
ns_pkg_dir.mkdir()
pkg_init = ns_pkg_dir / '__init__.py'
tmpl = '__import__("pkg_resources").declare_namespace({namespace!r})'
decl = tmpl.format(**locals())
pkg_init.write_text(decl, encoding='utf-8')
pkg_mod = ns_pkg_dir / (rest + '.py')
some_functionality = 'name = {rest!r}'.format(**locals())
pkg_mod.write_text(some_functionality, encoding='utf-8')
return src_dir
def make_site_dir(target):
"""
Add a sitecustomize.py module in target to cause
target to be added to site dirs such that .pth files
are processed there.
"""
sc = target / 'sitecustomize.py'
target_str = str(target)
tmpl = '__import__("site").addsitedir({target_str!r})'
sc.write_text(tmpl.format(**locals()), encoding='utf-8')
This diff is collapsed.
......@@ -7,7 +7,6 @@ import os
import site
import sys
import io
import textwrap
import subprocess
from setuptools.extern import six
......@@ -17,6 +16,7 @@ import pytest
from setuptools.command.develop import develop
from setuptools.dist import Distribution
from . import contexts
from . import namespaces
SETUP_PY = """\
from setuptools import setup
......@@ -122,44 +122,6 @@ class TestDevelop:
class TestNamespaces:
@staticmethod
def build_namespace_package(tmpdir, name):
src_dir = tmpdir / name
src_dir.mkdir()
setup_py = src_dir / 'setup.py'
namespace, sep, rest = name.partition('.')
script = textwrap.dedent("""
import setuptools
setuptools.setup(
name={name!r},
version="1.0",
namespace_packages=[{namespace!r}],
packages=[{namespace!r}],
)
""").format(**locals())
setup_py.write_text(script, encoding='utf-8')
ns_pkg_dir = src_dir / namespace
ns_pkg_dir.mkdir()
pkg_init = ns_pkg_dir / '__init__.py'
tmpl = '__import__("pkg_resources").declare_namespace({namespace!r})'
decl = tmpl.format(**locals())
pkg_init.write_text(decl, encoding='utf-8')
pkg_mod = ns_pkg_dir / (rest + '.py')
some_functionality = 'name = {rest!r}'.format(**locals())
pkg_mod.write_text(some_functionality, encoding='utf-8')
return src_dir
@staticmethod
def make_site_dir(target):
"""
Add a sitecustomize.py module in target to cause
target to be added to site dirs such that .pth files
are processed there.
"""
sc = target / 'sitecustomize.py'
target_str = str(target)
tmpl = '__import__("site").addsitedir({target_str!r})'
sc.write_text(tmpl.format(**locals()), encoding='utf-8')
@staticmethod
def install_develop(src_dir, target):
......@@ -181,8 +143,8 @@ class TestNamespaces:
and the other installed using `develop` should leave the namespace
in tact and both packages reachable by import.
"""
pkg_A = self.build_namespace_package(tmpdir, 'myns.pkgA')
pkg_B = self.build_namespace_package(tmpdir, 'myns.pkgB')
pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
target = tmpdir / 'packages'
# use pip to install to the target directory
install_cmd = [
......@@ -193,7 +155,7 @@ class TestNamespaces:
]
subprocess.check_call(install_cmd)
self.install_develop(pkg_B, target)
self.make_site_dir(target)
namespaces.make_site_dir(target)
try_import = [
sys.executable,
'-c', 'import myns.pkgA; import myns.pkgB',
......
......@@ -4,7 +4,7 @@ import re
import stat
import sys
from setuptools.command.egg_info import egg_info
from setuptools.command.egg_info import egg_info, manifest_maker
from setuptools.dist import Distribution
from setuptools.extern.six.moves import map
......@@ -237,6 +237,15 @@ class TestEggInfo(object):
pkginfo = os.path.join(egg_info_dir, 'PKG-INFO')
assert 'Requires-Python: >=1.2.3' in open(pkginfo).read().split('\n')
def test_manifest_maker_warning_suppression(self):
fixtures = [
"standard file not found: should have one of foo.py, bar.py",
"standard file 'setup.py' not found"
]
for msg in fixtures:
assert manifest_maker._should_suppress_warning(msg)
def _run_install_command(self, tmpdir_cwd, env, cmd=None, output=None):
environ = os.environ.copy().update(
HOME=env.paths['home'],
......
......@@ -449,6 +449,11 @@ class TestFileListTest(TempDirTestCase):
assert file_list.files == ['a.py', l('d/c.py')]
self.assertWarnings()
file_list.process_template_line('global-include .txt')
file_list.sort()
assert file_list.files == ['a.py', 'b.txt', l('d/c.py')]
self.assertNoWarnings()
def test_global_exclude(self):
l = make_local_path
# global-exclude
......@@ -465,6 +470,13 @@ class TestFileListTest(TempDirTestCase):
assert file_list.files == ['b.txt']
self.assertWarnings()
file_list = FileList()
file_list.files = ['a.py', 'b.txt', l('d/c.pyc'), 'e.pyo']
file_list.process_template_line('global-exclude .py[co]')
file_list.sort()
assert file_list.files == ['a.py', 'b.txt']
self.assertNoWarnings()
def test_recursive_include(self):
l = make_local_path
# recursive-include
......
from __future__ import absolute_import, unicode_literals
import os
import sys
import subprocess
import pytest
from . import namespaces
class TestNamespaces:
@pytest.mark.xfail(sys.version_info < (3, 3),
reason="Requires PEP 420")
@pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
reason="https://github.com/pypa/setuptools/issues/851")
def test_mixed_site_and_non_site(self, tmpdir):
"""
Installing two packages sharing the same namespace, one installed
to a site dir and the other installed just to a path on PYTHONPATH
should leave the namespace in tact and both packages reachable by
import.
"""
pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
site_packages = tmpdir / 'site-packages'
path_packages = tmpdir / 'path-packages'
targets = site_packages, path_packages
python_path = os.pathsep.join(map(str, targets))
# use pip to install to the target directory
install_cmd = [
'pip',
'install',
str(pkg_A),
'-t', str(site_packages),
]
subprocess.check_call(install_cmd)
namespaces.make_site_dir(site_packages)
install_cmd = [
'pip',
'install',
str(pkg_B),
'-t', str(path_packages),
]
subprocess.check_call(install_cmd)
try_import = [
sys.executable,
'-c', 'import myns.pkgA; import myns.pkgB',
]
env = dict(PYTHONPATH=python_path)
subprocess.check_call(try_import, env=env)
......@@ -23,22 +23,6 @@ class TestSandbox:
return do_write
def test_win32com(self, tmpdir):
"""
win32com should not be prevented from caching COM interfaces
in gen_py.
"""
win32com = pytest.importorskip('win32com')
gen_py = win32com.__gen_path__
target = os.path.join(gen_py, 'test_write')
sandbox = DirectorySandbox(str(tmpdir))
try:
# attempt to create gen_py file
sandbox.run(self._file_writer(target))
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
......
......@@ -26,7 +26,8 @@ SETUP_ATTRS = {
'name': 'sdist_test',
'version': '0.0',
'packages': ['sdist_test'],
'package_data': {'sdist_test': ['*.txt']}
'package_data': {'sdist_test': ['*.txt']},
'data_files': [("data", [os.path.join("d", "e.dat")])],
}
SETUP_PY = """\
......@@ -95,9 +96,12 @@ class TestSdistTest:
# Set up the rest of the test package
test_pkg = os.path.join(self.temp_dir, 'sdist_test')
os.mkdir(test_pkg)
data_folder = os.path.join(self.temp_dir, "d")
os.mkdir(data_folder)
# *.rst was not included in package_data, so c.rst should not be
# automatically added to the manifest when not under version control
for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst',
os.path.join(data_folder, "e.dat")]:
# Just touch the files; their contents are irrelevant
open(os.path.join(test_pkg, fname), 'w').close()
......@@ -126,6 +130,7 @@ class TestSdistTest:
assert os.path.join('sdist_test', 'a.txt') in manifest
assert os.path.join('sdist_test', 'b.txt') in manifest
assert os.path.join('sdist_test', 'c.rst') not in manifest
assert os.path.join('d', 'e.dat') in manifest
def test_defaults_case_sensitivity(self):
"""
......
import pkg_resources
try:
__version__ = pkg_resources.require('setuptools')[0].version
__version__ = pkg_resources.get_distribution('setuptools').version
except Exception:
__version__ = 'unknown'
[testenv]
deps=-rtests/requirements.txt
passenv=APPDATA USERPROFILE HOMEDRIVE HOMEPATH windir
commands=python -m pytest {posargs:-rsx}
passenv=APPDATA USERPROFILE HOMEDRIVE HOMEPATH windir APPVEYOR
commands=py.test {posargs:-rsx}
usedevelop=True
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