updated pyton versions and wrote hilfsbibliotheken
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
"""Extensions to the 'distutils' for large or complex distributions"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import functools
|
||||
import distutils.core
|
||||
import distutils.filelist
|
||||
from distutils.util import convert_path
|
||||
from fnmatch import fnmatchcase
|
||||
|
||||
from setuptools.extern.six import PY3
|
||||
from setuptools.extern.six.moves import filter, map
|
||||
|
||||
import setuptools.version
|
||||
@@ -15,11 +17,17 @@ from setuptools.dist import Distribution, Feature
|
||||
from setuptools.depends import Require
|
||||
from . import monkey
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
__all__ = [
|
||||
'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
|
||||
'find_packages',
|
||||
'find_packages'
|
||||
]
|
||||
|
||||
if PY3:
|
||||
__all__.append('find_namespace_packages')
|
||||
|
||||
__version__ = setuptools.version.__version__
|
||||
|
||||
bootstrap_install_from = None
|
||||
@@ -31,7 +39,7 @@ run_2to3_on_doctests = True
|
||||
lib2to3_fixer_packages = ['lib2to3.fixes']
|
||||
|
||||
|
||||
class PackageFinder(object):
|
||||
class PackageFinder:
|
||||
"""
|
||||
Generate a list of all Python packages found within a directory
|
||||
"""
|
||||
@@ -109,6 +117,9 @@ class PEP420PackageFinder(PackageFinder):
|
||||
|
||||
find_packages = PackageFinder.find
|
||||
|
||||
if PY3:
|
||||
find_namespace_packages = PEP420PackageFinder.find
|
||||
|
||||
|
||||
def _install_setup_requires(attrs):
|
||||
# Note: do not use `setuptools.Distribution` directly, as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# module pyparsing.py
|
||||
#
|
||||
# Copyright (c) 2003-2016 Paul T. McGuire
|
||||
# Copyright (c) 2003-2018 Paul T. McGuire
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
@@ -25,6 +25,7 @@
|
||||
__doc__ = \
|
||||
"""
|
||||
pyparsing module - Classes and methods to define and execute parsing grammars
|
||||
=============================================================================
|
||||
|
||||
The pyparsing module is an alternative approach to creating and executing simple grammars,
|
||||
vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you
|
||||
@@ -58,10 +59,23 @@ The pyparsing module handles some of the problems that are typically vexing when
|
||||
- extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.)
|
||||
- quoted strings
|
||||
- embedded comments
|
||||
|
||||
|
||||
Getting Started -
|
||||
-----------------
|
||||
Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing
|
||||
classes inherit from. Use the docstrings for examples of how to:
|
||||
- construct literal match expressions from L{Literal} and L{CaselessLiteral} classes
|
||||
- construct character word-group expressions using the L{Word} class
|
||||
- see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes
|
||||
- use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones
|
||||
- associate names with your parsed results using L{ParserElement.setResultsName}
|
||||
- find some helpful expression short-cuts like L{delimitedList} and L{oneOf}
|
||||
- find more useful common expressions in the L{pyparsing_common} namespace class
|
||||
"""
|
||||
|
||||
__version__ = "2.1.10"
|
||||
__versionTime__ = "07 Oct 2016 01:31 UTC"
|
||||
__version__ = "2.2.1"
|
||||
__versionTime__ = "18 Sep 2018 00:49 UTC"
|
||||
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
|
||||
|
||||
import string
|
||||
@@ -82,6 +96,15 @@ try:
|
||||
except ImportError:
|
||||
from threading import RLock
|
||||
|
||||
try:
|
||||
# Python 3
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import MutableMapping
|
||||
except ImportError:
|
||||
# Python 2.7
|
||||
from collections import Iterable
|
||||
from collections import MutableMapping
|
||||
|
||||
try:
|
||||
from collections import OrderedDict as _OrderedDict
|
||||
except ImportError:
|
||||
@@ -144,7 +167,7 @@ else:
|
||||
except UnicodeEncodeError:
|
||||
# Else encode it
|
||||
ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
|
||||
xmlcharref = Regex('&#\d+;')
|
||||
xmlcharref = Regex(r'&#\d+;')
|
||||
xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
|
||||
return xmlcharref.transformString(ret)
|
||||
|
||||
@@ -809,7 +832,7 @@ class ParseResults(object):
|
||||
return None
|
||||
|
||||
def getName(self):
|
||||
"""
|
||||
r"""
|
||||
Returns the results name for this token expression. Useful when several
|
||||
different expressions might match at a particular location.
|
||||
|
||||
@@ -940,7 +963,7 @@ class ParseResults(object):
|
||||
def __dir__(self):
|
||||
return (dir(type(self)) + list(self.keys()))
|
||||
|
||||
collections.MutableMapping.register(ParseResults)
|
||||
MutableMapping.register(ParseResults)
|
||||
|
||||
def col (loc,strg):
|
||||
"""Returns current column within a string, counting newlines as line separators.
|
||||
@@ -1025,11 +1048,11 @@ def _trim_arity(func, maxargs=2):
|
||||
# special handling for Python 3.5.0 - extra deep call stack by 1
|
||||
offset = -3 if system_version == (3,5,0) else -2
|
||||
frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
|
||||
return [(frame_summary.filename, frame_summary.lineno)]
|
||||
return [frame_summary[:2]]
|
||||
def extract_tb(tb, limit=0):
|
||||
frames = traceback.extract_tb(tb, limit=limit)
|
||||
frame_summary = frames[-1]
|
||||
return [(frame_summary.filename, frame_summary.lineno)]
|
||||
return [frame_summary[:2]]
|
||||
else:
|
||||
extract_stack = traceback.extract_stack
|
||||
extract_tb = traceback.extract_tb
|
||||
@@ -1226,7 +1249,7 @@ class ParserElement(object):
|
||||
|
||||
def setParseAction( self, *fns, **kwargs ):
|
||||
"""
|
||||
Define action to perform when successfully matching parse element definition.
|
||||
Define one or more actions to perform when successfully matching parse element definition.
|
||||
Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
|
||||
C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
|
||||
- s = the original string being parsed (see note below)
|
||||
@@ -1264,7 +1287,7 @@ class ParserElement(object):
|
||||
|
||||
def addParseAction( self, *fns, **kwargs ):
|
||||
"""
|
||||
Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
|
||||
Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
|
||||
|
||||
See examples in L{I{copy}<copy>}.
|
||||
"""
|
||||
@@ -1374,7 +1397,7 @@ class ParserElement(object):
|
||||
else:
|
||||
preloc = loc
|
||||
tokensStart = preloc
|
||||
if self.mayIndexError or loc >= len(instring):
|
||||
if self.mayIndexError or preloc >= len(instring):
|
||||
try:
|
||||
loc,tokens = self.parseImpl( instring, preloc, doActions )
|
||||
except IndexError:
|
||||
@@ -1408,7 +1431,6 @@ class ParserElement(object):
|
||||
self.resultsName,
|
||||
asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
|
||||
modal=self.modalResults )
|
||||
|
||||
if debugging:
|
||||
#~ print ("Matched",self,"->",retTokens.asList())
|
||||
if (self.debugActions[1] ):
|
||||
@@ -1443,10 +1465,14 @@ class ParserElement(object):
|
||||
|
||||
def clear(self):
|
||||
cache.clear()
|
||||
|
||||
def cache_len(self):
|
||||
return len(cache)
|
||||
|
||||
self.get = types.MethodType(get, self)
|
||||
self.set = types.MethodType(set, self)
|
||||
self.clear = types.MethodType(clear, self)
|
||||
self.__len__ = types.MethodType(cache_len, self)
|
||||
|
||||
if _OrderedDict is not None:
|
||||
class _FifoCache(object):
|
||||
@@ -1460,15 +1486,22 @@ class ParserElement(object):
|
||||
|
||||
def set(self, key, value):
|
||||
cache[key] = value
|
||||
if len(cache) > size:
|
||||
cache.popitem(False)
|
||||
while len(cache) > size:
|
||||
try:
|
||||
cache.popitem(False)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def clear(self):
|
||||
cache.clear()
|
||||
|
||||
def cache_len(self):
|
||||
return len(cache)
|
||||
|
||||
self.get = types.MethodType(get, self)
|
||||
self.set = types.MethodType(set, self)
|
||||
self.clear = types.MethodType(clear, self)
|
||||
self.__len__ = types.MethodType(cache_len, self)
|
||||
|
||||
else:
|
||||
class _FifoCache(object):
|
||||
@@ -1483,7 +1516,7 @@ class ParserElement(object):
|
||||
|
||||
def set(self, key, value):
|
||||
cache[key] = value
|
||||
if len(cache) > size:
|
||||
while len(key_fifo) > size:
|
||||
cache.pop(key_fifo.popleft(), None)
|
||||
key_fifo.append(key)
|
||||
|
||||
@@ -1491,9 +1524,13 @@ class ParserElement(object):
|
||||
cache.clear()
|
||||
key_fifo.clear()
|
||||
|
||||
def cache_len(self):
|
||||
return len(cache)
|
||||
|
||||
self.get = types.MethodType(get, self)
|
||||
self.set = types.MethodType(set, self)
|
||||
self.clear = types.MethodType(clear, self)
|
||||
self.__len__ = types.MethodType(cache_len, self)
|
||||
|
||||
# argument cache for optimizing repeated calls when backtracking through recursive expressions
|
||||
packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
|
||||
@@ -1743,8 +1780,12 @@ class ParserElement(object):
|
||||
cap_word = Word(alphas.upper(), alphas.lower())
|
||||
|
||||
print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
|
||||
|
||||
# the sum() builtin can be used to merge results into a single ParseResults object
|
||||
print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")))
|
||||
prints::
|
||||
['More', 'Iron', 'Lead', 'Gold', 'I']
|
||||
[['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']]
|
||||
['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity']
|
||||
"""
|
||||
try:
|
||||
return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
|
||||
@@ -1819,7 +1860,7 @@ class ParserElement(object):
|
||||
warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
|
||||
SyntaxWarning, stacklevel=2)
|
||||
return None
|
||||
return And( [ self, And._ErrorStop(), other ] )
|
||||
return self + And._ErrorStop() + other
|
||||
|
||||
def __rsub__(self, other ):
|
||||
"""
|
||||
@@ -2722,7 +2763,7 @@ class Word(Token):
|
||||
|
||||
|
||||
class Regex(Token):
|
||||
"""
|
||||
r"""
|
||||
Token for matching strings that match a given regular expression.
|
||||
Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
|
||||
If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as
|
||||
@@ -2911,7 +2952,7 @@ class QuotedString(Token):
|
||||
|
||||
# replace escaped characters
|
||||
if self.escChar:
|
||||
ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
|
||||
ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret)
|
||||
|
||||
# replace escaped quotes
|
||||
if self.escQuote:
|
||||
@@ -3223,7 +3264,7 @@ class ParseExpression(ParserElement):
|
||||
|
||||
if isinstance( exprs, basestring ):
|
||||
self.exprs = [ ParserElement._literalStringClass( exprs ) ]
|
||||
elif isinstance( exprs, collections.Iterable ):
|
||||
elif isinstance( exprs, Iterable ):
|
||||
exprs = list(exprs)
|
||||
# if sequence of strings provided, wrap with Literal
|
||||
if all(isinstance(expr, basestring) for expr in exprs):
|
||||
@@ -4374,7 +4415,7 @@ def traceParseAction(f):
|
||||
|
||||
@traceParseAction
|
||||
def remove_duplicate_chars(tokens):
|
||||
return ''.join(sorted(set(''.join(tokens)))
|
||||
return ''.join(sorted(set(''.join(tokens))))
|
||||
|
||||
wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
|
||||
print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
|
||||
@@ -4564,7 +4605,7 @@ def oneOf( strs, caseless=False, useRegex=True ):
|
||||
symbols = []
|
||||
if isinstance(strs,basestring):
|
||||
symbols = strs.split()
|
||||
elif isinstance(strs, collections.Iterable):
|
||||
elif isinstance(strs, Iterable):
|
||||
symbols = list(strs)
|
||||
else:
|
||||
warnings.warn("Invalid argument to oneOf, expected string or iterable",
|
||||
@@ -4715,7 +4756,7 @@ stringEnd = StringEnd().setName("stringEnd")
|
||||
_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
|
||||
_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
|
||||
_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
|
||||
_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE)
|
||||
_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1)
|
||||
_charRange = Group(_singleChar + Suppress("-") + _singleChar)
|
||||
_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
|
||||
|
||||
@@ -5020,7 +5061,9 @@ def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
|
||||
constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}.
|
||||
- parseAction is the parse action to be associated with
|
||||
expressions matching this operator expression (the
|
||||
parse action tuple member may be omitted)
|
||||
parse action tuple member may be omitted); if the parse action
|
||||
is passed a tuple or list of functions, this is equivalent to
|
||||
calling C{setParseAction(*fn)} (L{ParserElement.setParseAction})
|
||||
- lpar - expression for matching left-parentheses (default=C{Suppress('(')})
|
||||
- rpar - expression for matching right-parentheses (default=C{Suppress(')')})
|
||||
|
||||
@@ -5093,7 +5136,10 @@ def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
|
||||
else:
|
||||
raise ValueError("operator must indicate right or left associativity")
|
||||
if pa:
|
||||
matchExpr.setParseAction( pa )
|
||||
if isinstance(pa, (tuple, list)):
|
||||
matchExpr.setParseAction(*pa)
|
||||
else:
|
||||
matchExpr.setParseAction(pa)
|
||||
thisExpr <<= ( matchExpr.setName(termName) | lastExpr )
|
||||
lastExpr = thisExpr
|
||||
ret <<= lastExpr
|
||||
|
||||
@@ -61,6 +61,19 @@ class Distribution(setuptools.dist.Distribution):
|
||||
distutils.core.Distribution = orig
|
||||
|
||||
|
||||
def _to_str(s):
|
||||
"""
|
||||
Convert a filename to a string (on Python 2, explicitly
|
||||
a byte string, not Unicode) as distutils checks for the
|
||||
exact type str.
|
||||
"""
|
||||
if sys.version_info[0] == 2 and not isinstance(s, str):
|
||||
# Assume it's Unicode, as that's what the PEP says
|
||||
# should be provided.
|
||||
return s.encode(sys.getfilesystemencoding())
|
||||
return s
|
||||
|
||||
|
||||
def _run_setup(setup_script='setup.py'):
|
||||
# Note that we can reuse our build directory between calls
|
||||
# Correctness comes first, then optimization later
|
||||
@@ -78,9 +91,8 @@ def _fix_config(config_settings):
|
||||
return config_settings
|
||||
|
||||
|
||||
def _get_build_requires(config_settings):
|
||||
def _get_build_requires(config_settings, requirements):
|
||||
config_settings = _fix_config(config_settings)
|
||||
requirements = ['setuptools', 'wheel']
|
||||
|
||||
sys.argv = sys.argv[:1] + ['egg_info'] + \
|
||||
config_settings["--global-option"]
|
||||
@@ -100,20 +112,20 @@ def _get_immediate_subdirectories(a_dir):
|
||||
|
||||
def get_requires_for_build_wheel(config_settings=None):
|
||||
config_settings = _fix_config(config_settings)
|
||||
return _get_build_requires(config_settings)
|
||||
return _get_build_requires(config_settings, requirements=['setuptools', 'wheel'])
|
||||
|
||||
|
||||
def get_requires_for_build_sdist(config_settings=None):
|
||||
config_settings = _fix_config(config_settings)
|
||||
return _get_build_requires(config_settings)
|
||||
return _get_build_requires(config_settings, requirements=['setuptools'])
|
||||
|
||||
|
||||
def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
|
||||
sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', metadata_directory]
|
||||
sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', _to_str(metadata_directory)]
|
||||
_run_setup()
|
||||
|
||||
|
||||
dist_info_directory = metadata_directory
|
||||
while True:
|
||||
while True:
|
||||
dist_infos = [f for f in os.listdir(dist_info_directory)
|
||||
if f.endswith('.dist-info')]
|
||||
|
||||
@@ -159,11 +171,9 @@ def build_sdist(sdist_directory, config_settings=None):
|
||||
config_settings = _fix_config(config_settings)
|
||||
sdist_directory = os.path.abspath(sdist_directory)
|
||||
sys.argv = sys.argv[:1] + ['sdist'] + \
|
||||
config_settings["--global-option"]
|
||||
config_settings["--global-option"] + \
|
||||
["--dist-dir", sdist_directory]
|
||||
_run_setup()
|
||||
if sdist_directory != 'dist':
|
||||
shutil.rmtree(sdist_directory)
|
||||
shutil.copytree('dist', sdist_directory)
|
||||
|
||||
sdists = [f for f in os.listdir(sdist_directory)
|
||||
if f.endswith('.tar.gz')]
|
||||
|
||||
@@ -411,7 +411,7 @@ def scan_module(egg_dir, base, name, stubs):
|
||||
return True # Extension module
|
||||
pkg = base[len(egg_dir) + 1:].replace(os.sep, '.')
|
||||
module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0]
|
||||
if sys.version_info < (3, 3):
|
||||
if six.PY2:
|
||||
skip = 8 # skip magic & date
|
||||
elif sys.version_info < (3, 7):
|
||||
skip = 12 # skip magic & date & file size
|
||||
|
||||
@@ -112,7 +112,7 @@ class build_ext(_build_ext):
|
||||
and get_abi3_suffix()
|
||||
)
|
||||
if use_abi3:
|
||||
so_ext = _get_config_var_837('EXT_SUFFIX')
|
||||
so_ext = get_config_var('EXT_SUFFIX')
|
||||
filename = filename[:-len(so_ext)]
|
||||
filename = filename + get_abi3_suffix()
|
||||
if isinstance(ext, Library):
|
||||
@@ -319,13 +319,3 @@ else:
|
||||
self.create_static_lib(
|
||||
objects, basename, output_dir, debug, target_lang
|
||||
)
|
||||
|
||||
|
||||
def _get_config_var_837(name):
|
||||
"""
|
||||
In https://github.com/pypa/setuptools/pull/837, we discovered
|
||||
Python 3.3.0 exposes the extension suffix under the name 'SO'.
|
||||
"""
|
||||
if sys.version_info < (3, 3, 1):
|
||||
name = 'SO'
|
||||
return get_config_var(name)
|
||||
|
||||
@@ -12,6 +12,8 @@ from setuptools.command.easy_install import easy_install
|
||||
from setuptools import namespaces
|
||||
import setuptools
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
class develop(namespaces.DevelopInstaller, easy_install):
|
||||
"""Set up package for development"""
|
||||
@@ -192,7 +194,7 @@ class develop(namespaces.DevelopInstaller, easy_install):
|
||||
return easy_install.install_wrapper_scripts(self, dist)
|
||||
|
||||
|
||||
class VersionlessRequirement(object):
|
||||
class VersionlessRequirement:
|
||||
"""
|
||||
Adapt a pkg_resources.Distribution to simply return the project
|
||||
name as the 'requirement' so that scripts will work across
|
||||
|
||||
@@ -40,12 +40,13 @@ import subprocess
|
||||
import shlex
|
||||
import io
|
||||
|
||||
from sysconfig import get_config_vars, get_path
|
||||
|
||||
from setuptools.extern import six
|
||||
from setuptools.extern.six.moves import configparser, map
|
||||
|
||||
from setuptools import Command
|
||||
from setuptools.sandbox import run_setup
|
||||
from setuptools.py31compat import get_path, get_config_vars
|
||||
from setuptools.py27compat import rmtree_safe
|
||||
from setuptools.command import setopt
|
||||
from setuptools.archive_util import unpack_archive
|
||||
@@ -62,6 +63,8 @@ from pkg_resources import (
|
||||
)
|
||||
import pkg_resources.py31compat
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
# Turn on PEP440Warnings
|
||||
warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
|
||||
|
||||
@@ -93,7 +96,7 @@ def samefile(p1, p2):
|
||||
|
||||
if six.PY2:
|
||||
|
||||
def _to_ascii(s):
|
||||
def _to_bytes(s):
|
||||
return s
|
||||
|
||||
def isascii(s):
|
||||
@@ -104,8 +107,8 @@ if six.PY2:
|
||||
return False
|
||||
else:
|
||||
|
||||
def _to_ascii(s):
|
||||
return s.encode('ascii')
|
||||
def _to_bytes(s):
|
||||
return s.encode('utf8')
|
||||
|
||||
def isascii(s):
|
||||
try:
|
||||
@@ -319,7 +322,7 @@ class easy_install(Command):
|
||||
self.all_site_dirs.append(normalize_path(d))
|
||||
if not self.editable:
|
||||
self.check_site_dir()
|
||||
self.index_url = self.index_url or "https://pypi.python.org/simple"
|
||||
self.index_url = self.index_url or "https://pypi.org/simple/"
|
||||
self.shadow_path = self.all_site_dirs[:]
|
||||
for path_item in self.install_dir, normalize_path(self.script_dir):
|
||||
if path_item not in self.shadow_path:
|
||||
@@ -629,7 +632,7 @@ class easy_install(Command):
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _tmpdir(self):
|
||||
tmpdir = tempfile.mkdtemp(prefix=six.u("easy_install-"))
|
||||
tmpdir = tempfile.mkdtemp(prefix=u"easy_install-")
|
||||
try:
|
||||
# cast to str as workaround for #709 and #710 and #712
|
||||
yield str(tmpdir)
|
||||
@@ -802,7 +805,7 @@ class easy_install(Command):
|
||||
if is_script:
|
||||
body = 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_bytes(script_text), 'b')
|
||||
|
||||
@staticmethod
|
||||
def _load_template(dev_path):
|
||||
@@ -2049,7 +2052,7 @@ class WindowsCommandSpec(CommandSpec):
|
||||
split_args = dict(posix=False)
|
||||
|
||||
|
||||
class ScriptWriter(object):
|
||||
class ScriptWriter:
|
||||
"""
|
||||
Encapsulates behavior around writing entry point scripts for console and
|
||||
gui apps.
|
||||
@@ -2082,12 +2085,10 @@ class ScriptWriter(object):
|
||||
@classmethod
|
||||
def get_script_header(cls, script_text, executable=None, wininst=False):
|
||||
# for backward compatibility
|
||||
warnings.warn("Use get_header", DeprecationWarning)
|
||||
warnings.warn("Use get_header", DeprecationWarning, stacklevel=2)
|
||||
if wininst:
|
||||
executable = "python.exe"
|
||||
cmd = cls.command_spec_class.best().from_param(executable)
|
||||
cmd.install_options(script_text)
|
||||
return cmd.as_header()
|
||||
return cls.get_header(script_text, executable)
|
||||
|
||||
@classmethod
|
||||
def get_args(cls, dist, header=None):
|
||||
|
||||
@@ -116,7 +116,33 @@ def translate_pattern(glob):
|
||||
return re.compile(pat, flags=re.MULTILINE|re.DOTALL)
|
||||
|
||||
|
||||
class egg_info(Command):
|
||||
class InfoCommon:
|
||||
tag_build = None
|
||||
tag_date = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return safe_name(self.distribution.get_name())
|
||||
|
||||
def tagged_version(self):
|
||||
version = self.distribution.get_version()
|
||||
# egg_info may be called more than once for a distribution,
|
||||
# in which case the version string already contains all tags.
|
||||
if self.vtags and version.endswith(self.vtags):
|
||||
return safe_version(version)
|
||||
return safe_version(version + self.vtags)
|
||||
|
||||
def tags(self):
|
||||
version = ''
|
||||
if self.tag_build:
|
||||
version += self.tag_build
|
||||
if self.tag_date:
|
||||
version += time.strftime("-%Y%m%d")
|
||||
return version
|
||||
vtags = property(tags)
|
||||
|
||||
|
||||
class egg_info(InfoCommon, Command):
|
||||
description = "create a distribution's .egg-info directory"
|
||||
|
||||
user_options = [
|
||||
@@ -133,14 +159,11 @@ class egg_info(Command):
|
||||
}
|
||||
|
||||
def initialize_options(self):
|
||||
self.egg_name = None
|
||||
self.egg_version = None
|
||||
self.egg_base = None
|
||||
self.egg_name = None
|
||||
self.egg_info = None
|
||||
self.tag_build = None
|
||||
self.tag_date = 0
|
||||
self.egg_version = None
|
||||
self.broken_egg_info = False
|
||||
self.vtags = None
|
||||
|
||||
####################################
|
||||
# allow the 'tag_svn_revision' to be detected and
|
||||
@@ -168,10 +191,12 @@ class egg_info(Command):
|
||||
edit_config(filename, dict(egg_info=egg_info))
|
||||
|
||||
def finalize_options(self):
|
||||
self.egg_name = safe_name(self.distribution.get_name())
|
||||
self.vtags = self.tags()
|
||||
# Note: we need to capture the current value returned
|
||||
# by `self.tagged_version()`, so we can later update
|
||||
# `self.distribution.metadata.version` without
|
||||
# repercussions.
|
||||
self.egg_name = self.name
|
||||
self.egg_version = self.tagged_version()
|
||||
|
||||
parsed_version = parse_version(self.egg_version)
|
||||
|
||||
try:
|
||||
@@ -254,16 +279,9 @@ class egg_info(Command):
|
||||
if not self.dry_run:
|
||||
os.unlink(filename)
|
||||
|
||||
def tagged_version(self):
|
||||
version = self.distribution.get_version()
|
||||
# egg_info may be called more than once for a distribution,
|
||||
# in which case the version string already contains all tags.
|
||||
if self.vtags and version.endswith(self.vtags):
|
||||
return safe_version(version)
|
||||
return safe_version(version + self.vtags)
|
||||
|
||||
def run(self):
|
||||
self.mkpath(self.egg_info)
|
||||
os.utime(self.egg_info, None)
|
||||
installer = self.distribution.fetch_build_egg
|
||||
for ep in iter_entry_points('egg_info.writers'):
|
||||
ep.require(installer=installer)
|
||||
@@ -277,14 +295,6 @@ class egg_info(Command):
|
||||
|
||||
self.find_sources()
|
||||
|
||||
def tags(self):
|
||||
version = ''
|
||||
if self.tag_build:
|
||||
version += self.tag_build
|
||||
if self.tag_date:
|
||||
version += time.strftime("-%Y%m%d")
|
||||
return version
|
||||
|
||||
def find_sources(self):
|
||||
"""Generate SOURCES.txt manifest file"""
|
||||
manifest_filename = os.path.join(self.egg_info, "SOURCES.txt")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from distutils import log
|
||||
import distutils.command.register as orig
|
||||
|
||||
|
||||
@@ -5,6 +6,13 @@ class register(orig.register):
|
||||
__doc__ = orig.register.__doc__
|
||||
|
||||
def run(self):
|
||||
# Make sure that we are using valid current name/version info
|
||||
self.run_command('egg_info')
|
||||
orig.register.run(self)
|
||||
try:
|
||||
# Make sure that we are using valid current name/version info
|
||||
self.run_command('egg_info')
|
||||
orig.register.run(self)
|
||||
finally:
|
||||
self.announce(
|
||||
"WARNING: Registering is deprecated, use twine to "
|
||||
"upload instead (https://pypi.org/p/twine/)",
|
||||
log.WARN
|
||||
)
|
||||
|
||||
@@ -16,6 +16,8 @@ from pkg_resources import (resource_listdir, resource_exists, normalize_path,
|
||||
add_activation_listener, require, EntryPoint)
|
||||
from setuptools import Command
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
class ScanningLoader(TestLoader):
|
||||
|
||||
@@ -58,7 +60,7 @@ class ScanningLoader(TestLoader):
|
||||
|
||||
|
||||
# adapted from jaraco.classes.properties:NonDataProperty
|
||||
class NonDataProperty(object):
|
||||
class NonDataProperty:
|
||||
def __init__(self, fget):
|
||||
self.fget = fget
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import getpass
|
||||
from distutils import log
|
||||
from distutils.command import upload as orig
|
||||
|
||||
|
||||
@@ -8,6 +9,16 @@ class upload(orig.upload):
|
||||
in a variety of different ways.
|
||||
"""
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
orig.upload.run(self)
|
||||
finally:
|
||||
self.announce(
|
||||
"WARNING: Uploading via this command is deprecated, use twine "
|
||||
"to upload instead (https://pypi.org/p/twine/)",
|
||||
log.WARN
|
||||
)
|
||||
|
||||
def finalize_options(self):
|
||||
orig.upload.finalize_options(self)
|
||||
self.username = (
|
||||
|
||||
@@ -7,7 +7,11 @@ from functools import partial
|
||||
from importlib import import_module
|
||||
|
||||
from distutils.errors import DistutilsOptionError, DistutilsFileError
|
||||
from setuptools.extern.six import string_types
|
||||
from setuptools.extern.packaging.version import LegacyVersion, parse
|
||||
from setuptools.extern.six import string_types, PY3
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
def read_configuration(
|
||||
@@ -101,18 +105,18 @@ def parse_configuration(
|
||||
If False exceptions are propagated as expected.
|
||||
:rtype: list
|
||||
"""
|
||||
meta = ConfigMetadataHandler(
|
||||
distribution.metadata, command_options, ignore_option_errors)
|
||||
meta.parse()
|
||||
|
||||
options = ConfigOptionsHandler(
|
||||
distribution, command_options, ignore_option_errors)
|
||||
options.parse()
|
||||
|
||||
meta = ConfigMetadataHandler(
|
||||
distribution.metadata, command_options, ignore_option_errors, distribution.package_dir)
|
||||
meta.parse()
|
||||
|
||||
return meta, options
|
||||
|
||||
|
||||
class ConfigHandler(object):
|
||||
class ConfigHandler:
|
||||
"""Handles metadata supplied in configuration files."""
|
||||
|
||||
section_prefix = None
|
||||
@@ -280,7 +284,7 @@ class ConfigHandler(object):
|
||||
return f.read()
|
||||
|
||||
@classmethod
|
||||
def _parse_attr(cls, value):
|
||||
def _parse_attr(cls, value, package_dir=None):
|
||||
"""Represents value as a module attribute.
|
||||
|
||||
Examples:
|
||||
@@ -300,7 +304,21 @@ class ConfigHandler(object):
|
||||
module_name = '.'.join(attrs_path)
|
||||
module_name = module_name or '__init__'
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
parent_path = os.getcwd()
|
||||
if package_dir:
|
||||
if attrs_path[0] in package_dir:
|
||||
# A custom path was specified for the module we want to import
|
||||
custom_path = package_dir[attrs_path[0]]
|
||||
parts = custom_path.rsplit('/', 1)
|
||||
if len(parts) > 1:
|
||||
parent_path = os.path.join(os.getcwd(), parts[0])
|
||||
module_name = parts[1]
|
||||
else:
|
||||
module_name = custom_path
|
||||
elif '' in package_dir:
|
||||
# A custom parent directory was specified for all root modules
|
||||
parent_path = os.path.join(os.getcwd(), package_dir[''])
|
||||
sys.path.insert(0, parent_path)
|
||||
try:
|
||||
module = import_module(module_name)
|
||||
value = getattr(module, attr_name)
|
||||
@@ -399,6 +417,12 @@ class ConfigMetadataHandler(ConfigHandler):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, target_obj, options, ignore_option_errors=False,
|
||||
package_dir=None):
|
||||
super(ConfigMetadataHandler, self).__init__(target_obj, options,
|
||||
ignore_option_errors)
|
||||
self.package_dir = package_dir
|
||||
|
||||
@property
|
||||
def parsers(self):
|
||||
"""Metadata item name to parser function mapping."""
|
||||
@@ -427,7 +451,19 @@ class ConfigMetadataHandler(ConfigHandler):
|
||||
:rtype: str
|
||||
|
||||
"""
|
||||
version = self._parse_attr(value)
|
||||
version = self._parse_file(value)
|
||||
|
||||
if version != value:
|
||||
version = version.strip()
|
||||
# Be strict about versions loaded from file because it's easy to
|
||||
# accidentally include newlines and other unintended content
|
||||
if isinstance(parse(version), LegacyVersion):
|
||||
raise DistutilsOptionError('Version loaded from %s does not comply with PEP 440: %s' % (
|
||||
value, version
|
||||
))
|
||||
return version
|
||||
|
||||
version = self._parse_attr(value, self.package_dir)
|
||||
|
||||
if callable(version):
|
||||
version = version()
|
||||
@@ -479,16 +515,24 @@ class ConfigOptionsHandler(ConfigHandler):
|
||||
:param value:
|
||||
:rtype: list
|
||||
"""
|
||||
find_directive = 'find:'
|
||||
find_directives = ['find:', 'find_namespace:']
|
||||
trimmed_value = value.strip()
|
||||
|
||||
if not value.startswith(find_directive):
|
||||
if not trimmed_value in find_directives:
|
||||
return self._parse_list(value)
|
||||
|
||||
findns = trimmed_value == find_directives[1]
|
||||
if findns and not PY3:
|
||||
raise DistutilsOptionError('find_namespace: directive is unsupported on Python < 3.3')
|
||||
|
||||
# Read function arguments from a dedicated section.
|
||||
find_kwargs = self.parse_section_packages__find(
|
||||
self.sections.get('packages.find', {}))
|
||||
|
||||
from setuptools import find_packages
|
||||
if findns:
|
||||
from setuptools import find_namespace_packages as find_packages
|
||||
else:
|
||||
from setuptools import find_packages
|
||||
|
||||
return find_packages(**find_kwargs)
|
||||
|
||||
@@ -554,3 +598,11 @@ class ConfigOptionsHandler(ConfigHandler):
|
||||
parse_list = partial(self._parse_list, separator=';')
|
||||
self['extras_require'] = self._parse_section_to_dict(
|
||||
section_options, parse_list)
|
||||
|
||||
def parse_section_data_files(self, section_options):
|
||||
"""Parses `data_files` configuration file section.
|
||||
|
||||
:param dict section_options:
|
||||
"""
|
||||
parsed = self._parse_section_to_dict(section_options, self._parse_list)
|
||||
self['data_files'] = [(k, v) for k, v in parsed.items()]
|
||||
|
||||
@@ -123,15 +123,6 @@ def write_pkg_file(self, file):
|
||||
file.write('Provides-Extra: %s\n' % extra)
|
||||
|
||||
|
||||
# from Python 3.4
|
||||
def write_pkg_info(self, base_dir):
|
||||
"""Write the PKG-INFO file into the release tree.
|
||||
"""
|
||||
with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
|
||||
encoding='UTF-8') as pkg_info:
|
||||
self.write_pkg_file(pkg_info)
|
||||
|
||||
|
||||
sequence = tuple, list
|
||||
|
||||
|
||||
@@ -337,6 +328,12 @@ class Distribution(Distribution_parse_config_files, _Distribution):
|
||||
distribution for the included and excluded features.
|
||||
"""
|
||||
|
||||
_DISTUTILS_UNSUPPORTED_METADATA = {
|
||||
'long_description_content_type': None,
|
||||
'project_urls': dict,
|
||||
'provides_extras': set,
|
||||
}
|
||||
|
||||
_patched_dist = None
|
||||
|
||||
def patch_missing_pkg_info(self, attrs):
|
||||
@@ -362,25 +359,29 @@ class Distribution(Distribution_parse_config_files, _Distribution):
|
||||
self.require_features = []
|
||||
self.features = {}
|
||||
self.dist_files = []
|
||||
# Filter-out setuptools' specific options.
|
||||
self.src_root = attrs.pop("src_root", None)
|
||||
self.patch_missing_pkg_info(attrs)
|
||||
self.project_urls = attrs.get('project_urls', {})
|
||||
self.dependency_links = attrs.pop('dependency_links', [])
|
||||
self.setup_requires = attrs.pop('setup_requires', [])
|
||||
for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
|
||||
vars(self).setdefault(ep.name, None)
|
||||
_Distribution.__init__(self, attrs)
|
||||
_Distribution.__init__(self, {
|
||||
k: v for k, v in attrs.items()
|
||||
if k not in self._DISTUTILS_UNSUPPORTED_METADATA
|
||||
})
|
||||
|
||||
# The project_urls attribute may not be supported in distutils, so
|
||||
# prime it here from our value if not automatically set
|
||||
self.metadata.project_urls = getattr(
|
||||
self.metadata, 'project_urls', self.project_urls)
|
||||
self.metadata.long_description_content_type = attrs.get(
|
||||
'long_description_content_type'
|
||||
)
|
||||
self.metadata.provides_extras = getattr(
|
||||
self.metadata, 'provides_extras', set()
|
||||
)
|
||||
# Fill-in missing metadata fields not supported by distutils.
|
||||
# Note some fields may have been set by other tools (e.g. pbr)
|
||||
# above; they are taken preferrentially to setup() arguments
|
||||
for option, default in self._DISTUTILS_UNSUPPORTED_METADATA.items():
|
||||
for source in self.metadata.__dict__, attrs:
|
||||
if option in source:
|
||||
value = source[option]
|
||||
break
|
||||
else:
|
||||
value = default() if default else None
|
||||
setattr(self.metadata, option, value)
|
||||
|
||||
if isinstance(self.metadata.version, numbers.Number):
|
||||
# Some people apparently take "version number" too literally :)
|
||||
|
||||
@@ -48,7 +48,7 @@ class VendorImporter:
|
||||
# on later Python versions to cause relative imports
|
||||
# in the vendor package to resolve the same modules
|
||||
# as those going through this importer.
|
||||
if sys.version_info > (3, 3):
|
||||
if sys.version_info >= (3, ):
|
||||
del sys.modules[extant]
|
||||
return mod
|
||||
except ImportError:
|
||||
|
||||
@@ -3,14 +3,12 @@ Filename globbing utility. Mostly a copy of `glob` from Python 3.5.
|
||||
|
||||
Changes include:
|
||||
* `yield from` and PEP3102 `*` removed.
|
||||
* `bytes` changed to `six.binary_type`.
|
||||
* Hidden files are not ignored.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import fnmatch
|
||||
from setuptools.extern.six import binary_type
|
||||
|
||||
__all__ = ["glob", "iglob", "escape"]
|
||||
|
||||
@@ -92,7 +90,7 @@ def _iglob(pathname, recursive):
|
||||
|
||||
def glob1(dirname, pattern):
|
||||
if not dirname:
|
||||
if isinstance(pattern, binary_type):
|
||||
if isinstance(pattern, bytes):
|
||||
dirname = os.curdir.encode('ASCII')
|
||||
else:
|
||||
dirname = os.curdir
|
||||
@@ -129,8 +127,8 @@ def glob2(dirname, pattern):
|
||||
# Recursively yields relative pathnames inside a literal directory.
|
||||
def _rlistdir(dirname):
|
||||
if not dirname:
|
||||
if isinstance(dirname, binary_type):
|
||||
dirname = binary_type(os.curdir, 'ASCII')
|
||||
if isinstance(dirname, bytes):
|
||||
dirname = os.curdir.encode('ASCII')
|
||||
else:
|
||||
dirname = os.curdir
|
||||
try:
|
||||
@@ -149,7 +147,7 @@ magic_check_bytes = re.compile(b'([*?[])')
|
||||
|
||||
|
||||
def has_magic(s):
|
||||
if isinstance(s, binary_type):
|
||||
if isinstance(s, bytes):
|
||||
match = magic_check_bytes.search(s)
|
||||
else:
|
||||
match = magic_check.search(s)
|
||||
@@ -157,7 +155,7 @@ def has_magic(s):
|
||||
|
||||
|
||||
def _isrecursive(pattern):
|
||||
if isinstance(pattern, binary_type):
|
||||
if isinstance(pattern, bytes):
|
||||
return pattern == b'**'
|
||||
else:
|
||||
return pattern == '**'
|
||||
@@ -169,7 +167,7 @@ def escape(pathname):
|
||||
# Escaping is done by wrapping any of "*?[" between square brackets.
|
||||
# Metacharacters do not work in the drive part and shouldn't be escaped.
|
||||
drive, pathname = os.path.splitdrive(pathname)
|
||||
if isinstance(pathname, binary_type):
|
||||
if isinstance(pathname, bytes):
|
||||
pathname = magic_check_bytes.sub(br'[\1]', pathname)
|
||||
else:
|
||||
pathname = magic_check.sub(r'[\1]', pathname)
|
||||
|
||||
@@ -75,8 +75,6 @@ def patch_all():
|
||||
needs_warehouse = (
|
||||
sys.version_info < (2, 7, 13)
|
||||
or
|
||||
(3, 0) < sys.version_info < (3, 3, 7)
|
||||
or
|
||||
(3, 4) < sys.version_info < (3, 4, 6)
|
||||
or
|
||||
(3, 5) < sys.version_info <= (3, 5, 3)
|
||||
@@ -87,7 +85,6 @@ def patch_all():
|
||||
distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse
|
||||
|
||||
_patch_distribution_metadata_write_pkg_file()
|
||||
_patch_distribution_metadata_write_pkg_info()
|
||||
|
||||
# Install Distribution throughout the distutils
|
||||
for module in distutils.dist, distutils.core, distutils.cmd:
|
||||
@@ -111,21 +108,6 @@ def _patch_distribution_metadata_write_pkg_file():
|
||||
)
|
||||
|
||||
|
||||
def _patch_distribution_metadata_write_pkg_info():
|
||||
"""
|
||||
Workaround issue #197 - Python 3 prior to 3.2.2 uses an environment-local
|
||||
encoding to save the pkg_info. Monkey-patch its write_pkg_info method to
|
||||
correct this undesirable behavior.
|
||||
"""
|
||||
environment_local = (3,) <= sys.version_info[:3] < (3, 2, 2)
|
||||
if not environment_local:
|
||||
return
|
||||
|
||||
distutils.dist.DistributionMetadata.write_pkg_info = (
|
||||
setuptools.dist.write_pkg_info
|
||||
)
|
||||
|
||||
|
||||
def patch_func(replacement, target_mod, func_name):
|
||||
"""
|
||||
Patch func_name in target_mod with replacement
|
||||
|
||||
@@ -232,8 +232,7 @@ def _augment_exception(exc, version, arch=''):
|
||||
elif version >= 14.0:
|
||||
# For VC++ 14.0 Redirect user to Visual C++ Build Tools
|
||||
message += (' Get it with "Microsoft Visual C++ Build Tools": '
|
||||
r'http://landinghub.visualstudio.com/'
|
||||
'visual-cpp-build-tools')
|
||||
r'https://visualstudio.microsoft.com/downloads/')
|
||||
|
||||
exc.args = (message, )
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import socket
|
||||
import base64
|
||||
import hashlib
|
||||
import itertools
|
||||
import warnings
|
||||
from functools import wraps
|
||||
|
||||
from setuptools.extern import six
|
||||
@@ -26,12 +27,13 @@ from setuptools.py27compat import get_all_headers
|
||||
from setuptools.py33compat import unescape
|
||||
from setuptools.wheel import Wheel
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
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
|
||||
HREF = re.compile(r"""href\s*=\s*['"]?([^'"> ]+)""", re.I)
|
||||
PYPI_MD5 = re.compile(
|
||||
'<a href="([^"#]+)">([^<]+)</a>\n\\s+\\(<a (?:title="MD5 hash"\n\\s+)'
|
||||
'href="[^?]+\\?:action=show_md5&digest=([0-9a-f]{32})">md5</a>\\)'
|
||||
r'<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)'
|
||||
r'href="[^?]+\?:action=show_md5&digest=([0-9a-f]{32})">md5</a>\)'
|
||||
)
|
||||
URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match
|
||||
EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split()
|
||||
@@ -235,7 +237,7 @@ def find_external_links(url, page):
|
||||
yield urllib.parse.urljoin(url, htmldecode(match.group(1)))
|
||||
|
||||
|
||||
class ContentChecker(object):
|
||||
class ContentChecker:
|
||||
"""
|
||||
A null content checker that defines the interface for checking content
|
||||
"""
|
||||
@@ -297,7 +299,7 @@ class PackageIndex(Environment):
|
||||
"""A distribution index that scans web pages for download URLs"""
|
||||
|
||||
def __init__(
|
||||
self, index_url="https://pypi.python.org/simple", hosts=('*',),
|
||||
self, index_url="https://pypi.org/simple/", hosts=('*',),
|
||||
ca_bundle=None, verify_ssl=True, *args, **kw
|
||||
):
|
||||
Environment.__init__(self, *args, **kw)
|
||||
@@ -847,6 +849,7 @@ class PackageIndex(Environment):
|
||||
raise DistutilsError("Unexpected HTML page found at " + url)
|
||||
|
||||
def _download_svn(self, url, filename):
|
||||
warnings.warn("SVN download support is deprecated", UserWarning)
|
||||
url = url.split('#', 1)[0] # remove any fragment for svn's sake
|
||||
creds = ''
|
||||
if url.lower().startswith('svn:') and '@' in url:
|
||||
@@ -933,12 +936,19 @@ entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub
|
||||
|
||||
|
||||
def decode_entity(match):
|
||||
what = match.group(1)
|
||||
what = match.group(0)
|
||||
return unescape(what)
|
||||
|
||||
|
||||
def htmldecode(text):
|
||||
"""Decode HTML entities in the given text."""
|
||||
"""
|
||||
Decode HTML entities in the given text.
|
||||
|
||||
>>> htmldecode(
|
||||
... 'https://../package_name-0.1.2.tar.gz'
|
||||
... '?tokena=A&tokenb=B">package_name-0.1.2.tar.gz')
|
||||
'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz'
|
||||
"""
|
||||
return entity_sub(decode_entity, text)
|
||||
|
||||
|
||||
@@ -972,15 +982,14 @@ def _encode_auth(auth):
|
||||
auth_s = urllib.parse.unquote(auth)
|
||||
# convert to bytes
|
||||
auth_bytes = auth_s.encode()
|
||||
# use the legacy interface for Python 2.3 support
|
||||
encoded_bytes = base64.encodestring(auth_bytes)
|
||||
encoded_bytes = base64.b64encode(auth_bytes)
|
||||
# convert back to a string
|
||||
encoded = encoded_bytes.decode()
|
||||
# strip the trailing carriage return
|
||||
return encoded.replace('\n', '')
|
||||
|
||||
|
||||
class Credential(object):
|
||||
class Credential:
|
||||
"""
|
||||
A username/password pair. Use like a namedtuple.
|
||||
"""
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import distutils.util
|
||||
from distutils import log
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
@@ -11,6 +12,8 @@ import sysconfig
|
||||
import warnings
|
||||
from collections import OrderedDict
|
||||
|
||||
from .extern import six
|
||||
|
||||
from . import glibc
|
||||
|
||||
_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)')
|
||||
@@ -69,8 +72,8 @@ def get_flag(var, fallback, expected=True, warn=True):
|
||||
val = get_config_var(var)
|
||||
if val is None:
|
||||
if warn:
|
||||
warnings.warn("Config variable '{0}' is unset, Python ABI tag may "
|
||||
"be incorrect".format(var), RuntimeWarning, 2)
|
||||
log.debug("Config variable '%s' is unset, Python ABI tag may "
|
||||
"be incorrect", var)
|
||||
return fallback()
|
||||
return val == expected
|
||||
|
||||
@@ -96,8 +99,8 @@ def get_abi_tag():
|
||||
lambda: sys.maxunicode == 0x10ffff,
|
||||
expected=4,
|
||||
warn=(impl == 'cp' and
|
||||
sys.version_info < (3, 3))) \
|
||||
and sys.version_info < (3, 3):
|
||||
six.PY2)) \
|
||||
and six.PY2:
|
||||
u = 'u'
|
||||
abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u)
|
||||
elif soabi and soabi.startswith('cpython-'):
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
__all__ = ['get_config_vars', 'get_path']
|
||||
__all__ = []
|
||||
|
||||
try:
|
||||
# Python 2.7 or >=3.2
|
||||
from sysconfig import get_config_vars, get_path
|
||||
except ImportError:
|
||||
from distutils.sysconfig import get_config_vars, get_python_lib
|
||||
|
||||
def get_path(name):
|
||||
if name not in ('platlib', 'purelib'):
|
||||
raise ValueError("Name must be purelib or platlib")
|
||||
return get_python_lib(name == 'platlib')
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
try:
|
||||
@@ -19,7 +10,7 @@ except ImportError:
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
class TemporaryDirectory(object):
|
||||
class TemporaryDirectory:
|
||||
"""
|
||||
Very simple temporary directory context manager.
|
||||
Will try to delete afterward, but will also ignore OS and similar
|
||||
|
||||
@@ -10,11 +10,12 @@ except ImportError:
|
||||
from setuptools.extern import six
|
||||
from setuptools.extern.six.moves import html_parser
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
OpArg = collections.namedtuple('OpArg', 'opcode arg')
|
||||
|
||||
|
||||
class Bytecode_compat(object):
|
||||
class Bytecode_compat:
|
||||
def __init__(self, code):
|
||||
self.code = code
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
__requires__ = %(spec)r
|
||||
__import__('pkg_resources').require(%(spec)r)
|
||||
__file__ = %(dev_path)r
|
||||
exec(compile(open(__file__).read(), __file__, 'exec'))
|
||||
with open(__file__) as f:
|
||||
exec(compile(f.read(), __file__, 'exec'))
|
||||
|
||||
@@ -23,7 +23,7 @@ def __boot():
|
||||
break
|
||||
else:
|
||||
try:
|
||||
import imp # Avoid import loop in Python >= 3.3
|
||||
import imp # Avoid import loop in Python 3
|
||||
stream, path, descr = imp.find_module('site', [item])
|
||||
except ImportError:
|
||||
continue
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
'''Wheels support.'''
|
||||
"""Wheels support."""
|
||||
|
||||
from distutils.util import get_platform
|
||||
import email
|
||||
import itertools
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import zipfile
|
||||
|
||||
from pkg_resources import Distribution, PathMetadata, parse_version
|
||||
from setuptools.extern.packaging.utils import canonicalize_name
|
||||
from setuptools.extern.six import PY3
|
||||
from setuptools import Distribution as SetuptoolsDistribution
|
||||
from setuptools import pep425tags
|
||||
from setuptools.command.egg_info import write_requirements
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
WHEEL_NAME = re.compile(
|
||||
r"""^(?P<project_name>.+?)-(?P<version>\d.*?)
|
||||
((-(?P<build>\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)
|
||||
)\.whl$""",
|
||||
re.VERBOSE).match
|
||||
re.VERBOSE).match
|
||||
|
||||
NAMESPACE_PACKAGE_INIT = '''\
|
||||
try:
|
||||
@@ -50,7 +55,7 @@ def unpack(src_dir, dst_dir):
|
||||
os.rmdir(dirpath)
|
||||
|
||||
|
||||
class Wheel(object):
|
||||
class Wheel:
|
||||
|
||||
def __init__(self, filename):
|
||||
match = WHEEL_NAME(os.path.basename(filename))
|
||||
@@ -62,9 +67,11 @@ class Wheel(object):
|
||||
|
||||
def tags(self):
|
||||
'''List tags (py_version, abi, platform) supported by this wheel.'''
|
||||
return itertools.product(self.py_version.split('.'),
|
||||
self.abi.split('.'),
|
||||
self.platform.split('.'))
|
||||
return itertools.product(
|
||||
self.py_version.split('.'),
|
||||
self.abi.split('.'),
|
||||
self.platform.split('.'),
|
||||
)
|
||||
|
||||
def is_compatible(self):
|
||||
'''Is the wheel is compatible with the current platform?'''
|
||||
@@ -77,87 +84,127 @@ class Wheel(object):
|
||||
platform=(None if self.platform == 'any' else get_platform()),
|
||||
).egg_name() + '.egg'
|
||||
|
||||
def get_dist_info(self, zf):
|
||||
# find the correct name of the .dist-info dir in the wheel file
|
||||
for member in zf.namelist():
|
||||
dirname = posixpath.dirname(member)
|
||||
if (dirname.endswith('.dist-info') and
|
||||
canonicalize_name(dirname).startswith(
|
||||
canonicalize_name(self.project_name))):
|
||||
return dirname
|
||||
raise ValueError("unsupported wheel format. .dist-info not found")
|
||||
|
||||
def install_as_egg(self, destination_eggdir):
|
||||
'''Install wheel as an egg directory.'''
|
||||
with zipfile.ZipFile(self.filename) as zf:
|
||||
dist_basename = '%s-%s' % (self.project_name, self.version)
|
||||
dist_info = '%s.dist-info' % dist_basename
|
||||
dist_data = '%s.data' % dist_basename
|
||||
def get_metadata(name):
|
||||
with zf.open('%s/%s' % (dist_info, name)) as fp:
|
||||
value = fp.read().decode('utf-8') if PY3 else fp.read()
|
||||
return email.parser.Parser().parsestr(value)
|
||||
wheel_metadata = get_metadata('WHEEL')
|
||||
dist_metadata = get_metadata('METADATA')
|
||||
# Check wheel format version is supported.
|
||||
wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
|
||||
if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):
|
||||
raise ValueError('unsupported wheel format version: %s' % wheel_version)
|
||||
# Extract to target directory.
|
||||
os.mkdir(destination_eggdir)
|
||||
zf.extractall(destination_eggdir)
|
||||
# Convert metadata.
|
||||
dist_info = os.path.join(destination_eggdir, dist_info)
|
||||
dist = Distribution.from_location(
|
||||
destination_eggdir, dist_info,
|
||||
metadata=PathMetadata(destination_eggdir, dist_info)
|
||||
self._install_as_egg(destination_eggdir, zf)
|
||||
|
||||
def _install_as_egg(self, destination_eggdir, zf):
|
||||
dist_basename = '%s-%s' % (self.project_name, self.version)
|
||||
dist_info = self.get_dist_info(zf)
|
||||
dist_data = '%s.data' % dist_basename
|
||||
egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
|
||||
|
||||
self._convert_metadata(zf, destination_eggdir, dist_info, egg_info)
|
||||
self._move_data_entries(destination_eggdir, dist_data)
|
||||
self._fix_namespace_packages(egg_info, destination_eggdir)
|
||||
|
||||
@staticmethod
|
||||
def _convert_metadata(zf, destination_eggdir, dist_info, egg_info):
|
||||
def get_metadata(name):
|
||||
with zf.open(posixpath.join(dist_info, name)) as fp:
|
||||
value = fp.read().decode('utf-8') if PY3 else fp.read()
|
||||
return email.parser.Parser().parsestr(value)
|
||||
|
||||
wheel_metadata = get_metadata('WHEEL')
|
||||
# Check wheel format version is supported.
|
||||
wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
|
||||
wheel_v1 = (
|
||||
parse_version('1.0') <= wheel_version < parse_version('2.0dev0')
|
||||
)
|
||||
if not wheel_v1:
|
||||
raise ValueError(
|
||||
'unsupported wheel format version: %s' % wheel_version)
|
||||
# Extract to target directory.
|
||||
os.mkdir(destination_eggdir)
|
||||
zf.extractall(destination_eggdir)
|
||||
# Convert metadata.
|
||||
dist_info = os.path.join(destination_eggdir, dist_info)
|
||||
dist = Distribution.from_location(
|
||||
destination_eggdir, dist_info,
|
||||
metadata=PathMetadata(destination_eggdir, dist_info),
|
||||
)
|
||||
|
||||
# Note: Evaluate and strip markers now,
|
||||
# as it's difficult to convert back from the syntax:
|
||||
# foobar; "linux" in sys_platform and extra == 'test'
|
||||
def raw_req(req):
|
||||
req.marker = None
|
||||
return str(req)
|
||||
install_requires = list(sorted(map(raw_req, dist.requires())))
|
||||
extras_require = {
|
||||
extra: sorted(
|
||||
req
|
||||
for req in map(raw_req, dist.requires((extra,)))
|
||||
if req not in install_requires
|
||||
)
|
||||
# Note: we need to evaluate and strip markers now,
|
||||
# as we can't easily convert back from the syntax:
|
||||
# foobar; "linux" in sys_platform and extra == 'test'
|
||||
def raw_req(req):
|
||||
req.marker = None
|
||||
return str(req)
|
||||
install_requires = list(sorted(map(raw_req, dist.requires())))
|
||||
extras_require = {
|
||||
extra: list(sorted(
|
||||
req
|
||||
for req in map(raw_req, dist.requires((extra,)))
|
||||
if req not in install_requires
|
||||
))
|
||||
for extra in dist.extras
|
||||
}
|
||||
egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
|
||||
os.rename(dist_info, egg_info)
|
||||
os.rename(os.path.join(egg_info, 'METADATA'),
|
||||
os.path.join(egg_info, 'PKG-INFO'))
|
||||
setup_dist = SetuptoolsDistribution(attrs=dict(
|
||||
for extra in dist.extras
|
||||
}
|
||||
os.rename(dist_info, egg_info)
|
||||
os.rename(
|
||||
os.path.join(egg_info, 'METADATA'),
|
||||
os.path.join(egg_info, 'PKG-INFO'),
|
||||
)
|
||||
setup_dist = SetuptoolsDistribution(
|
||||
attrs=dict(
|
||||
install_requires=install_requires,
|
||||
extras_require=extras_require,
|
||||
))
|
||||
write_requirements(setup_dist.get_command_obj('egg_info'),
|
||||
None, os.path.join(egg_info, 'requires.txt'))
|
||||
# Move data entries to their correct location.
|
||||
dist_data = os.path.join(destination_eggdir, dist_data)
|
||||
dist_data_scripts = os.path.join(dist_data, 'scripts')
|
||||
if os.path.exists(dist_data_scripts):
|
||||
egg_info_scripts = os.path.join(destination_eggdir,
|
||||
'EGG-INFO', 'scripts')
|
||||
os.mkdir(egg_info_scripts)
|
||||
for entry in os.listdir(dist_data_scripts):
|
||||
# Remove bytecode, as it's not properly handled
|
||||
# during easy_install scripts install phase.
|
||||
if entry.endswith('.pyc'):
|
||||
os.unlink(os.path.join(dist_data_scripts, entry))
|
||||
else:
|
||||
os.rename(os.path.join(dist_data_scripts, entry),
|
||||
os.path.join(egg_info_scripts, entry))
|
||||
os.rmdir(dist_data_scripts)
|
||||
for subdir in filter(os.path.exists, (
|
||||
os.path.join(dist_data, d)
|
||||
for d in ('data', 'headers', 'purelib', 'platlib')
|
||||
)):
|
||||
unpack(subdir, destination_eggdir)
|
||||
if os.path.exists(dist_data):
|
||||
os.rmdir(dist_data)
|
||||
# Fix namespace packages.
|
||||
namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')
|
||||
if os.path.exists(namespace_packages):
|
||||
with open(namespace_packages) as fp:
|
||||
namespace_packages = fp.read().split()
|
||||
for mod in namespace_packages:
|
||||
mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
|
||||
mod_init = os.path.join(mod_dir, '__init__.py')
|
||||
if os.path.exists(mod_dir) and not os.path.exists(mod_init):
|
||||
with open(mod_init, 'w') as fp:
|
||||
fp.write(NAMESPACE_PACKAGE_INIT)
|
||||
),
|
||||
)
|
||||
write_requirements(
|
||||
setup_dist.get_command_obj('egg_info'),
|
||||
None,
|
||||
os.path.join(egg_info, 'requires.txt'),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _move_data_entries(destination_eggdir, dist_data):
|
||||
"""Move data entries to their correct location."""
|
||||
dist_data = os.path.join(destination_eggdir, dist_data)
|
||||
dist_data_scripts = os.path.join(dist_data, 'scripts')
|
||||
if os.path.exists(dist_data_scripts):
|
||||
egg_info_scripts = os.path.join(
|
||||
destination_eggdir, 'EGG-INFO', 'scripts')
|
||||
os.mkdir(egg_info_scripts)
|
||||
for entry in os.listdir(dist_data_scripts):
|
||||
# Remove bytecode, as it's not properly handled
|
||||
# during easy_install scripts install phase.
|
||||
if entry.endswith('.pyc'):
|
||||
os.unlink(os.path.join(dist_data_scripts, entry))
|
||||
else:
|
||||
os.rename(
|
||||
os.path.join(dist_data_scripts, entry),
|
||||
os.path.join(egg_info_scripts, entry),
|
||||
)
|
||||
os.rmdir(dist_data_scripts)
|
||||
for subdir in filter(os.path.exists, (
|
||||
os.path.join(dist_data, d)
|
||||
for d in ('data', 'headers', 'purelib', 'platlib')
|
||||
)):
|
||||
unpack(subdir, destination_eggdir)
|
||||
if os.path.exists(dist_data):
|
||||
os.rmdir(dist_data)
|
||||
|
||||
@staticmethod
|
||||
def _fix_namespace_packages(egg_info, destination_eggdir):
|
||||
namespace_packages = os.path.join(
|
||||
egg_info, 'namespace_packages.txt')
|
||||
if os.path.exists(namespace_packages):
|
||||
with open(namespace_packages) as fp:
|
||||
namespace_packages = fp.read().split()
|
||||
for mod in namespace_packages:
|
||||
mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
|
||||
mod_init = os.path.join(mod_dir, '__init__.py')
|
||||
if os.path.exists(mod_dir) and not os.path.exists(mod_init):
|
||||
with open(mod_init, 'w') as fp:
|
||||
fp.write(NAMESPACE_PACKAGE_INIT)
|
||||
|
||||
Reference in New Issue
Block a user