diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2014-11-16 09:40:21 -0500 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2014-11-16 09:40:21 -0500 |
commit | 82ff46cb011b5d3f5112ab3519d116d94c03d216 (patch) | |
tree | 8ca7105bfa4b3db9c549982fc3a00851a7da5cf8 /setuptools | |
parent | 651486f2739fc33fef3a9325b963dc14745e466a (diff) | |
parent | 1d82cc3348f6a35e8a93923079fbd7af8317b5b8 (diff) | |
download | python-setuptools-bitbucket-82ff46cb011b5d3f5112ab3519d116d94c03d216.tar.gz |
Merge with master
Diffstat (limited to 'setuptools')
28 files changed, 209 insertions, 257 deletions
diff --git a/setuptools/__init__.py b/setuptools/__init__.py index ca025c30..920dad38 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -8,11 +8,12 @@ from distutils.core import Command as _Command from distutils.util import convert_path from fnmatch import fnmatchcase +from six.moves import filterfalse + import setuptools.version from setuptools.extension import Extension from setuptools.dist import Distribution, Feature, _get_unpatched from setuptools.depends import Require -from setuptools.compat import filterfalse __all__ = [ 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 34fdeec2..3d241b99 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -12,9 +12,10 @@ import os import marshal import textwrap +import six + from pkg_resources import get_build_platform, Distribution, ensure_directory from pkg_resources import EntryPoint -from setuptools.compat import basestring from setuptools.extension import Library from setuptools import Command @@ -418,7 +419,7 @@ def iter_symbols(code): for name in code.co_names: yield name for const in code.co_consts: - if isinstance(const, basestring): + if isinstance(const, six.string_types): yield const elif isinstance(const, CodeType): for name in iter_symbols(const): diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 368b64fe..9f0b6f47 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -4,9 +4,10 @@ from distutils.errors import DistutilsError, DistutilsOptionError import os import glob +import six + from pkg_resources import Distribution, PathMetadata, normalize_path from setuptools.command.easy_install import easy_install -from setuptools.compat import PY3 import setuptools @@ -86,7 +87,7 @@ class develop(easy_install): " installation directory", p, normalize_path(os.curdir)) def install_for_development(self): - if PY3 and getattr(self.distribution, 'use_2to3', False): + if six.PY3 and getattr(self.distribution, 'use_2to3', False): # If we run 2to3 we can not do this inplace: # Ensure metadata is up-to-date diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 2e00b996..5444ba53 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -35,6 +35,9 @@ import warnings import site import struct +import six +from six.moves import configparser + from setuptools import Command from setuptools.sandbox import run_setup from setuptools.py31compat import get_path, get_config_vars @@ -43,8 +46,6 @@ from setuptools.archive_util import unpack_archive from setuptools.package_index import PackageIndex from setuptools.package_index import URL_SCHEME from setuptools.command import bdist_egg, egg_info -from setuptools.compat import (iteritems, maxsize, basestring, unicode, - reraise, PY2, PY3) from pkg_resources import ( yield_lines, normalize_path, resource_string, ensure_directory, get_distribution, find_distributions, Environment, Requirement, @@ -77,13 +78,13 @@ def samefile(p1, p2): return norm_p1 == norm_p2 -if PY2: +if six.PY2: def _to_ascii(s): return s def isascii(s): try: - unicode(s, 'ascii') + six.text_type(s, 'ascii') return True except UnicodeError: return False @@ -315,7 +316,7 @@ class easy_install(Command): self.local_index = Environment(self.shadow_path + sys.path) if self.find_links is not None: - if isinstance(self.find_links, basestring): + if isinstance(self.find_links, six.string_types): self.find_links = self.find_links.split() else: self.find_links = [] @@ -393,7 +394,7 @@ class easy_install(Command): try: pid = os.getpid() except: - pid = random.randint(0, maxsize) + pid = random.randint(0, sys.maxsize) return os.path.join(self.install_dir, "test-easy-install-%s" % pid) def warn_deprecated_options(self): @@ -1217,7 +1218,7 @@ Please make the appropriate changes for your system and try again.""" f = open(sitepy, 'rb') current = f.read() # we want str, not bytes - if PY3: + if six.PY3: current = current.decode() f.close() @@ -1243,7 +1244,7 @@ Please make the appropriate changes for your system and try again.""" if not self.user: return home = convert_path(os.path.expanduser("~")) - for name, path in iteritems(self.config_vars): + for name, path in six.iteritems(self.config_vars): if path.startswith(home) and not os.path.isdir(path): self.debug_print("os.makedirs('%s', 0o700)" % path) os.makedirs(path, 0o700) @@ -1374,7 +1375,7 @@ def expand_paths(inputs): def extract_wininst_cfg(dist_filename): """Extract configuration data from a bdist_wininst .exe - Returns a ConfigParser.RawConfigParser, or None + Returns a configparser.RawConfigParser, or None """ f = open(dist_filename, 'rb') try: @@ -1387,15 +1388,12 @@ def extract_wininst_cfg(dist_filename): return None f.seek(prepended - 12) - from setuptools.compat import StringIO, ConfigParser - import struct - tag, cfglen, bmlen = struct.unpack("<iii", f.read(12)) if tag not in (0x1234567A, 0x1234567B): return None # not a valid tag f.seek(prepended - (12 + cfglen)) - cfg = ConfigParser.RawConfigParser( + cfg = configparser.RawConfigParser( {'version': '', 'target_version': ''}) try: part = f.read(cfglen) @@ -1409,8 +1407,8 @@ def extract_wininst_cfg(dist_filename): # Now the config is in bytes, but for RawConfigParser, it should # be text, so decode it. config = config.decode(sys.getfilesystemencoding()) - cfg.readfp(StringIO(config)) - except ConfigParser.Error: + cfg.readfp(six.StringIO(config)) + except configparser.Error: return None if not cfg.has_section('metadata') or not cfg.has_section('Setup'): return None @@ -1444,7 +1442,7 @@ def get_exe_prefixes(exe_filename): continue if parts[0].upper() in ('PURELIB', 'PLATLIB'): contents = z.read(name) - if PY3: + if six.PY3: contents = contents.decode() for pth in yield_lines(contents): pth = pth.strip().replace('\\', '/') @@ -1618,7 +1616,7 @@ def auto_chmod(func, arg, exc): chmod(arg, stat.S_IWRITE) return func(arg) et, ev, _ = sys.exc_info() - reraise(et, (ev[0], ev[1] + (" %s %s" % (func, arg)))) + six.reraise(et, (ev[0], ev[1] + (" %s %s" % (func, arg)))) def update_dist_caches(dist_path, fix_zipimporter_caches): @@ -2053,7 +2051,7 @@ def get_win_launcher(type): def load_launcher_manifest(name): manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') - if PY2: + if six.PY2: return manifest % vars() else: return manifest.decode('utf-8') % vars() diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 06764a17..14ff0763 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -10,9 +10,10 @@ import os import re import sys +import six + from setuptools import Command from setuptools.command.sdist import sdist -from setuptools.compat import basestring, PY3, StringIO from setuptools import svn_utils from setuptools.command.sdist import walk_revctrl from pkg_resources import ( @@ -132,7 +133,7 @@ class egg_info(Command): to the file. """ log.info("writing %s to %s", what, filename) - if PY3: + if six.PY3: data = data.encode("utf-8") if not self.dry_run: f = open(filename, 'wb') @@ -373,7 +374,7 @@ def _write_requirements(stream, reqs): def write_requirements(cmd, basename, filename): dist = cmd.distribution - data = StringIO() + data = six.StringIO() _write_requirements(data, dist.install_requires) extras_require = dist.extras_require or {} for extra in sorted(extras_require): @@ -407,12 +408,12 @@ def write_arg(cmd, basename, filename, force=False): def write_entries(cmd, basename, filename): ep = cmd.distribution.entry_points - if isinstance(ep, basestring) or ep is None: + if isinstance(ep, six.string_types) or ep is None: data = ep elif ep is not None: data = [] for section, contents in sorted(ep.items()): - if not isinstance(contents, basestring): + if not isinstance(contents, six.string_types): contents = EntryPoint.parse_group(section, contents) contents = '\n'.join(sorted(map(str, contents.values()))) data.append('[%s]\n%s\n\n' % (section, contents)) diff --git a/setuptools/command/rotate.py b/setuptools/command/rotate.py index 1b073620..09eac496 100755 --- a/setuptools/command/rotate.py +++ b/setuptools/command/rotate.py @@ -3,8 +3,9 @@ from distutils import log from distutils.errors import DistutilsOptionError import os +import six + from setuptools import Command -from setuptools.compat import basestring class rotate(Command): @@ -36,7 +37,7 @@ class rotate(Command): self.keep = int(self.keep) except ValueError: raise DistutilsOptionError("--keep must be an integer") - if isinstance(self.match, basestring): + if isinstance(self.match, six.string_types): self.match = [ convert_path(p.strip()) for p in self.match.split(',') ] diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index a77c39f2..a15582c3 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -6,8 +6,9 @@ import os import re import sys +import six + from setuptools import svn_utils -from setuptools.compat import PY3 from setuptools.utils import cs_path_exists import pkg_resources @@ -238,7 +239,7 @@ class sdist(orig.sdist): manifest = open(self.manifest, 'rbU') for line in manifest: # The manifest must contain UTF-8. See #303. - if PY3: + if six.PY3: try: line = line.decode('UTF-8') except UnicodeDecodeError: diff --git a/setuptools/command/setopt.py b/setuptools/command/setopt.py index a04d6032..f78e0cd5 100755 --- a/setuptools/command/setopt.py +++ b/setuptools/command/setopt.py @@ -4,6 +4,8 @@ from distutils.errors import DistutilsOptionError import distutils import os +from six.moves import configparser + from setuptools import Command @@ -37,10 +39,8 @@ def edit_config(filename, settings, dry_run=False): while a dictionary lists settings to be changed or deleted in that section. 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 = configparser.RawConfigParser() opts.read([filename]) for section, options in settings.items(): if options is None: diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 1038da71..14dd2600 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -3,11 +3,12 @@ from unittest import TestLoader import unittest import sys +import six + 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 @@ -84,7 +85,7 @@ class test(Command): self.test_runner = getattr(self.distribution, 'test_runner', None) def with_project_on_sys_path(self, func): - with_2to3 = PY3 and getattr(self.distribution, 'use_2to3', False) + with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False) if with_2to3: # If we run 2to3 we can not do this inplace: @@ -145,7 +146,7 @@ class test(Command): # Purge modules under test from sys.modules. The test loader will # re-import them from the build location. Required when 2to3 is used # with namespace packages. - if PY3 and getattr(self.distribution, 'use_2to3', False): + if six.PY3 and getattr(self.distribution, 'use_2to3', False): module = self.test_args[-1].split('.')[0] if module in _namespace_packages: del_modules = [] diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index cd6c300c..360c10e8 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -16,17 +16,19 @@ import tempfile import sys import shutil -from setuptools.compat import httplib, urlparse, unicode, iteritems, PY3 +from six.moves import http_client, urllib +import six + from pkg_resources import iter_entry_points -errors = 'surrogateescape' if PY3 else 'strict' +errors = 'surrogateescape' if six.PY3 else 'strict' # This is not just a replacement for byte literals # but works as a general purpose encoder def b(s, encoding='utf-8'): - if isinstance(s, unicode): + if isinstance(s, six.text_type): return s.encode(encoding, errors) return s @@ -113,7 +115,7 @@ class upload_docs(upload): # set up the authentication credentials = b(self.username + ':' + self.password) credentials = standard_b64encode(credentials) - if PY3: + if six.PY3: credentials = credentials.decode('ascii') auth = "Basic " + credentials @@ -122,7 +124,7 @@ class upload_docs(upload): sep_boundary = b('\n--') + b(boundary) end_boundary = sep_boundary + b('--') body = [] - for key, values in iteritems(data): + for key, values in six.iteritems(data): title = '\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name if not isinstance(values, list): @@ -150,12 +152,12 @@ class upload_docs(upload): # We can't use urllib2 since we need to send the Basic # auth right with the first request schema, netloc, url, params, query, fragments = \ - urlparse(self.repository) + urllib.parse.urlparse(self.repository) assert not params and not query and not fragments if schema == 'http': - conn = httplib.HTTPConnection(netloc) + conn = http_client.HTTPConnection(netloc) elif schema == 'https': - conn = httplib.HTTPSConnection(netloc) + conn = http_client.HTTPSConnection(netloc) else: raise AssertionError("unsupported schema " + schema) diff --git a/setuptools/compat.py b/setuptools/compat.py deleted file mode 100644 index 73e6e4aa..00000000 --- a/setuptools/compat.py +++ /dev/null @@ -1,66 +0,0 @@ -import sys -import itertools - -PY3 = sys.version_info >= (3,) -PY2 = not PY3 - -if PY2: - basestring = basestring - import __builtin__ as builtins - import ConfigParser - from StringIO import StringIO - BytesIO = StringIO - func_code = lambda o: o.func_code - func_globals = lambda o: o.func_globals - im_func = lambda o: o.im_func - from htmlentitydefs import name2codepoint - import httplib - from BaseHTTPServer import HTTPServer - from SimpleHTTPServer import SimpleHTTPRequestHandler - from BaseHTTPServer import BaseHTTPRequestHandler - iteritems = lambda o: o.iteritems() - long_type = long - maxsize = sys.maxint - unichr = unichr - unicode = unicode - bytes = str - from urllib import url2pathname, splittag, pathname2url - import urllib2 - from urllib2 import urlopen, HTTPError, URLError, unquote, splituser - from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit - filterfalse = itertools.ifilterfalse - - exec("""def reraise(tp, value, tb=None): - raise tp, value, tb""") - -if PY3: - basestring = str - import builtins - import configparser as ConfigParser - from io import StringIO, BytesIO - func_code = lambda o: o.__code__ - func_globals = lambda o: o.__globals__ - im_func = lambda o: o.__func__ - from html.entities import name2codepoint - import http.client as httplib - from http.server import HTTPServer, SimpleHTTPRequestHandler - from http.server import BaseHTTPRequestHandler - iteritems = lambda o: o.items() - long_type = int - maxsize = sys.maxsize - unichr = chr - unicode = str - bytes = bytes - from urllib.error import HTTPError, URLError - import urllib.request as urllib2 - from urllib.request import urlopen, url2pathname, pathname2url - from urllib.parse import ( - urlparse, urlunparse, unquote, splituser, urljoin, urlsplit, - urlunsplit, splittag, - ) - filterfalse = itertools.filterfalse - - def reraise(tp, value, tb=None): - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value diff --git a/setuptools/depends.py b/setuptools/depends.py index e87ef3f3..43617e6d 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -3,7 +3,8 @@ import imp import marshal from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from distutils.version import StrictVersion -from setuptools import compat + +import six __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -99,7 +100,8 @@ def _iter_code(code): ptr += 3 if op==EXTENDED_ARG: - extended_arg = arg * compat.long_type(65536) + long_type = six.integer_types[-1] + extended_arg = arg * long_type(65536) continue else: diff --git a/setuptools/dist.py b/setuptools/dist.py index 6b9d350e..99939f45 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -13,8 +13,9 @@ from distutils.core import Distribution as _Distribution from distutils.errors import (DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError) +import six + from setuptools.depends import Require -from setuptools.compat import basestring, PY2 from setuptools import windows_support import pkg_resources @@ -133,7 +134,7 @@ def check_entry_points(dist, attr, value): raise DistutilsSetupError(e) def check_test_suite(dist, attr, value): - if not isinstance(value,basestring): + if not isinstance(value, six.string_types): raise DistutilsSetupError("test_suite must be a string") def check_package_data(dist, attr, value): @@ -649,7 +650,7 @@ class Distribution(_Distribution): """ import sys - if PY2 or self.help_commands: + if six.PY2 or self.help_commands: return _Distribution.handle_display_options(self, option_order) # Stdout may be StringIO (e.g. in tests) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 58572ce6..a14c8ac6 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -8,6 +8,14 @@ import base64 import hashlib from functools import wraps +try: + from urllib.parse import splituser +except ImportError: + from urllib2 import splituser + +import six +from six.moves import urllib, http_client + from pkg_resources import ( CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST, require, Environment, find_distributions, safe_name, safe_version, @@ -16,12 +24,6 @@ from pkg_resources import ( from setuptools import ssl_support from distutils import log from distutils.errors import DistutilsError -from setuptools.compat import (urllib2, httplib, StringIO, HTTPError, - urlparse, urlunparse, unquote, splituser, - url2pathname, name2codepoint, - unichr, urljoin, urlsplit, urlunsplit, - ConfigParser) -from setuptools.compat import filterfalse from fnmatch import translate from setuptools.py26compat import strip_fragment from setuptools.py27compat import get_all_headers @@ -68,10 +70,11 @@ def parse_bdist_wininst(name): def egg_info_for_url(url): - scheme, server, path, parameters, query, fragment = urlparse(url) - base = unquote(path.split('/')[-1]) + parts = urllib.parse.urlparse(url) + scheme, server, path, parameters, query, fragment = parts + base = urllib.parse.unquote(path.split('/')[-1]) if server=='sourceforge.net' and base=='download': # XXX Yuck - base = unquote(path.split('/')[-2]) + base = urllib.parse.unquote(path.split('/')[-2]) if '#' in base: base, fragment = base.split('#',1) return base,fragment @@ -158,7 +161,7 @@ def unique_everseen(iterable, key=None): seen = set() seen_add = seen.add if key is None: - for element in filterfalse(seen.__contains__, iterable): + for element in six.moves.filterfalse(seen.__contains__, iterable): seen_add(element) yield element else: @@ -190,14 +193,14 @@ def find_external_links(url, page): rels = set(map(str.strip, rel.lower().split(','))) if 'homepage' in rels or 'download' in rels: for match in HREF.finditer(tag): - yield urljoin(url, htmldecode(match.group(1))) + yield urllib.parse.urljoin(url, htmldecode(match.group(1))) for tag in ("<th>Home Page", "<th>Download URL"): pos = page.find(tag) if pos!=-1: match = HREF.search(page,pos) if match: - yield urljoin(url, htmldecode(match.group(1))) + yield urllib.parse.urljoin(url, htmldecode(match.group(1))) user_agent = "Python-urllib/%s setuptools/%s" % ( sys.version[:3], require('setuptools')[0].version @@ -240,7 +243,7 @@ class HashChecker(ContentChecker): @classmethod def from_url(cls, url): "Construct a (possibly null) ContentChecker from a URL" - fragment = urlparse(url)[-1] + fragment = urllib.parse.urlparse(url)[-1] if not fragment: return ContentChecker() match = cls.pattern.search(fragment) @@ -275,7 +278,7 @@ class PackageIndex(Environment): self.to_scan = [] if verify_ssl and ssl_support.is_available and (ca_bundle or ssl_support.find_ca_bundle()): self.opener = ssl_support.opener_for(ca_bundle) - else: self.opener = urllib2.urlopen + else: self.opener = urllib.request.urlopen def process_url(self, url, retrieve=False): """Evaluate a URL as a possible download, and maybe retrieve it""" @@ -312,7 +315,7 @@ class PackageIndex(Environment): base = f.url # handle redirects page = f.read() if not isinstance(page, str): # We are in Python 3 and got bytes. We want str. - if isinstance(f, HTTPError): + if isinstance(f, urllib.error.HTTPError): # Errors have no charset, assume latin1: charset = 'latin-1' else: @@ -320,7 +323,7 @@ class PackageIndex(Environment): page = page.decode(charset, "ignore") f.close() for match in HREF.finditer(page): - link = urljoin(base, htmldecode(match.group(1))) + link = urllib.parse.urljoin(base, htmldecode(match.group(1))) self.process_url(link) if url.startswith(self.index_url) and getattr(f,'code',None)!=404: page = self.process_index(url, page) @@ -343,7 +346,7 @@ class PackageIndex(Environment): def url_ok(self, url, fatal=False): s = URL_SCHEME(url) - if (s and s.group(1).lower()=='file') or self.allows(urlparse(url)[1]): + if (s and s.group(1).lower()=='file') or self.allows(urllib.parse.urlparse(url)[1]): return True msg = ("\nNote: Bypassing %s (disallowed host; see " "http://bit.ly/1dg9ijs for details).\n") @@ -374,7 +377,7 @@ class PackageIndex(Environment): # Process a URL to see if it's for a package page if link.startswith(self.index_url): parts = list(map( - unquote, link[len(self.index_url):].split('/') + urllib.parse.unquote, link[len(self.index_url):].split('/') )) if len(parts)==2 and '#' not in parts[1]: # it's a package page, sanitize and index it @@ -387,7 +390,7 @@ class PackageIndex(Environment): # process an index page into the package-page index for match in HREF.finditer(page): try: - scan(urljoin(url, htmldecode(match.group(1)))) + scan(urllib.parse.urljoin(url, htmldecode(match.group(1)))) except ValueError: pass @@ -663,7 +666,7 @@ class PackageIndex(Environment): try: checker = HashChecker.from_url(url) fp = self.open_url(strip_fragment(url)) - if isinstance(fp, HTTPError): + if isinstance(fp, urllib.error.HTTPError): raise DistutilsError( "Can't download %s: %s %s" % (url, fp.code,fp.msg) ) @@ -699,24 +702,24 @@ class PackageIndex(Environment): return local_open(url) try: return open_with_auth(url, self.opener) - except (ValueError, httplib.InvalidURL): + except (ValueError, http_client.InvalidURL): v = sys.exc_info()[1] msg = ' '.join([str(arg) for arg in v.args]) if warning: self.warn(warning, msg) else: raise DistutilsError('%s %s' % (url, msg)) - except urllib2.HTTPError: + except urllib.error.HTTPError: v = sys.exc_info()[1] return v - except urllib2.URLError: + except urllib.error.URLError: v = sys.exc_info()[1] if warning: self.warn(warning, v.reason) else: raise DistutilsError("Download error for %s: %s" % (url, v.reason)) - except httplib.BadStatusLine: + except http_client.BadStatusLine: v = sys.exc_info()[1] if warning: self.warn(warning, v.line) @@ -726,7 +729,7 @@ class PackageIndex(Environment): 'down, %s' % (url, v.line) ) - except httplib.HTTPException: + except http_client.HTTPException: v = sys.exc_info()[1] if warning: self.warn(warning, v) @@ -758,7 +761,7 @@ class PackageIndex(Environment): elif scheme.startswith('hg+'): return self._download_hg(url, filename) elif scheme=='file': - return url2pathname(urlparse(url)[2]) + return urllib.request.url2pathname(urllib.parse.urlparse(url)[2]) else: self.url_ok(url, True) # raises error if not allowed return self._attempt_download(url, filename) @@ -792,7 +795,7 @@ class PackageIndex(Environment): url = url.split('#',1)[0] # remove any fragment for svn's sake creds = '' if url.lower().startswith('svn:') and '@' in url: - scheme, netloc, path, p, q, f = urlparse(url) + scheme, netloc, path, p, q, f = urllib.parse.urlparse(url) if not netloc and path.startswith('//') and '/' in path[2:]: netloc, path = path[2:].split('/',1) auth, host = splituser(netloc) @@ -803,14 +806,15 @@ class PackageIndex(Environment): else: creds = " --username="+auth netloc = host - url = urlunparse((scheme, netloc, url, p, q, f)) + parts = scheme, netloc, url, p, q, f + url = urllib.parse.urlunparse(parts) self.info("Doing subversion checkout from %s to %s", url, filename) os.system("svn checkout%s -q %s %s" % (creds, url, filename)) return filename @staticmethod def _vcs_split_rev_from_url(url, pop_prefix=False): - scheme, netloc, path, query, frag = urlsplit(url) + scheme, netloc, path, query, frag = urllib.parse.urlsplit(url) scheme = scheme.split('+', 1)[-1] @@ -822,7 +826,7 @@ class PackageIndex(Environment): path, rev = path.rsplit('@', 1) # Also, discard fragment - url = urlunsplit((scheme, netloc, path, query, '')) + url = urllib.parse.urlunsplit((scheme, netloc, path, query, '')) return url, rev @@ -874,7 +878,7 @@ entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub def uchr(c): if not isinstance(c, int): return c - if c>255: return unichr(c) + if c>255: return six.unichr(c) return chr(c) def decode_entity(match): @@ -884,7 +888,7 @@ def decode_entity(match): elif what.startswith('#'): what = int(what[1:]) else: - what = name2codepoint.get(what, match.group(0)) + what = six.moves.html_entities.name2codepoint.get(what, match.group(0)) return uchr(what) def htmldecode(text): @@ -915,7 +919,7 @@ def _encode_auth(auth): >>> chr(10) in str(_encode_auth(long_auth)) False """ - auth_s = unquote(auth) + auth_s = urllib.parse.unquote(auth) # convert to bytes auth_bytes = auth_s.encode() # use the legacy interface for Python 2.3 support @@ -940,14 +944,14 @@ class Credential(object): def __str__(self): return '%(username)s:%(password)s' % vars(self) -class PyPIConfig(ConfigParser.ConfigParser): +class PyPIConfig(six.moves.configparser.ConfigParser): def __init__(self): """ Load from ~/.pypirc """ defaults = dict.fromkeys(['username', 'password', 'repository'], '') - ConfigParser.ConfigParser.__init__(self, defaults) + six.moves.configparser.ConfigParser.__init__(self, defaults) rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): @@ -979,15 +983,15 @@ class PyPIConfig(ConfigParser.ConfigParser): return cred -def open_with_auth(url, opener=urllib2.urlopen): +def open_with_auth(url, opener=urllib.request.urlopen): """Open a urllib2 request, handling HTTP authentication""" - scheme, netloc, path, params, query, frag = urlparse(url) + scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url) # Double scheme does not raise on Mac OS X as revealed by a # failing test. We would expect "nonnumeric port". Refs #20. if netloc.endswith(':'): - raise httplib.InvalidURL("nonnumeric port: ''") + raise http_client.InvalidURL("nonnumeric port: ''") if scheme in ('http', 'https'): auth, host = splituser(netloc) @@ -1003,11 +1007,12 @@ def open_with_auth(url, opener=urllib2.urlopen): if auth: auth = "Basic " + _encode_auth(auth) - new_url = urlunparse((scheme,host,path,params,query,frag)) - request = urllib2.Request(new_url) + parts = scheme, host, path, params, query, frag + new_url = urllib.parse.urlunparse(parts) + request = urllib.request.Request(new_url) request.add_header("Authorization", auth) else: - request = urllib2.Request(url) + request = urllib.request.Request(url) request.add_header('User-Agent', user_agent) fp = opener(request) @@ -1015,9 +1020,10 @@ def open_with_auth(url, opener=urllib2.urlopen): if auth: # Put authentication info back into request URL if same host, # so that links found on the page will work - s2, h2, path2, param2, query2, frag2 = urlparse(fp.url) + s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url) if s2==scheme and h2==host: - fp.url = urlunparse((s2,netloc,path2,param2,query2,frag2)) + parts = s2, netloc, path2, param2, query2, frag2 + fp.url = urllib.parse.urlunparse(parts) return fp @@ -1030,10 +1036,10 @@ def fix_sf_url(url): def local_open(url): """Read a local path, with special support for directories""" - scheme, server, path, param, query, frag = urlparse(url) - filename = url2pathname(path) + scheme, server, path, param, query, frag = urllib.parse.urlparse(url) + filename = urllib.request.url2pathname(path) if os.path.isfile(filename): - return urllib2.urlopen(url) + return urllib.request.urlopen(url) elif path.endswith('/') and os.path.isdir(filename): files = [] for f in os.listdir(filename): @@ -1052,4 +1058,5 @@ def local_open(url): status, message, body = 404, "Path not found", "Not found" headers = {'content-type': 'text/html'} - return HTTPError(url, status, message, headers, StringIO(body)) + body_stream = six.StringIO(body) + return urllib.error.HTTPError(url, status, message, headers, body_stream) diff --git a/setuptools/py26compat.py b/setuptools/py26compat.py index 738b0cc4..e52bd85b 100644 --- a/setuptools/py26compat.py +++ b/setuptools/py26compat.py @@ -4,7 +4,10 @@ Compatibility Support for Python 2.6 and earlier import sys -from setuptools.compat import splittag +try: + from urllib.parse import splittag +except ImportError: + from urllib import splittag def strip_fragment(url): """ diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index e79a13a8..1d23ba98 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -6,6 +6,8 @@ import functools import itertools import re +from six.moves import builtins + import pkg_resources if os.name == "java": @@ -20,8 +22,6 @@ _open = open from distutils.errors import DistutilsError from pkg_resources import working_set -from setuptools.compat import builtins - __all__ = [ "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup", ] diff --git a/setuptools/ssl_support.py b/setuptools/ssl_support.py index cc7db067..c618ea7c 100644 --- a/setuptools/ssl_support.py +++ b/setuptools/ssl_support.py @@ -3,9 +3,10 @@ import socket import atexit import re +from six.moves import urllib, http_client + import pkg_resources from pkg_resources import ResolutionError, ExtractionError -from setuptools.compat import urllib2 try: import ssl @@ -27,17 +28,11 @@ cert_paths = """ """.strip().split() -HTTPSHandler = HTTPSConnection = object - -for what, where in ( - ('HTTPSHandler', ['urllib2','urllib.request']), - ('HTTPSConnection', ['httplib', 'http.client']), -): - for module in where: - try: - exec("from %s import %s" % (module, what)) - except ImportError: - pass +try: + HTTPSHandler = urllib.request.HTTPSHandler + HTTPSConnection = http_client.HTTPSConnection +except AttributeError: + HTTPSHandler = HTTPSConnection = object is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection) @@ -198,7 +193,7 @@ class VerifyingHTTPSConn(HTTPSConnection): def opener_for(ca_bundle=None): """Get a urlopen() replacement that uses ca_bundle for verification""" - return urllib2.build_opener( + return urllib.request.build_opener( VerifyingHTTPSHandler(ca_bundle or find_ca_bundle()) ).open diff --git a/setuptools/svn_utils.py b/setuptools/svn_utils.py index 6502fc98..f80fd9f3 100644 --- a/setuptools/svn_utils.py +++ b/setuptools/svn_utils.py @@ -10,14 +10,11 @@ import locale import codecs
import unicodedata
import warnings
-from setuptools.compat import unicode, PY2
from setuptools.py31compat import TemporaryDirectory
from xml.sax.saxutils import unescape
-try:
- import urlparse
-except ImportError:
- import urllib.parse as urlparse
+import six
+from six.moves import urllib
from subprocess import Popen as _Popen, PIPE as _PIPE
@@ -62,7 +59,7 @@ def _get_target_property(target): def _get_xml_data(decoded_str):
- if PY2:
+ if six.PY2:
#old versions want an encoded string
data = decoded_str.encode('utf-8')
else:
@@ -120,7 +117,7 @@ def decode_as_string(text, encoding=None): if encoding is None:
encoding = _console_encoding
- if not isinstance(text, unicode):
+ if not isinstance(text, six.text_type):
text = text.decode(encoding)
text = unicodedata.normalize('NFC', text)
@@ -182,17 +179,17 @@ def parse_external_prop(lines): if not line:
continue
- if PY2:
+ if six.PY2:
#shlex handles NULLs just fine and shlex in 2.7 tries to encode
#as ascii automatiically
line = line.encode('utf-8')
line = shlex.split(line)
- if PY2:
+ if six.PY2:
line = [x.decode('utf-8') for x in line]
#EXT_FOLDERNAME is either the first or last depending on where
#the URL falls
- if urlparse.urlsplit(line[-1])[0]:
+ if urllib.parse.urlsplit(line[-1])[0]:
external = line[0]
else:
external = line[-1]
diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py index d6a4542e..823cf937 100644 --- a/setuptools/tests/__init__.py +++ b/setuptools/tests/__init__.py @@ -9,9 +9,9 @@ from distutils.errors import DistutilsOptionError, DistutilsPlatformError from distutils.errors import DistutilsSetupError from distutils.core import Extension from distutils.version import LooseVersion -from setuptools.compat import func_code -from setuptools.compat import func_code +import six + import setuptools.dist import setuptools.depends as dep from setuptools import Feature @@ -54,7 +54,7 @@ class DependsTests(unittest.TestCase): x = "test" y = z - fc = func_code(f1) + fc = six.get_function_code(f1) # unrecognized name self.assertEqual(dep.extract_constant(fc,'q', -1), None) diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py index ae2381e3..099e8b19 100644 --- a/setuptools/tests/server.py +++ b/setuptools/tests/server.py @@ -3,11 +3,10 @@ import sys import time import threading -from setuptools.compat import BaseHTTPRequestHandler -from setuptools.compat import (urllib2, URLError, HTTPServer, - SimpleHTTPRequestHandler) -class IndexServer(HTTPServer): +from six.moves import BaseHTTPServer, SimpleHTTPServer, urllib + +class IndexServer(BaseHTTPServer.HTTPServer): """Basic single-threaded http server simulating a package index You can use this server in unittest like this:: @@ -19,8 +18,9 @@ class IndexServer(HTTPServer): s.stop() """ def __init__(self, server_address=('', 0), - RequestHandlerClass=SimpleHTTPRequestHandler): - HTTPServer.__init__(self, server_address, RequestHandlerClass) + RequestHandlerClass=SimpleHTTPServer.SimpleHTTPRequestHandler): + BaseHTTPServer.HTTPServer.__init__(self, server_address, + RequestHandlerClass) self._run = True def serve(self): @@ -44,10 +44,10 @@ class IndexServer(HTTPServer): url = 'http://127.0.0.1:%(server_port)s/' % vars(self) try: if sys.version_info >= (2, 6): - urllib2.urlopen(url, timeout=5) + urllib.request.urlopen(url, timeout=5) else: - urllib2.urlopen(url) - except URLError: + urllib.request.urlopen(url) + except urllib.error.URLError: # ignore any errors; all that's important is the request pass self.thread.join() @@ -57,19 +57,20 @@ class IndexServer(HTTPServer): port = self.server_port return 'http://127.0.0.1:%s/setuptools/tests/indexes/' % port -class RequestRecorder(BaseHTTPRequestHandler): +class RequestRecorder(BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(self): requests = vars(self.server).setdefault('requests', []) requests.append(self) self.send_response(200, 'OK') -class MockServer(HTTPServer, threading.Thread): +class MockServer(BaseHTTPServer.HTTPServer, threading.Thread): """ A simple HTTP Server that records the requests made to it. """ def __init__(self, server_address=('', 0), RequestHandlerClass=RequestRecorder): - HTTPServer.__init__(self, server_address, RequestHandlerClass) + BaseHTTPServer.HTTPServer.__init__(self, server_address, + RequestHandlerClass) threading.Thread.__init__(self) self.setDaemon(True) self.requests = [] diff --git a/setuptools/tests/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py index cf4bcd11..937e0ed0 100644 --- a/setuptools/tests/test_bdist_egg.py +++ b/setuptools/tests/test_bdist_egg.py @@ -8,8 +8,9 @@ import sys import tempfile import unittest +import six + from distutils.errors import DistutilsError -from setuptools.compat import StringIO from setuptools.command.bdist_egg import bdist_egg from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution @@ -56,7 +57,7 @@ class TestDevelopTest(unittest.TestCase): )) os.makedirs(os.path.join('build', 'src')) old_stdout = sys.stdout - sys.stdout = o = StringIO() + sys.stdout = o = six.StringIO() try: dist.parse_command_line() dist.run_commands() @@ -69,4 +70,3 @@ class TestDevelopTest(unittest.TestCase): def test_suite(): return unittest.makeSuite(TestDevelopTest) - diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index a4430953..8dfe234e 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -11,8 +11,11 @@ import textwrap import tarfile import logging import distutils.core +import io + +import six +from six.moves import urllib -from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup, SandboxViolation from setuptools.command.easy_install import ( easy_install, fix_jython_executable, get_script_args, nt_quote_arg) @@ -261,7 +264,7 @@ class TestSetupRequires(unittest.TestCase): p_index = setuptools.tests.server.MockServer() p_index.start() netloc = 1 - p_index_loc = urlparse(p_index.url)[netloc] + p_index_loc = urllib.parse.urlparse(p_index.url)[netloc] if p_index_loc.endswith(':0'): # Some platforms (Jython) don't find a port to which to bind, # so skip this test for them. @@ -385,12 +388,7 @@ def make_trivial_sdist(dist_path, setup_py): """ setup_py_file = tarfile.TarInfo(name='setup.py') - try: - # Python 3 (StringIO gets converted to io module) - MemFile = BytesIO - except AttributeError: - MemFile = StringIO - setup_py_bytes = MemFile(setup_py.encode('utf-8')) + setup_py_bytes = io.BytesIO(setup_py.encode('utf-8')) setup_py_file.size = len(setup_py_bytes.getvalue()) dist = tarfile.open(dist_path, 'w:gz') try: @@ -451,8 +449,8 @@ def quiet_context(): old_stdout = sys.stdout old_stderr = sys.stderr - new_stdout = sys.stdout = StringIO() - new_stderr = sys.stderr = StringIO() + new_stdout = sys.stdout = six.StringIO() + new_stderr = sys.stderr = six.StringIO() try: yield new_stdout, new_stderr finally: diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index 664566a3..40ae0af3 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -3,9 +3,12 @@ import sys import os import unittest -import pkg_resources -from setuptools.compat import urllib2, httplib, HTTPError, unicode, pathname2url import distutils.errors + +import six +from six.moves import urllib, http_client + +import pkg_resources import setuptools.package_index from setuptools.tests.server import IndexServer @@ -20,7 +23,7 @@ class TestPackageIndex(unittest.TestCase): v = sys.exc_info()[1] self.assertTrue(url in str(v)) else: - self.assertTrue(isinstance(v, HTTPError)) + self.assertTrue(isinstance(v, urllib.error.HTTPError)) def test_bad_url_typo(self): # issue 16 @@ -37,7 +40,7 @@ class TestPackageIndex(unittest.TestCase): v = sys.exc_info()[1] self.assertTrue(url in str(v)) else: - self.assertTrue(isinstance(v, HTTPError)) + self.assertTrue(isinstance(v, urllib.error.HTTPError)) def test_bad_url_bad_status_line(self): index = setuptools.package_index.PackageIndex( @@ -45,7 +48,7 @@ class TestPackageIndex(unittest.TestCase): ) def _urlopen(*args): - raise httplib.BadStatusLine('line') + raise http_client.BadStatusLine('line') index.opener = _urlopen url = 'http://example.com' @@ -71,7 +74,7 @@ class TestPackageIndex(unittest.TestCase): index.open_url(url) except distutils.errors.DistutilsError: error = sys.exc_info()[1] - msg = unicode(error) + msg = six.text_type(error) assert 'nonnumeric port' in msg or 'getaddrinfo failed' in msg or 'Name or service not known' in msg return raise RuntimeError("Did not raise") @@ -160,7 +163,7 @@ class TestPackageIndex(unittest.TestCase): f.write('<div>content</div>') f.close() try: - url = 'file:' + pathname2url(os.getcwd()) + '/' + url = 'file:' + urllib.request.pathname2url(os.getcwd()) + '/' res = setuptools.package_index.local_open(url) finally: os.remove('index.html') diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py index 3baa3ab1..b688cfe0 100644 --- a/setuptools/tests/test_resources.py +++ b/setuptools/tests/test_resources.py @@ -15,9 +15,10 @@ from pkg_resources import (parse_requirements, VersionConflict, parse_version, from setuptools.command.easy_install import (get_script_header, is_sh, nt_quote_arg) -from setuptools.compat import StringIO, iteritems, PY3 from .py26compat import skipIf +import six + def safe_repr(obj, short=False): """ copied from Python2.7""" try: @@ -266,7 +267,7 @@ class EntryPointTests(TestCase): def checkSubMap(self, m): self.assertEqual(len(m), len(self.submap_expect)) - for key, ep in iteritems(self.submap_expect): + for key, ep in six.iteritems(self.submap_expect): self.assertEqual(repr(m.get(key)), repr(ep)) submap_expect = dict( @@ -518,7 +519,7 @@ class ScriptHeaderTests(TestCase): def test_get_script_header_jython_workaround(self): # This test doesn't work with Python 3 in some locales - if PY3 and os.environ.get("LC_CTYPE") in (None, "C", "POSIX"): + if six.PY3 and os.environ.get("LC_CTYPE") in (None, "C", "POSIX"): return class java: @@ -541,12 +542,12 @@ class ScriptHeaderTests(TestCase): # Ensure we generate what is basically a broken shebang line # when there's options, with a warning emitted - sys.stdout = sys.stderr = StringIO() + sys.stdout = sys.stderr = six.StringIO() self.assertEqual(get_script_header('#!/usr/bin/python -x', executable=exe), '#!%s -x\n' % exe) self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue()) - sys.stdout = sys.stderr = StringIO() + sys.stdout = sys.stderr = six.StringIO() self.assertEqual(get_script_header('#!/usr/bin/python', executable=self.non_ascii_exe), '#!%s -x\n' % self.non_ascii_exe) diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 5f8a190f..26b072cc 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -10,10 +10,11 @@ import unittest import unicodedata import re import contextlib + +import six + from setuptools.tests import environment, test_svn from setuptools.tests.py26compat import skipIf - -from setuptools.compat import StringIO, unicode, PY3, PY2 from setuptools.command.sdist import sdist, walk_revctrl from setuptools.command.egg_info import manifest_maker from setuptools.dist import Distribution @@ -34,7 +35,7 @@ setup(**%r) """ % SETUP_ATTRS -if PY3: +if six.PY3: LATIN1_FILENAME = 'smörbröd.py'.encode('latin-1') else: LATIN1_FILENAME = 'sm\xf6rbr\xf6d.py' @@ -44,7 +45,7 @@ else: @contextlib.contextmanager def quiet(): old_stdout, old_stderr = sys.stdout, sys.stderr - sys.stdout, sys.stderr = StringIO(), StringIO() + sys.stdout, sys.stderr = six.StringIO(), six.StringIO() try: yield finally: @@ -53,14 +54,14 @@ def quiet(): # Fake byte literals for Python <= 2.5 def b(s, encoding='utf-8'): - if PY3: + if six.PY3: return s.encode(encoding) return s # Convert to POSIX path def posix(path): - if PY3 and not isinstance(path, str): + if six.PY3 and not isinstance(path, str): return path.replace(os.sep.encode('ascii'), b('/')) else: return path.replace(os.sep, '/') @@ -68,7 +69,7 @@ def posix(path): # HFS Plus uses decomposed UTF-8 def decompose(path): - if isinstance(path, unicode): + if isinstance(path, six.text_type): return unicodedata.normalize('NFD', path) try: path = path.decode('utf-8') @@ -181,14 +182,14 @@ class TestSdistTest(unittest.TestCase): self.fail(e) # The manifest should contain the UTF-8 filename - if PY2: + if six.PY2: fs_enc = sys.getfilesystemencoding() filename = filename.decode(fs_enc) self.assertTrue(posix(filename) in u_contents) # Python 3 only - if PY3: + if six.PY3: def test_write_manifest_allows_utf8_filenames(self): # Test for #303. @@ -297,12 +298,12 @@ class TestSdistTest(unittest.TestCase): cmd.read_manifest() # The filelist should contain the UTF-8 filename - if PY3: + if six.PY3: filename = filename.decode('utf-8') self.assertTrue(filename in cmd.filelist.files) # Python 3 only - if PY3: + if six.PY3: def test_read_manifest_skips_non_utf8_filenames(self): # Test for #303. @@ -338,7 +339,7 @@ class TestSdistTest(unittest.TestCase): filename = filename.decode('latin-1') self.assertFalse(filename in cmd.filelist.files) - @skipIf(PY3 and locale.getpreferredencoding() != 'UTF-8', + @skipIf(six.PY3 and locale.getpreferredencoding() != 'UTF-8', 'Unittest fails if locale is not utf-8 but the manifests is recorded correctly') def test_sdist_with_utf8_encoded_filename(self): # Test for #303. @@ -357,7 +358,7 @@ class TestSdistTest(unittest.TestCase): if sys.platform == 'darwin': filename = decompose(filename) - if PY3: + if six.PY3: fs_enc = sys.getfilesystemencoding() if sys.platform == 'win32': @@ -389,7 +390,7 @@ class TestSdistTest(unittest.TestCase): with quiet(): cmd.run() - if PY3: + if six.PY3: # not all windows systems have a default FS encoding of cp1252 if sys.platform == 'win32': # Latin-1 is similar to Windows-1252 however diff --git a/setuptools/tests/test_svn.py b/setuptools/tests/test_svn.py index 33400362..0e6c3e95 100644 --- a/setuptools/tests/test_svn.py +++ b/setuptools/tests/test_svn.py @@ -6,9 +6,10 @@ import os import subprocess import sys import unittest -from setuptools.tests import environment -from setuptools.compat import unicode, unichr +import six + +from setuptools.tests import environment from setuptools import svn_utils from setuptools.tests.py26compat import skipIf @@ -119,13 +120,13 @@ class ParserExternalXML(unittest.TestCase): os.sep.join((example_base, folder3)), # folder is third_party大介 os.sep.join((example_base, - unicode('third_party') + - unichr(0x5927) + unichr(0x4ecb))), + six.text_type('third_party') + + six.unichr(0x5927) + six.unichr(0x4ecb))), os.sep.join((example_base, 'folder', folder2)), os.sep.join((example_base, 'folder', folder3)), os.sep.join((example_base, 'folder', - unicode('third_party') + - unichr(0x5927) + unichr(0x4ecb))), + six.text_type('third_party') + + six.unichr(0x5927) + six.unichr(0x4ecb))), ]) expected = set(os.path.normpath(x) for x in expected) diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py index df92085e..67df14e5 100644 --- a/setuptools/tests/test_test.py +++ b/setuptools/tests/test_test.py @@ -8,9 +8,10 @@ import site import sys import tempfile import unittest - from distutils.errors import DistutilsError -from setuptools.compat import StringIO, PY2 + +import six + from setuptools.command.test import test from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution @@ -34,7 +35,7 @@ except ImportError: __path__ = extend_path(__path__, __name__) """ # Make sure this is Latin-1 binary, before writing: -if PY2: +if six.PY2: NS_INIT = NS_INIT.decode('UTF-8') NS_INIT = NS_INIT.encode('Latin-1') @@ -115,7 +116,7 @@ class TestTestTest(unittest.TestCase): cmd.install_dir = site.USER_SITE cmd.user = 1 old_stdout = sys.stdout - sys.stdout = StringIO() + sys.stdout = six.StringIO() try: try: # try/except/finally doesn't work in Python 2.4, so we need nested try-statements. cmd.run() diff --git a/setuptools/unicode_utils.py b/setuptools/unicode_utils.py index d2de941a..f028589e 100644 --- a/setuptools/unicode_utils.py +++ b/setuptools/unicode_utils.py @@ -1,11 +1,11 @@ import unicodedata import sys -from setuptools.compat import unicode as decoded_string +import six # HFS Plus uses decomposed UTF-8 def decompose(path): - if isinstance(path, decoded_string): + if isinstance(path, six.text_type): return unicodedata.normalize('NFD', path) try: path = path.decode('utf-8') @@ -23,7 +23,7 @@ def filesys_decode(path): """ fs_enc = sys.getfilesystemencoding() - if isinstance(path, decoded_string): + if isinstance(path, six.text_type): return path for enc in (fs_enc, "utf-8"): |