Commit d2adf3da authored by Jason R. Coombs's avatar Jason R. Coombs Committed by GitHub

Merge branch 'master' into feature/upload-infer-username

parents 05d47d9f 5c80844b
......@@ -35,7 +35,7 @@ deploy:
on:
tags: true
all_branches: true
python: 3.5
python: 3.6
condition: $LC_ALL != "C"
user: jaraco
password:
......
......@@ -4,6 +4,22 @@ v34.3.0
* #941: In the upload command, if the username is blank,
default to ``getpass.getuser()``.
v34.2.0
-------
* #966: Add support for reading dist-info metadata and
thus locating Distributions from zip files.
* #968: Allow '+' and '!' in egg fragments
so that it can take package names that contain
PEP 440 conforming version specifiers.
v34.1.1
-------
* #953: More aggressively employ the compatibility issue
originally added in #706.
v34.1.0
-------
......
......@@ -17,7 +17,6 @@ import sys
import textwrap
import subprocess
import pip
minimal_egg_info = textwrap.dedent("""
[distutils.commands]
......@@ -75,7 +74,7 @@ def gen_deps():
@contextlib.contextmanager
def install_deps():
"Just in time make the deps available"
gen_deps()
import pip
tmpdir = tempfile.mkdtemp()
args = [
'install',
......@@ -90,7 +89,16 @@ def install_deps():
shutil.rmtree(tmpdir)
if __name__ == '__main__':
def main():
ensure_egg_info()
with install_deps():
gen_deps()
try:
# first assume dependencies are present
run_egg_info()
except Exception:
# but if that fails, try again with dependencies just in time
with install_deps():
run_egg_info()
__name__ == '__main__' and main()
......@@ -29,7 +29,7 @@ import setup as setup_script
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['rst.linker']
extensions = ['rst.linker', 'sphinx.ext.autosectionlabel']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
......
......@@ -143,10 +143,10 @@ namespace package for Zope Corporation packages, and the ``peak`` namespace
package for the Python Enterprise Application Kit.
To create a namespace package, you list it in the ``namespace_packages``
argument to ``setup()``, in your project's ``setup.py``. (See the `setuptools
documentation on namespace packages`_ for more information on this.) Also,
you must add a ``declare_namespace()`` call in the package's ``__init__.py``
file(s):
argument to ``setup()``, in your project's ``setup.py``. (See the
:ref:`setuptools documentation on namespace packages <Namespace Packages>` for
more information on this.) Also, you must add a ``declare_namespace()`` call
in the package's ``__init__.py`` file(s):
``declare_namespace(name)``
Declare that the dotted package name `name` is a "namespace package" whose
......@@ -175,8 +175,6 @@ filesystem and zip importers, you can extend its support to other "importers"
compatible with PEP 302 using the ``register_namespace_handler()`` function.
See the section below on `Supporting Custom Importers`_ for details.
.. _setuptools documentation on namespace packages: http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
``WorkingSet`` Objects
======================
......
rst.linker>=1.6.1
sphinx>=1.4
......@@ -940,14 +940,13 @@ Typically, existing programs manipulate a package's ``__file__`` attribute in
order to find the location of data files. However, this manipulation isn't
compatible with PEP 302-based import hooks, including importing from zip files
and Python Eggs. It is strongly recommended that, if you are using data files,
you should use the `Resource Management API`_ of ``pkg_resources`` to access
you should use the :ref:`ResourceManager API` of ``pkg_resources`` to access
them. The ``pkg_resources`` module is distributed as part of setuptools, so if
you're using setuptools to distribute your package, there is no reason not to
use its resource management API. See also `Accessing Package Resources`_ for
a quick example of converting code that uses ``__file__`` to use
``pkg_resources`` instead.
.. _Resource Management API: http://peak.telecommunity.com/DevCenter/PkgResources#resourcemanager-api
.. _Accessing Package Resources: http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources
......@@ -959,8 +958,8 @@ location (e.g. ``/usr/share``). This feature intended to be used for things
like documentation, example configuration files, and the like. ``setuptools``
does not install these data files in a separate location, however. They are
bundled inside the egg file or directory, alongside the Python modules and
packages. The data files can also be accessed using the `Resource Management
API`_, by specifying a ``Requirement`` instead of a package name::
packages. The data files can also be accessed using the :ref:`ResourceManager
API`, by specifying a ``Requirement`` instead of a package name::
from pkg_resources import Requirement, resource_filename
filename = resource_filename(Requirement.parse("MyProject"),"sample.conf")
......@@ -2303,10 +2302,10 @@ boilerplate code in some cases.
long_description = file: README.rst
keywords = one, two
license = BSD 3-Clause License
[metadata.classifiers]
Framework :: Django
Programming Language :: Python :: 3.5
classifiers =
Framework :: Django
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
[options]
zip_safe = False
......@@ -2399,7 +2398,7 @@ author str
author_email author-email str
maintainer str
maintainer_email maintainer-email str
classifiers classifier file:, section, list-comma
classifiers classifier file:, list-comma
license file:, str
description summary file:, str
long_description long-description file:, str
......
......@@ -1956,6 +1956,12 @@ def find_eggs_in_zip(importer, path_item, only=False):
subpath = os.path.join(path_item, subitem)
for dist in find_eggs_in_zip(zipimport.zipimporter(subpath), subpath):
yield dist
elif subitem.lower().endswith('.dist-info'):
subpath = os.path.join(path_item, subitem)
submeta = EggMetadata(zipimport.zipimporter(subpath))
submeta.egg_info = subpath
yield Distribution.from_location(path_item, subitem, submeta)
register_finder(zipimport.zipimporter, find_eggs_in_zip)
......
[bumpversion]
current_version = 34.1.0
current_version = 34.2.0
commit = True
tag = True
......
......@@ -88,7 +88,7 @@ def pypi_link(pkg_filename):
setup_params = dict(
name="setuptools",
version="34.1.0",
version="34.2.0",
description="Easily download, build, install, upgrade, and uninstall "
"Python packages",
author="Python Packaging Authority",
......
......@@ -412,17 +412,6 @@ class ConfigMetadataHandler(ConfigHandler):
'version': self._parse_version,
}
def parse_section_classifiers(self, section_options):
"""Parses configuration file section.
:param dict section_options:
"""
classifiers = []
for begin, (_, rest) in section_options.items():
classifiers.append('%s :%s' % (begin.title(), rest))
self['classifiers'] = classifiers
def _parse_version(self, value):
"""Parses `version` option value.
......
......@@ -52,7 +52,7 @@ class Installer:
"importlib.util.module_from_spec("
"importlib.machinery.PathFinder.find_spec(%(pkg)r, "
"[os.path.dirname(p)])))",
"m = m or not has_mfs and "
"m = m or "
"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)",
......
......@@ -30,7 +30,7 @@ from fnmatch import translate
from setuptools.py26compat import strip_fragment
from setuptools.py27compat import get_all_headers
EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$')
EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$')
HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I)
# this is here to fix emacs' cruddy broken syntax highlighting
PYPI_MD5 = re.compile(
......
......@@ -21,7 +21,6 @@ if sys.version_info < (3,):
linux_py2_ascii = (
platform.system() == 'Linux' and
sys.getfilesystemencoding() == 'ascii' and
sys.version_info < (3,)
)
......
......@@ -257,6 +257,7 @@ class TestMetadata:
def test_classifiers(self, tmpdir):
expected = set([
'Framework :: Django',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
])
......@@ -269,19 +270,21 @@ class TestMetadata:
tmpdir.join('classifiers').write(
'Framework :: Django\n'
'Programming Language :: Python :: 3\n'
'Programming Language :: Python :: 3.5\n'
)
with get_dist(tmpdir) as dist:
assert set(dist.metadata.classifiers) == expected
# From section.
# From list notation
config.write(
'[metadata.classifiers]\n'
'Framework :: Django\n'
'Programming Language :: Python :: 3.5\n'
'[metadata]\n'
'classifiers =\n'
' Framework :: Django\n'
' Programming Language :: Python :: 3\n'
' Programming Language :: Python :: 3.5\n'
)
with get_dist(tmpdir) as dist:
assert set(dist.metadata.classifiers) == expected
......
......@@ -181,6 +181,48 @@ class TestPackageIndex:
res = setuptools.package_index.local_open(url)
assert 'content' in res.read()
def test_egg_fragment(self):
"""
EGG fragments must comply to PEP 440
"""
epoch = [
'',
'1!',
]
releases = [
'0',
'0.0',
'0.0.0',
]
pre = [
'a0',
'b0',
'rc0',
]
post = [
'.post0'
]
dev = [
'.dev0',
]
local = [
('', ''),
('+ubuntu.0', '+ubuntu.0'),
('+ubuntu-0', '+ubuntu.0'),
('+ubuntu_0', '+ubuntu.0'),
]
versions = [
[''.join([e, r, p, l]) for l in ll]
for e in epoch
for r in releases
for p in sum([pre, post, dev], [''])
for ll in local]
for v, vc in versions:
dists = list(setuptools.package_index.distros_for_url(
'http://example.com/example.zip#egg=example-' + v))
assert dists[0].version == ''
assert dists[1].version == vc
class TestContentCheckers:
def test_md5(self):
......
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