Commit 792edda4 authored by Steve Kowalik's avatar Steve Kowalik

Merge from master.

parents a718819d 81ca4fea
...@@ -3,6 +3,18 @@ CHANGES ...@@ -3,6 +3,18 @@ CHANGES
======= =======
----
18.8
----
* Deprecated ``egg_info.get_pkg_info_revision``.
* Issue #471: Don't rely on repr for an HTML attribute value in
package_index.
* Issue #419: Avoid errors in FileMetadata when the metadata directory
is broken.
* Issue #472: Remove deprecated use of 'U' in mode parameter
when opening files.
------ ------
18.7.1 18.7.1
------ ------
......
...@@ -1987,11 +1987,11 @@ class FileMetadata(EmptyProvider): ...@@ -1987,11 +1987,11 @@ class FileMetadata(EmptyProvider):
self.path = path self.path = path
def has_metadata(self, name): def has_metadata(self, name):
return name=='PKG-INFO' return name=='PKG-INFO' and os.path.isfile(self.path)
def get_metadata(self, name): def get_metadata(self, name):
if name=='PKG-INFO': if name=='PKG-INFO':
with io.open(self.path, 'rU', encoding='utf-8') as f: with io.open(self.path, encoding='utf-8') as f:
metadata = f.read() metadata = f.read()
return metadata return metadata
raise KeyError("No metadata except PKG-INFO is available") raise KeyError("No metadata except PKG-INFO is available")
......
...@@ -2,9 +2,13 @@ from glob import glob ...@@ -2,9 +2,13 @@ from glob import glob
from distutils.util import convert_path from distutils.util import convert_path
import distutils.command.build_py as orig import distutils.command.build_py as orig
import os import os
import sys
import fnmatch import fnmatch
import textwrap import textwrap
import io
import distutils.errors
import collections
import itertools
try: try:
from setuptools.lib2to3_ex import Mixin2to3 from setuptools.lib2to3_ex import Mixin2to3
...@@ -157,17 +161,15 @@ class build_py(orig.build_py, Mixin2to3): ...@@ -157,17 +161,15 @@ class build_py(orig.build_py, Mixin2to3):
else: else:
return init_py return init_py
f = open(init_py, 'rbU') with io.open(init_py, 'rb') as f:
if 'declare_namespace'.encode() not in f.read(): contents = f.read()
from distutils.errors import DistutilsError if b'declare_namespace' not in contents:
raise distutils.errors.DistutilsError(
raise DistutilsError(
"Namespace package problem: %s is a namespace package, but " "Namespace package problem: %s is a namespace package, but "
"its\n__init__.py does not call declare_namespace()! Please " "its\n__init__.py does not call declare_namespace()! Please "
'fix it.\n(See the setuptools manual under ' 'fix it.\n(See the setuptools manual under '
'"Namespace Packages" for details.)\n"' % (package,) '"Namespace Packages" for details.)\n"' % (package,)
) )
f.close()
return init_py return init_py
def initialize_options(self): def initialize_options(self):
...@@ -182,20 +184,25 @@ class build_py(orig.build_py, Mixin2to3): ...@@ -182,20 +184,25 @@ class build_py(orig.build_py, Mixin2to3):
def exclude_data_files(self, package, src_dir, files): def exclude_data_files(self, package, src_dir, files):
"""Filter filenames for package's data files in 'src_dir'""" """Filter filenames for package's data files in 'src_dir'"""
globs = (self.exclude_package_data.get('', []) globs = (
+ self.exclude_package_data.get(package, [])) self.exclude_package_data.get('', [])
bad = [] + self.exclude_package_data.get(package, [])
for pattern in globs: )
bad.extend( bad = set(
fnmatch.filter( item
files, os.path.join(src_dir, convert_path(pattern)) for pattern in globs
) for item in fnmatch.filter(
files,
os.path.join(src_dir, convert_path(pattern)),
) )
bad = dict.fromkeys(bad) )
seen = {} seen = collections.defaultdict(itertools.count)
return [ return [
f for f in files if f not in bad fn
and f not in seen and seen.setdefault(f, 1) # ditch dupes for fn in files
if fn not in bad
# ditch dupes
and not next(seen[fn])
] ]
......
...@@ -3,6 +3,7 @@ from distutils import log ...@@ -3,6 +3,7 @@ from distutils import log
from distutils.errors import DistutilsError, DistutilsOptionError from distutils.errors import DistutilsError, DistutilsOptionError
import os import os
import glob import glob
import io
from pkg_resources import Distribution, PathMetadata, normalize_path from pkg_resources import Distribution, PathMetadata, normalize_path
from setuptools.command.easy_install import easy_install from setuptools.command.easy_install import easy_install
...@@ -163,9 +164,8 @@ class develop(easy_install): ...@@ -163,9 +164,8 @@ class develop(easy_install):
for script_name in self.distribution.scripts or []: for script_name in self.distribution.scripts or []:
script_path = os.path.abspath(convert_path(script_name)) script_path = os.path.abspath(convert_path(script_name))
script_name = os.path.basename(script_path) script_name = os.path.basename(script_path)
f = open(script_path, 'rU') with io.open(script_path) as strm:
script_text = f.read() script_text = strm.read()
f.close()
self.install_script(dist, script_name, script_text, script_path) self.install_script(dist, script_name, script_text, script_path)
def install_wrapper_scripts(self, dist): def install_wrapper_scripts(self, dist):
......
...@@ -772,8 +772,8 @@ class easy_install(Command): ...@@ -772,8 +772,8 @@ class easy_install(Command):
is_script = is_python_script(script_text, script_name) is_script = is_python_script(script_text, script_name)
if is_script: if is_script:
script_text = (ScriptWriter.get_header(script_text) + body = self._load_template(dev_path) % locals()
self._load_template(dev_path) % locals()) script_text = ScriptWriter.get_header(script_text) + body
self.write_script(script_name, _to_ascii(script_text), 'b') self.write_script(script_name, _to_ascii(script_text), 'b')
@staticmethod @staticmethod
...@@ -805,9 +805,8 @@ class easy_install(Command): ...@@ -805,9 +805,8 @@ class easy_install(Command):
ensure_directory(target) ensure_directory(target)
if os.path.exists(target): if os.path.exists(target):
os.unlink(target) os.unlink(target)
f = open(target, "w" + mode) with open(target, "w" + mode) as f:
f.write(contents) f.write(contents)
f.close()
chmod(target, 0o777 - mask) chmod(target, 0o777 - mask)
def install_eggs(self, spec, dist_filename, tmpdir): def install_eggs(self, spec, dist_filename, tmpdir):
......
...@@ -10,16 +10,17 @@ import distutils.filelist ...@@ -10,16 +10,17 @@ import distutils.filelist
import os import os
import re import re
import sys import sys
import io
import warnings
import time
try: from setuptools.compat import basestring, PY3, StringIO
from setuptools_svn import svn_utils
except ImportError:
pass
from setuptools import Command from setuptools import Command
from setuptools.command.sdist import sdist from setuptools.command.sdist import sdist
from setuptools.compat import basestring, PY3, StringIO
from setuptools.command.sdist import walk_revctrl from setuptools.command.sdist import walk_revctrl
from setuptools.command.setopt import edit_config
from setuptools.command import bdist_egg
from pkg_resources import ( from pkg_resources import (
parse_requirements, safe_name, parse_version, parse_requirements, safe_name, parse_version,
safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
...@@ -27,6 +28,12 @@ import setuptools.unicode_utils as unicode_utils ...@@ -27,6 +28,12 @@ import setuptools.unicode_utils as unicode_utils
from pkg_resources import packaging from pkg_resources import packaging
try:
from setuptools_svn import svn_utils
except ImportError:
pass
class egg_info(Command): class egg_info(Command):
description = "create a distribution's .egg-info directory" description = "create a distribution's .egg-info directory"
...@@ -58,8 +65,6 @@ class egg_info(Command): ...@@ -58,8 +65,6 @@ class egg_info(Command):
self.vtags = None self.vtags = None
def save_version_info(self, filename): def save_version_info(self, filename):
from setuptools.command.setopt import edit_config
values = dict( values = dict(
egg_info=dict( egg_info=dict(
tag_svn_revision=0, tag_svn_revision=0,
...@@ -184,12 +189,8 @@ class egg_info(Command): ...@@ -184,12 +189,8 @@ class egg_info(Command):
if self.tag_build: if self.tag_build:
version += self.tag_build version += self.tag_build
if self.tag_svn_revision: if self.tag_svn_revision:
rev = self.get_svn_revision() version += '-r%s' % self.get_svn_revision()
if rev: # is 0 if it's not an svn working copy
version += '-r%s' % rev
if self.tag_date: if self.tag_date:
import time
version += time.strftime("-%Y%m%d") version += time.strftime("-%Y%m%d")
return version return version
...@@ -390,7 +391,6 @@ def write_pkg_info(cmd, basename, filename): ...@@ -390,7 +391,6 @@ def write_pkg_info(cmd, basename, filename):
metadata.name, metadata.version = oldname, oldver metadata.name, metadata.version = oldname, oldver
safe = getattr(cmd.distribution, 'zip_safe', None) safe = getattr(cmd.distribution, 'zip_safe', None)
from setuptools.command import bdist_egg
bdist_egg.write_safety_flag(cmd.egg_info, safe) bdist_egg.write_safety_flag(cmd.egg_info, safe)
...@@ -467,14 +467,15 @@ def write_entries(cmd, basename, filename): ...@@ -467,14 +467,15 @@ def write_entries(cmd, basename, filename):
def get_pkg_info_revision(): def get_pkg_info_revision():
# See if we can get a -r### off of PKG-INFO, in case this is an sdist of """
# a subversion revision Get a -r### off of PKG-INFO Version in case this is an sdist of
# a subversion revision.
"""
warnings.warn("get_pkg_info_revision is deprecated.", DeprecationWarning)
if os.path.exists('PKG-INFO'): if os.path.exists('PKG-INFO'):
f = open('PKG-INFO', 'rU') with io.open('PKG-INFO') as f:
for line in f: for line in f:
match = re.match(r"Version:.*-r(\d+)\s*$", line) match = re.match(r"Version:.*-r(\d+)\s*$", line)
if match: if match:
return int(match.group(1)) return int(match.group(1))
f.close()
return 0 return 0
...@@ -3,6 +3,7 @@ from distutils import log ...@@ -3,6 +3,7 @@ from distutils import log
import distutils.command.sdist as orig import distutils.command.sdist as orig
import os import os
import sys import sys
import io
from setuptools.compat import PY3 from setuptools.compat import PY3
from setuptools.utils import cs_path_exists from setuptools.utils import cs_path_exists
...@@ -166,11 +167,8 @@ class sdist(orig.sdist): ...@@ -166,11 +167,8 @@ class sdist(orig.sdist):
if not os.path.isfile(self.manifest): if not os.path.isfile(self.manifest):
return False return False
fp = open(self.manifest, 'rbU') with io.open(self.manifest, 'rb') as fp:
try:
first_line = fp.readline() first_line = fp.readline()
finally:
fp.close()
return (first_line != return (first_line !=
'# file GENERATED by distutils, do NOT edit\n'.encode()) '# file GENERATED by distutils, do NOT edit\n'.encode())
......
...@@ -1031,16 +1031,18 @@ def local_open(url): ...@@ -1031,16 +1031,18 @@ def local_open(url):
elif path.endswith('/') and os.path.isdir(filename): elif path.endswith('/') and os.path.isdir(filename):
files = [] files = []
for f in os.listdir(filename): for f in os.listdir(filename):
if f=='index.html': filepath = os.path.join(filename, f)
with open(os.path.join(filename,f),'r') as fp: if f == 'index.html':
with open(filepath, 'r') as fp:
body = fp.read() body = fp.read()
break break
elif os.path.isdir(os.path.join(filename,f)): elif os.path.isdir(filepath):
f+='/' f += '/'
files.append("<a href=%r>%s</a>" % (f,f)) files.append('<a href="{name}">{name}</a>'.format(name=f))
else: else:
body = ("<html><head><title>%s</title>" % url) + \ tmpl = ("<html><head><title>{url}</title>"
"</head><body>%s</body></html>" % '\n'.join(files) "</head><body>{files}</body></html>")
body = tmpl.format(url=url, files='\n'.join(files))
status, message = 200, "OK" status, message = 200, "OK"
else: else:
status, message, body = 404, "Path not found", "Not found" status, message, body = 404, "Path not found", "Not found"
......
...@@ -7,6 +7,7 @@ import sys ...@@ -7,6 +7,7 @@ import sys
import tempfile import tempfile
import unicodedata import unicodedata
import contextlib import contextlib
import io
import pytest import pytest
...@@ -81,6 +82,11 @@ def decompose(path): ...@@ -81,6 +82,11 @@ def decompose(path):
return path return path
def read_all_bytes(filename):
with io.open(filename, 'rb') as fp:
return fp.read()
class TestSdistTest: class TestSdistTest:
def setup_method(self, method): def setup_method(self, method):
...@@ -172,9 +178,7 @@ class TestSdistTest: ...@@ -172,9 +178,7 @@ class TestSdistTest:
mm.filelist.append(filename) mm.filelist.append(filename)
mm.write_manifest() mm.write_manifest()
manifest = open(mm.manifest, 'rbU') contents = read_all_bytes(mm.manifest)
contents = manifest.read()
manifest.close()
# The manifest should be UTF-8 encoded # The manifest should be UTF-8 encoded
u_contents = contents.decode('UTF-8') u_contents = contents.decode('UTF-8')
...@@ -210,9 +214,7 @@ class TestSdistTest: ...@@ -210,9 +214,7 @@ class TestSdistTest:
# Re-write manifest # Re-write manifest
mm.write_manifest() mm.write_manifest()
manifest = open(mm.manifest, 'rbU') contents = read_all_bytes(mm.manifest)
contents = manifest.read()
manifest.close()
# The manifest should be UTF-8 encoded # The manifest should be UTF-8 encoded
contents.decode('UTF-8') contents.decode('UTF-8')
...@@ -248,9 +250,7 @@ class TestSdistTest: ...@@ -248,9 +250,7 @@ class TestSdistTest:
# Re-write manifest # Re-write manifest
mm.write_manifest() mm.write_manifest()
manifest = open(mm.manifest, 'rbU') contents = read_all_bytes(mm.manifest)
contents = manifest.read()
manifest.close()
# The manifest should be UTF-8 encoded # The manifest should be UTF-8 encoded
contents.decode('UTF-8') contents.decode('UTF-8')
......
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