summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--distutils2/_backport/__init__.py6
-rw-r--r--distutils2/_backport/misc.py141
-rw-r--r--distutils2/_backport/tests/test_shutil.py2
-rw-r--r--distutils2/command/build_scripts.py2
-rw-r--r--distutils2/compat.py143
-rw-r--r--distutils2/create.py6
-rw-r--r--distutils2/markers.py2
-rw-r--r--distutils2/pypi/simple.py6
-rw-r--r--distutils2/tests/pypi_server.py2
-rw-r--r--distutils2/tests/test_markers.py2
10 files changed, 155 insertions, 157 deletions
diff --git a/distutils2/_backport/__init__.py b/distutils2/_backport/__init__.py
index ce6f11b..3d67498 100644
--- a/distutils2/_backport/__init__.py
+++ b/distutils2/_backport/__init__.py
@@ -1,4 +1,6 @@
-"""Modules copied from Python 3 standard libraries.
+"""Modules copied from Python 3 standard libraries, for internal use only.
-Individual classes and objects like the any function are in compat.
+Individual classes and functions are found in d2._backport.misc. Intended
+usage is to always import things missing from 2.4 from that module: the
+built-in/stdlib objects will be used if found.
"""
diff --git a/distutils2/_backport/misc.py b/distutils2/_backport/misc.py
new file mode 100644
index 0000000..1759c94
--- /dev/null
+++ b/distutils2/_backport/misc.py
@@ -0,0 +1,141 @@
+"""Backports for individual classes and functions."""
+
+import os
+import re
+import sys
+import codecs
+
+__all__ = ['any', 'detect_encoding', 'fsencode', 'python_implementation',
+ 'wraps']
+
+
+try:
+ any = any
+except NameError:
+ def any(seq):
+ for elem in seq:
+ if elem:
+ return True
+ return False
+
+
+_cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
+
+
+def _get_normal_name(orig_enc):
+ """Imitates get_normal_name in tokenizer.c."""
+ # Only care about the first 12 characters.
+ enc = orig_enc[:12].lower().replace("_", "-")
+ if enc == "utf-8" or enc.startswith("utf-8-"):
+ return "utf-8"
+ if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
+ enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
+ return "iso-8859-1"
+ return orig_enc
+
+
+def detect_encoding(readline):
+ """
+ The detect_encoding() function is used to detect the encoding that should
+ be used to decode a Python source file. It requires one argment, readline,
+ in the same way as the tokenize() generator.
+
+ It will call readline a maximum of twice, and return the encoding used
+ (as a string) and a list of any lines (left as bytes) it has read in.
+
+ It detects the encoding from the presence of a utf-8 bom or an encoding
+ cookie as specified in pep-0263. If both a bom and a cookie are present,
+ but disagree, a SyntaxError will be raised. If the encoding cookie is an
+ invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
+ 'utf-8-sig' is returned.
+
+ If no encoding is specified, then the default of 'utf-8' will be returned.
+ """
+ bom_found = False
+ encoding = None
+ default = 'utf-8'
+
+ def read_or_stop():
+ try:
+ return readline()
+ except StopIteration:
+ return ''
+
+ def find_cookie(line):
+ try:
+ line_string = line.decode('ascii')
+ except UnicodeDecodeError:
+ return None
+
+ matches = _cookie_re.findall(line_string)
+ if not matches:
+ return None
+ encoding = _get_normal_name(matches[0])
+ try:
+ codec = codecs.lookup(encoding)
+ except LookupError:
+ # This behaviour mimics the Python interpreter
+ raise SyntaxError("unknown encoding: " + encoding)
+
+ if bom_found:
+ if codec.name != 'utf-8':
+ # This behaviour mimics the Python interpreter
+ raise SyntaxError('encoding problem: utf-8')
+ encoding += '-sig'
+ return encoding
+
+ first = read_or_stop()
+ if first.startswith(codecs.BOM_UTF8):
+ bom_found = True
+ first = first[3:]
+ default = 'utf-8-sig'
+ if not first:
+ return default, []
+
+ encoding = find_cookie(first)
+ if encoding:
+ return encoding, [first]
+
+ second = read_or_stop()
+ if not second:
+ return default, [first]
+
+ encoding = find_cookie(second)
+ if encoding:
+ return encoding, [first, second]
+
+ return default, [first, second]
+
+
+def fsencode(filename):
+ if isinstance(filename, str):
+ return filename
+ elif isinstance(filename, unicode):
+ return filename.encode(sys.getfilesystemencoding())
+ else:
+ raise TypeError("expect bytes or str, not %s" %
+ type(filename).__name__)
+
+
+try:
+ from functools import wraps
+except ImportError:
+ def wraps(func=None):
+ """No-op replacement for functools.wraps"""
+ def wrapped(func):
+ return func
+ return wrapped
+
+
+try:
+ from platform import python_implementation
+except ImportError:
+ def python_implementation():
+ """Return a string identifying the Python implementation."""
+ if 'PyPy' in sys.version:
+ return 'PyPy'
+ if os.name == 'java':
+ return 'Jython'
+ if sys.version.startswith('IronPython'):
+ return 'IronPython'
+ return 'CPython'
diff --git a/distutils2/_backport/tests/test_shutil.py b/distutils2/_backport/tests/test_shutil.py
index fc883ad..b058d67 100644
--- a/distutils2/_backport/tests/test_shutil.py
+++ b/distutils2/_backport/tests/test_shutil.py
@@ -6,13 +6,13 @@ from os.path import splitdrive
from StringIO import StringIO
from distutils.spawn import find_executable, spawn
-from distutils2.compat import wraps
from distutils2._backport import shutil, tarfile
from distutils2._backport.shutil import (
_make_tarball, _make_zipfile, make_archive, unpack_archive,
register_archive_format, unregister_archive_format, get_archive_formats,
register_unpack_format, unregister_unpack_format, get_unpack_formats,
Error, RegistryError)
+from distutils2._backport.misc import wraps
from distutils2.tests import unittest, support
from test.test_support import TESTFN
diff --git a/distutils2/command/build_scripts.py b/distutils2/command/build_scripts.py
index 300f692..901a679 100644
--- a/distutils2/command/build_scripts.py
+++ b/distutils2/command/build_scripts.py
@@ -7,8 +7,8 @@ from distutils2.command.cmd import Command
from distutils2.util import convert_path, newer
from distutils2 import logger
from distutils2.compat import Mixin2to3
-from distutils2.compat import detect_encoding, fsencode
from distutils2._backport import sysconfig
+from distutils2._backport.misc import detect_encoding, fsencode
# check if Python is called on the first line with this expression
diff --git a/distutils2/compat.py b/distutils2/compat.py
index 7c82142..bcd4f0f 100644
--- a/distutils2/compat.py
+++ b/distutils2/compat.py
@@ -1,13 +1,5 @@
-"""Compatibility helpers.
+"""Support for build-time 2to3 conversion."""
-This module provides individual classes or objects backported from
-Python 3.2, for internal use only. Whole modules are in _backport.
-"""
-
-import os
-import re
-import sys
-import codecs
from distutils2 import logger
@@ -57,136 +49,3 @@ class Mixin2to3(_KLASS):
def _run_2to3(self, files, doctests=[], fixers=[]):
pass
-
-
-# The rest of this file does not exist in packaging
-# functions are sorted alphabetically and are not included in __all__
-
-try:
- any
-except NameError:
- def any(seq):
- for elem in seq:
- if elem:
- return True
- return False
-
-
-_cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
-
-
-def _get_normal_name(orig_enc):
- """Imitates get_normal_name in tokenizer.c."""
- # Only care about the first 12 characters.
- enc = orig_enc[:12].lower().replace("_", "-")
- if enc == "utf-8" or enc.startswith("utf-8-"):
- return "utf-8"
- if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
- enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
- return "iso-8859-1"
- return orig_enc
-
-
-def detect_encoding(readline):
- """
- The detect_encoding() function is used to detect the encoding that should
- be used to decode a Python source file. It requires one argment, readline,
- in the same way as the tokenize() generator.
-
- It will call readline a maximum of twice, and return the encoding used
- (as a string) and a list of any lines (left as bytes) it has read in.
-
- It detects the encoding from the presence of a utf-8 bom or an encoding
- cookie as specified in pep-0263. If both a bom and a cookie are present,
- but disagree, a SyntaxError will be raised. If the encoding cookie is an
- invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
- 'utf-8-sig' is returned.
-
- If no encoding is specified, then the default of 'utf-8' will be returned.
- """
- bom_found = False
- encoding = None
- default = 'utf-8'
-
- def read_or_stop():
- try:
- return readline()
- except StopIteration:
- return ''
-
- def find_cookie(line):
- try:
- line_string = line.decode('ascii')
- except UnicodeDecodeError:
- return None
-
- matches = _cookie_re.findall(line_string)
- if not matches:
- return None
- encoding = _get_normal_name(matches[0])
- try:
- codec = codecs.lookup(encoding)
- except LookupError:
- # This behaviour mimics the Python interpreter
- raise SyntaxError("unknown encoding: " + encoding)
-
- if bom_found:
- if codec.name != 'utf-8':
- # This behaviour mimics the Python interpreter
- raise SyntaxError('encoding problem: utf-8')
- encoding += '-sig'
- return encoding
-
- first = read_or_stop()
- if first.startswith(codecs.BOM_UTF8):
- bom_found = True
- first = first[3:]
- default = 'utf-8-sig'
- if not first:
- return default, []
-
- encoding = find_cookie(first)
- if encoding:
- return encoding, [first]
-
- second = read_or_stop()
- if not second:
- return default, [first]
-
- encoding = find_cookie(second)
- if encoding:
- return encoding, [first, second]
-
- return default, [first, second]
-
-
-def fsencode(filename):
- if isinstance(filename, str):
- return filename
- elif isinstance(filename, unicode):
- return filename.encode(sys.getfilesystemencoding())
- else:
- raise TypeError("expect bytes or str, not %s" %
- type(filename).__name__)
-
-
-try:
- from functools import wraps
-except ImportError:
- def wraps(func=None):
- """No-op replacement for functools.wraps"""
- def wrapped(func):
- return func
- return wrapped
-
-try:
- from platform import python_implementation
-except ImportError:
- def python_implementation():
- if 'PyPy' in sys.version:
- return 'PyPy'
- if os.name == 'java':
- return 'Jython'
- if sys.version.startswith('IronPython'):
- return 'IronPython'
- return 'CPython'
diff --git a/distutils2/create.py b/distutils2/create.py
index d0c9477..5ad4563 100644
--- a/distutils2/create.py
+++ b/distutils2/create.py
@@ -31,13 +31,9 @@ from distutils2 import logger
# importing this with an underscore as it should be replaced by the
# dict form or another structures for all purposes
from distutils2._trove import all_classifiers as _CLASSIFIERS_LIST
-from distutils2.compat import detect_encoding
from distutils2.version import is_valid_version
from distutils2._backport import shutil, sysconfig
-try:
- any
-except NameError:
- from distutils2.compat import any
+from distutils2._backport.misc import any, detect_encoding
try:
from hashlib import md5
except ImportError:
diff --git a/distutils2/markers.py b/distutils2/markers.py
index 0281179..ac7df79 100644
--- a/distutils2/markers.py
+++ b/distutils2/markers.py
@@ -6,7 +6,7 @@ import platform
from tokenize import generate_tokens, NAME, OP, STRING, ENDMARKER
from StringIO import StringIO as BytesIO
-from distutils2.compat import python_implementation
+from distutils2._backport.misc import python_implementation
__all__ = ['interpret']
diff --git a/distutils2/pypi/simple.py b/distutils2/pypi/simple.py
index 50b2c9c..46c9d1c 100644
--- a/distutils2/pypi/simple.py
+++ b/distutils2/pypi/simple.py
@@ -16,10 +16,9 @@ import os
from fnmatch import translate
from distutils2 import logger
-from distutils2.compat import wraps
-from distutils2.metadata import Metadata
-from distutils2.version import get_version_predicate
from distutils2 import __version__ as distutils2_version
+from distutils2.version import get_version_predicate
+from distutils2.metadata import Metadata
from distutils2.pypi.base import BaseClient
from distutils2.pypi.dist import (ReleasesList, EXTENSIONS,
get_infos_from_url, MD5_HASH)
@@ -27,6 +26,7 @@ from distutils2.pypi.errors import (PackagingPyPIError, DownloadError,
UnableToDownload, CantParseArchiveName,
ReleaseNotFound, ProjectNotFound)
from distutils2.pypi.mirrors import get_mirrors
+from distutils2._backport.misc import wraps
__all__ = ['Crawler', 'DEFAULT_SIMPLE_INDEX_URL']
diff --git a/distutils2/tests/pypi_server.py b/distutils2/tests/pypi_server.py
index 0dfde1f..ad4ce14 100644
--- a/distutils2/tests/pypi_server.py
+++ b/distutils2/tests/pypi_server.py
@@ -38,7 +38,7 @@ from SimpleHTTPServer import SimpleHTTPRequestHandler
from SimpleXMLRPCServer import SimpleXMLRPCServer
from distutils2.tests import unittest
-from distutils2.compat import wraps
+from distutils2._backport.misc import wraps
PYPI_DEFAULT_STATIC_PATH = os.path.join(
diff --git a/distutils2/tests/test_markers.py b/distutils2/tests/test_markers.py
index 67e9e9b..89697d0 100644
--- a/distutils2/tests/test_markers.py
+++ b/distutils2/tests/test_markers.py
@@ -2,8 +2,8 @@
import os
import sys
import platform
-from distutils2.compat import python_implementation
from distutils2.markers import interpret
+from distutils2._backport.misc import python_implementation
from distutils2.tests import unittest
from distutils2.tests.support import LoggingCatcher