[pypy-commit] pypy numpypy-problems: merge default into branch
mattip
noreply at buildbot.pypy.org
Thu Sep 27 01:16:18 CEST 2012
Author: mattip <matti.picus at gmail.com>
Branch: numpypy-problems
Changeset: r57620:e684b5c23259
Date: 2012-09-26 23:25 +0200
http://bitbucket.org/pypy/pypy/changeset/e684b5c23259/
Log: merge default into branch use default's implementation of
StringType, but add tests that require coerce
diff too long, truncating to 2000 out of 49429 lines
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -1,5 +1,6 @@
syntax: glob
*.py[co]
+*.sw[po]
*~
.*.swp
.idea
diff --git a/lib-python/2.7/BaseHTTPServer.py b/lib-python/2.7/BaseHTTPServer.py
--- a/lib-python/2.7/BaseHTTPServer.py
+++ b/lib-python/2.7/BaseHTTPServer.py
@@ -244,14 +244,11 @@
self.request_version = version = self.default_request_version
self.close_connection = 1
requestline = self.raw_requestline
- if requestline[-2:] == '\r\n':
- requestline = requestline[:-2]
- elif requestline[-1:] == '\n':
- requestline = requestline[:-1]
+ requestline = requestline.rstrip('\r\n')
self.requestline = requestline
words = requestline.split()
if len(words) == 3:
- [command, path, version] = words
+ command, path, version = words
if version[:5] != 'HTTP/':
self.send_error(400, "Bad request version (%r)" % version)
return False
@@ -277,7 +274,7 @@
"Invalid HTTP Version (%s)" % base_version_number)
return False
elif len(words) == 2:
- [command, path] = words
+ command, path = words
self.close_connection = 1
if command != 'GET':
self.send_error(400,
diff --git a/lib-python/2.7/ConfigParser.py b/lib-python/2.7/ConfigParser.py
--- a/lib-python/2.7/ConfigParser.py
+++ b/lib-python/2.7/ConfigParser.py
@@ -142,6 +142,7 @@
def __init__(self, section):
Error.__init__(self, 'No section: %r' % (section,))
self.section = section
+ self.args = (section, )
class DuplicateSectionError(Error):
"""Raised when a section is multiply-created."""
@@ -149,6 +150,7 @@
def __init__(self, section):
Error.__init__(self, "Section %r already exists" % section)
self.section = section
+ self.args = (section, )
class NoOptionError(Error):
"""A requested option was not found."""
@@ -158,6 +160,7 @@
(option, section))
self.option = option
self.section = section
+ self.args = (option, section)
class InterpolationError(Error):
"""Base class for interpolation-related exceptions."""
@@ -166,6 +169,7 @@
Error.__init__(self, msg)
self.option = option
self.section = section
+ self.args = (option, section, msg)
class InterpolationMissingOptionError(InterpolationError):
"""A string substitution required a setting which was not available."""
@@ -179,6 +183,7 @@
% (section, option, reference, rawval))
InterpolationError.__init__(self, option, section, msg)
self.reference = reference
+ self.args = (option, section, rawval, reference)
class InterpolationSyntaxError(InterpolationError):
"""Raised when the source text into which substitutions are made
@@ -194,6 +199,7 @@
"\trawval : %s\n"
% (section, option, rawval))
InterpolationError.__init__(self, option, section, msg)
+ self.args = (option, section, rawval)
class ParsingError(Error):
"""Raised when a configuration file does not follow legal syntax."""
@@ -202,6 +208,7 @@
Error.__init__(self, 'File contains parsing errors: %s' % filename)
self.filename = filename
self.errors = []
+ self.args = (filename, )
def append(self, lineno, line):
self.errors.append((lineno, line))
@@ -218,6 +225,7 @@
self.filename = filename
self.lineno = lineno
self.line = line
+ self.args = (filename, lineno, line)
class RawConfigParser:
@@ -570,7 +578,7 @@
def keys(self):
result = []
seen = set()
- for mapping in self_maps:
+ for mapping in self._maps:
for key in mapping:
if key not in seen:
result.append(key)
diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py
--- a/lib-python/2.7/HTMLParser.py
+++ b/lib-python/2.7/HTMLParser.py
@@ -14,7 +14,6 @@
# Regular expressions used for parsing
interesting_normal = re.compile('[&<]')
-interesting_cdata = re.compile(r'<(/|\Z)')
incomplete = re.compile('&[a-zA-Z#]')
entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
@@ -24,25 +23,31 @@
piclose = re.compile('>')
commentclose = re.compile(r'--\s*>')
tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*')
+# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state
+# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state
+tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*')
+
attrfind = re.compile(
- r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*'
- r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?')
+ r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*'
+ r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*')
locatestarttagend = re.compile(r"""
<[a-zA-Z][-.a-zA-Z0-9:_]* # tag name
- (?:\s+ # whitespace before attribute name
- (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name
- (?:\s*=\s* # value indicator
+ (?:[\s/]* # optional whitespace before attribute name
+ (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name
+ (?:\s*=+\s* # value indicator
(?:'[^']*' # LITA-enclosed value
- |\"[^\"]*\" # LIT-enclosed value
- |[^'\">\s]+ # bare value
+ |"[^"]*" # LIT-enclosed value
+ |(?!['"])[^>\s]* # bare value
)
- )?
- )
- )*
+ )?(?:\s|/(?!>))*
+ )*
+ )?
\s* # trailing whitespace
""", re.VERBOSE)
endendtag = re.compile('>')
+# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between
+# </ and the tag name, so maybe this should be fixed
endtagfind = re.compile('</\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\s*>')
@@ -96,6 +101,7 @@
self.rawdata = ''
self.lasttag = '???'
self.interesting = interesting_normal
+ self.cdata_elem = None
markupbase.ParserBase.reset(self)
def feed(self, data):
@@ -120,11 +126,13 @@
"""Return full source of start tag: '<...>'."""
return self.__starttag_text
- def set_cdata_mode(self):
- self.interesting = interesting_cdata
+ def set_cdata_mode(self, elem):
+ self.cdata_elem = elem.lower()
+ self.interesting = re.compile(r'</\s*%s\s*>' % self.cdata_elem, re.I)
def clear_cdata_mode(self):
self.interesting = interesting_normal
+ self.cdata_elem = None
# Internal -- handle data as far as reasonable. May leave state
# and data to be processed by a subsequent call. If 'end' is
@@ -138,6 +146,8 @@
if match:
j = match.start()
else:
+ if self.cdata_elem:
+ break
j = n
if i < j: self.handle_data(rawdata[i:j])
i = self.updatepos(i, j)
@@ -153,16 +163,23 @@
elif startswith("<?", i):
k = self.parse_pi(i)
elif startswith("<!", i):
- k = self.parse_declaration(i)
+ k = self.parse_html_declaration(i)
elif (i + 1) < n:
self.handle_data("<")
k = i + 1
else:
break
if k < 0:
- if end:
- self.error("EOF in middle of construct")
- break
+ if not end:
+ break
+ k = rawdata.find('>', i + 1)
+ if k < 0:
+ k = rawdata.find('<', i + 1)
+ if k < 0:
+ k = i + 1
+ else:
+ k += 1
+ self.handle_data(rawdata[i:k])
i = self.updatepos(i, k)
elif startswith("&#", i):
match = charref.match(rawdata, i)
@@ -206,11 +223,46 @@
else:
assert 0, "interesting.search() lied"
# end while
- if end and i < n:
+ if end and i < n and not self.cdata_elem:
self.handle_data(rawdata[i:n])
i = self.updatepos(i, n)
self.rawdata = rawdata[i:]
+ # Internal -- parse html declarations, return length or -1 if not terminated
+ # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state
+ # See also parse_declaration in _markupbase
+ def parse_html_declaration(self, i):
+ rawdata = self.rawdata
+ if rawdata[i:i+2] != '<!':
+ self.error('unexpected call to parse_html_declaration()')
+ if rawdata[i:i+4] == '<!--':
+ # this case is actually already handled in goahead()
+ return self.parse_comment(i)
+ elif rawdata[i:i+3] == '<![':
+ return self.parse_marked_section(i)
+ elif rawdata[i:i+9].lower() == '<!doctype':
+ # find the closing >
+ gtpos = rawdata.find('>', i+9)
+ if gtpos == -1:
+ return -1
+ self.handle_decl(rawdata[i+2:gtpos])
+ return gtpos+1
+ else:
+ return self.parse_bogus_comment(i)
+
+ # Internal -- parse bogus comment, return length or -1 if not terminated
+ # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state
+ def parse_bogus_comment(self, i, report=1):
+ rawdata = self.rawdata
+ if rawdata[i:i+2] not in ('<!', '</'):
+ self.error('unexpected call to parse_comment()')
+ pos = rawdata.find('>', i+2)
+ if pos == -1:
+ return -1
+ if report:
+ self.handle_comment(rawdata[i+2:pos])
+ return pos + 1
+
# Internal -- parse processing instr, return end or -1 if not terminated
def parse_pi(self, i):
rawdata = self.rawdata
@@ -249,6 +301,7 @@
elif attrvalue[:1] == '\'' == attrvalue[-1:] or \
attrvalue[:1] == '"' == attrvalue[-1:]:
attrvalue = attrvalue[1:-1]
+ if attrvalue:
attrvalue = self.unescape(attrvalue)
attrs.append((attrname.lower(), attrvalue))
k = m.end()
@@ -262,15 +315,15 @@
- self.__starttag_text.rfind("\n")
else:
offset = offset + len(self.__starttag_text)
- self.error("junk characters in start tag: %r"
- % (rawdata[k:endpos][:20],))
+ self.handle_data(rawdata[i:endpos])
+ return endpos
if end.endswith('/>'):
# XHTML-style empty tag: <span attr="value" />
self.handle_startendtag(tag, attrs)
else:
self.handle_starttag(tag, attrs)
if tag in self.CDATA_CONTENT_ELEMENTS:
- self.set_cdata_mode()
+ self.set_cdata_mode(tag)
return endpos
# Internal -- check to see if we have a complete starttag; return end
@@ -300,8 +353,10 @@
# end of input in or before attribute value, or we have the
# '/' from a '/>' ending
return -1
- self.updatepos(i, j)
- self.error("malformed start tag")
+ if j > i:
+ return j
+ else:
+ return i + 1
raise AssertionError("we should not get here!")
# Internal -- parse endtag, return end or -1 if incomplete
@@ -311,14 +366,38 @@
match = endendtag.search(rawdata, i+1) # >
if not match:
return -1
- j = match.end()
+ gtpos = match.end()
match = endtagfind.match(rawdata, i) # </ + tag + >
if not match:
- self.error("bad end tag: %r" % (rawdata[i:j],))
- tag = match.group(1)
- self.handle_endtag(tag.lower())
+ if self.cdata_elem is not None:
+ self.handle_data(rawdata[i:gtpos])
+ return gtpos
+ # find the name: w3.org/TR/html5/tokenization.html#tag-name-state
+ namematch = tagfind_tolerant.match(rawdata, i+2)
+ if not namematch:
+ # w3.org/TR/html5/tokenization.html#end-tag-open-state
+ if rawdata[i:i+3] == '</>':
+ return i+3
+ else:
+ return self.parse_bogus_comment(i)
+ tagname = namematch.group().lower()
+ # consume and ignore other stuff between the name and the >
+ # Note: this is not 100% correct, since we might have things like
+ # </tag attr=">">, but looking for > after tha name should cover
+ # most of the cases and is much simpler
+ gtpos = rawdata.find('>', namematch.end())
+ self.handle_endtag(tagname)
+ return gtpos+1
+
+ elem = match.group(1).lower() # script or style
+ if self.cdata_elem is not None:
+ if elem != self.cdata_elem:
+ self.handle_data(rawdata[i:gtpos])
+ return gtpos
+
+ self.handle_endtag(elem)
self.clear_cdata_mode()
- return j
+ return gtpos
# Overridable -- finish processing of start+end tag: <tag.../>
def handle_startendtag(self, tag, attrs):
@@ -358,7 +437,7 @@
pass
def unknown_decl(self, data):
- self.error("unknown declaration: %r" % (data,))
+ pass
# Internal -- helper to remove special character quoting
entitydefs = None
diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py
--- a/lib-python/2.7/SocketServer.py
+++ b/lib-python/2.7/SocketServer.py
@@ -82,7 +82,7 @@
data is stored externally (e.g. in the file system), a synchronous
class will essentially render the service "deaf" while one request is
being handled -- which may be for a very long time if a client is slow
-to reqd all the data it has requested. Here a threading or forking
+to read all the data it has requested. Here a threading or forking
server is appropriate.
In some cases, it may be appropriate to process part of a request
@@ -589,8 +589,7 @@
"""Start a new thread to process the request."""
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
- if self.daemon_threads:
- t.setDaemon (1)
+ t.daemon = self.daemon_threads
t.start()
diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py
--- a/lib-python/2.7/_pyio.py
+++ b/lib-python/2.7/_pyio.py
@@ -8,6 +8,7 @@
import abc
import codecs
import warnings
+import errno
# Import thread instead of threading to reduce startup cost
try:
from thread import allocate_lock as Lock
@@ -720,8 +721,11 @@
def close(self):
if self.raw is not None and not self.closed:
- self.flush()
- self.raw.close()
+ try:
+ # may raise BlockingIOError or BrokenPipeError etc
+ self.flush()
+ finally:
+ self.raw.close()
def detach(self):
if self.raw is None:
@@ -1074,13 +1078,9 @@
# XXX we can implement some more tricks to try and avoid
# partial writes
if len(self._write_buf) > self.buffer_size:
- # We're full, so let's pre-flush the buffer
- try:
- self._flush_unlocked()
- except BlockingIOError as e:
- # We can't accept anything else.
- # XXX Why not just let the exception pass through?
- raise BlockingIOError(e.errno, e.strerror, 0)
+ # We're full, so let's pre-flush the buffer. (This may
+ # raise BlockingIOError with characters_written == 0.)
+ self._flush_unlocked()
before = len(self._write_buf)
self._write_buf.extend(b)
written = len(self._write_buf) - before
@@ -1111,24 +1111,23 @@
def _flush_unlocked(self):
if self.closed:
raise ValueError("flush of closed file")
- written = 0
- try:
- while self._write_buf:
- try:
- n = self.raw.write(self._write_buf)
- except IOError as e:
- if e.errno != EINTR:
- raise
- continue
- if n > len(self._write_buf) or n < 0:
- raise IOError("write() returned incorrect number of bytes")
- del self._write_buf[:n]
- written += n
- except BlockingIOError as e:
- n = e.characters_written
+ while self._write_buf:
+ try:
+ n = self.raw.write(self._write_buf)
+ except BlockingIOError:
+ raise RuntimeError("self.raw should implement RawIOBase: it "
+ "should not raise BlockingIOError")
+ except IOError as e:
+ if e.errno != EINTR:
+ raise
+ continue
+ if n is None:
+ raise BlockingIOError(
+ errno.EAGAIN,
+ "write could not complete without blocking", 0)
+ if n > len(self._write_buf) or n < 0:
+ raise IOError("write() returned incorrect number of bytes")
del self._write_buf[:n]
- written += n
- raise BlockingIOError(e.errno, e.strerror, written)
def tell(self):
return _BufferedIOMixin.tell(self) + len(self._write_buf)
diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py
--- a/lib-python/2.7/aifc.py
+++ b/lib-python/2.7/aifc.py
@@ -162,6 +162,12 @@
except struct.error:
raise EOFError
+def _read_ushort(file):
+ try:
+ return struct.unpack('>H', file.read(2))[0]
+ except struct.error:
+ raise EOFError
+
def _read_string(file):
length = ord(file.read(1))
if length == 0:
@@ -194,13 +200,19 @@
def _write_short(f, x):
f.write(struct.pack('>h', x))
+def _write_ushort(f, x):
+ f.write(struct.pack('>H', x))
+
def _write_long(f, x):
+ f.write(struct.pack('>l', x))
+
+def _write_ulong(f, x):
f.write(struct.pack('>L', x))
def _write_string(f, s):
if len(s) > 255:
raise ValueError("string exceeds maximum pstring length")
- f.write(chr(len(s)))
+ f.write(struct.pack('B', len(s)))
f.write(s)
if len(s) & 1 == 0:
f.write(chr(0))
@@ -218,7 +230,7 @@
lomant = 0
else:
fmant, expon = math.frexp(x)
- if expon > 16384 or fmant >= 1: # Infinity or NaN
+ if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN
expon = sign|0x7FFF
himant = 0
lomant = 0
@@ -234,9 +246,9 @@
fmant = math.ldexp(fmant - fsmant, 32)
fsmant = math.floor(fmant)
lomant = long(fsmant)
- _write_short(f, expon)
- _write_long(f, himant)
- _write_long(f, lomant)
+ _write_ushort(f, expon)
+ _write_ulong(f, himant)
+ _write_ulong(f, lomant)
from chunk import Chunk
@@ -840,15 +852,15 @@
if self._aifc:
self._file.write('AIFC')
self._file.write('FVER')
- _write_long(self._file, 4)
- _write_long(self._file, self._version)
+ _write_ulong(self._file, 4)
+ _write_ulong(self._file, self._version)
else:
self._file.write('AIFF')
self._file.write('COMM')
- _write_long(self._file, commlength)
+ _write_ulong(self._file, commlength)
_write_short(self._file, self._nchannels)
self._nframes_pos = self._file.tell()
- _write_long(self._file, self._nframes)
+ _write_ulong(self._file, self._nframes)
_write_short(self._file, self._sampwidth * 8)
_write_float(self._file, self._framerate)
if self._aifc:
@@ -856,9 +868,9 @@
_write_string(self._file, self._compname)
self._file.write('SSND')
self._ssnd_length_pos = self._file.tell()
- _write_long(self._file, self._datalength + 8)
- _write_long(self._file, 0)
- _write_long(self._file, 0)
+ _write_ulong(self._file, self._datalength + 8)
+ _write_ulong(self._file, 0)
+ _write_ulong(self._file, 0)
def _write_form_length(self, datalength):
if self._aifc:
@@ -869,8 +881,8 @@
else:
commlength = 18
verslength = 0
- _write_long(self._file, 4 + verslength + self._marklength + \
- 8 + commlength + 16 + datalength)
+ _write_ulong(self._file, 4 + verslength + self._marklength + \
+ 8 + commlength + 16 + datalength)
return commlength
def _patchheader(self):
@@ -888,9 +900,9 @@
self._file.seek(self._form_length_pos, 0)
dummy = self._write_form_length(datalength)
self._file.seek(self._nframes_pos, 0)
- _write_long(self._file, self._nframeswritten)
+ _write_ulong(self._file, self._nframeswritten)
self._file.seek(self._ssnd_length_pos, 0)
- _write_long(self._file, datalength + 8)
+ _write_ulong(self._file, datalength + 8)
self._file.seek(curpos, 0)
self._nframes = self._nframeswritten
self._datalength = datalength
@@ -905,13 +917,13 @@
length = length + len(name) + 1 + 6
if len(name) & 1 == 0:
length = length + 1
- _write_long(self._file, length)
+ _write_ulong(self._file, length)
self._marklength = length + 8
_write_short(self._file, len(self._markers))
for marker in self._markers:
id, pos, name = marker
_write_short(self._file, id)
- _write_long(self._file, pos)
+ _write_ulong(self._file, pos)
_write_string(self._file, name)
def open(f, mode=None):
diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py
--- a/lib-python/2.7/asyncore.py
+++ b/lib-python/2.7/asyncore.py
@@ -132,7 +132,8 @@
is_w = obj.writable()
if is_r:
r.append(fd)
- if is_w:
+ # accepting sockets should not be writable
+ if is_w and not obj.accepting:
w.append(fd)
if is_r or is_w:
e.append(fd)
@@ -179,7 +180,8 @@
flags = 0
if obj.readable():
flags |= select.POLLIN | select.POLLPRI
- if obj.writable():
+ # accepting sockets should not be writable
+ if obj.writable() and not obj.accepting:
flags |= select.POLLOUT
if flags:
# Only check for exceptions if object was either readable
diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py
--- a/lib-python/2.7/cgi.py
+++ b/lib-python/2.7/cgi.py
@@ -293,7 +293,7 @@
while s[:1] == ';':
s = s[1:]
end = s.find(';')
- while end > 0 and s.count('"', 0, end) % 2:
+ while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
end = s.find(';', end + 1)
if end < 0:
end = len(s)
diff --git a/lib-python/2.7/cmd.py b/lib-python/2.7/cmd.py
--- a/lib-python/2.7/cmd.py
+++ b/lib-python/2.7/cmd.py
@@ -209,6 +209,8 @@
if cmd is None:
return self.default(line)
self.lastcmd = line
+ if line == 'EOF' :
+ self.lastcmd = ''
if cmd == '':
return self.default(line)
else:
diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py
--- a/lib-python/2.7/collections.py
+++ b/lib-python/2.7/collections.py
@@ -312,6 +312,7 @@
def _asdict(self):
'Return a new OrderedDict which maps field names to their values'
return OrderedDict(zip(self._fields, self)) \n
+ __dict__ = property(_asdict) \n
def _replace(_self, **kwds):
'Return a new %(typename)s object replacing specified fields with new values'
result = _self._make(map(kwds.pop, %(field_names)r, _self))
diff --git a/lib-python/2.7/compileall.py b/lib-python/2.7/compileall.py
--- a/lib-python/2.7/compileall.py
+++ b/lib-python/2.7/compileall.py
@@ -1,4 +1,4 @@
-"""Module/script to "compile" all .py files to .pyc (or .pyo) file.
+"""Module/script to byte-compile all .py files to .pyc (or .pyo) files.
When called as a script with arguments, this compiles the directories
given as arguments recursively; the -l option prevents it from
@@ -26,8 +26,8 @@
dir: the directory to byte-compile
maxlevels: maximum recursion level (default 10)
- ddir: if given, purported directory name (this is the
- directory name that will show up in error messages)
+ ddir: the directory that will be prepended to the path to the
+ file as it is compiled into each byte-code file.
force: if 1, force compilation, even if timestamps are up-to-date
quiet: if 1, be quiet during compilation
"""
@@ -64,8 +64,8 @@
Arguments (only fullname is required):
fullname: the file to byte-compile
- ddir: if given, purported directory name (this is the
- directory name that will show up in error messages)
+ ddir: if given, the directory name compiled in to the
+ byte-code file.
force: if 1, force compilation, even if timestamps are up-to-date
quiet: if 1, be quiet during compilation
"""
@@ -157,14 +157,27 @@
print msg
print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
"[-x regexp] [-i list] [directory|file ...]"
- print "-l: don't recurse down"
+ print
+ print "arguments: zero or more file and directory names to compile; " \
+ "if no arguments given, "
+ print " defaults to the equivalent of -l sys.path"
+ print
+ print "options:"
+ print "-l: don't recurse into subdirectories"
print "-f: force rebuild even if timestamps are up-to-date"
- print "-q: quiet operation"
- print "-d destdir: purported directory name for error messages"
- print " if no directory arguments, -l sys.path is assumed"
- print "-x regexp: skip files matching the regular expression regexp"
- print " the regexp is searched for in the full path of the file"
- print "-i list: expand list with its content (file and directory names)"
+ print "-q: output only error messages"
+ print "-d destdir: directory to prepend to file paths for use in " \
+ "compile-time tracebacks and in"
+ print " runtime tracebacks in cases where the source " \
+ "file is unavailable"
+ print "-x regexp: skip files matching the regular expression regexp; " \
+ "the regexp is searched for"
+ print " in the full path of each file considered for " \
+ "compilation"
+ print "-i file: add all the files and directories listed in file to " \
+ "the list considered for"
+ print ' compilation; if "-", names are read from stdin'
+
sys.exit(2)
maxlevels = 10
ddir = None
@@ -205,7 +218,7 @@
else:
success = compile_path()
except KeyboardInterrupt:
- print "\n[interrupt]"
+ print "\n[interrupted]"
success = 0
return success
diff --git a/lib-python/2.7/cookielib.py b/lib-python/2.7/cookielib.py
--- a/lib-python/2.7/cookielib.py
+++ b/lib-python/2.7/cookielib.py
@@ -1014,7 +1014,7 @@
(not erhn.startswith(".") and
not ("."+erhn).endswith(domain))):
_debug(" effective request-host %s (even with added "
- "initial dot) does not end end with %s",
+ "initial dot) does not end with %s",
erhn, domain)
return False
if (cookie.version > 0 or
diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py
--- a/lib-python/2.7/ctypes/__init__.py
+++ b/lib-python/2.7/ctypes/__init__.py
@@ -263,6 +263,22 @@
from _ctypes import POINTER, pointer, _pointer_type_cache
+def _reset_cache():
+ _pointer_type_cache.clear()
+ _c_functype_cache.clear()
+ if _os.name in ("nt", "ce"):
+ _win_functype_cache.clear()
+ # _SimpleCData.c_wchar_p_from_param
+ POINTER(c_wchar).from_param = c_wchar_p.from_param
+ # _SimpleCData.c_char_p_from_param
+ POINTER(c_char).from_param = c_char_p.from_param
+ _pointer_type_cache[None] = c_void_p
+ # XXX for whatever reasons, creating the first instance of a callback
+ # function is needed for the unittests on Win64 to succeed. This MAY
+ # be a compiler bug, since the problem occurs only when _ctypes is
+ # compiled with the MS SDK compiler. Or an uninitialized variable?
+ CFUNCTYPE(c_int)(lambda: None)
+
try:
from _ctypes import set_conversion_mode
except ImportError:
@@ -279,8 +295,6 @@
class c_wchar(_SimpleCData):
_type_ = "u"
- POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
-
def create_unicode_buffer(init, size=None):
"""create_unicode_buffer(aString) -> character array
create_unicode_buffer(anInteger) -> character array
@@ -299,8 +313,6 @@
return buf
raise TypeError(init)
-POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
-
# XXX Deprecated
def SetPointerType(pointer, cls):
if _pointer_type_cache.get(cls, None) is not None:
@@ -463,8 +475,6 @@
descr = FormatError(code).strip()
return WindowsError(code, descr)
-_pointer_type_cache[None] = c_void_p
-
if sizeof(c_uint) == sizeof(c_void_p):
c_size_t = c_uint
c_ssize_t = c_int
@@ -550,8 +560,4 @@
elif sizeof(kind) == 8: c_uint64 = kind
del(kind)
-# XXX for whatever reasons, creating the first instance of a callback
-# function is needed for the unittests on Win64 to succeed. This MAY
-# be a compiler bug, since the problem occurs only when _ctypes is
-# compiled with the MS SDK compiler. Or an uninitialized variable?
-CFUNCTYPE(c_int)(lambda: None)
+_reset_cache()
diff --git a/lib-python/2.7/ctypes/_endian.py b/lib-python/2.7/ctypes/_endian.py
--- a/lib-python/2.7/ctypes/_endian.py
+++ b/lib-python/2.7/ctypes/_endian.py
@@ -4,20 +4,24 @@
import sys
from ctypes import *
-_array_type = type(c_int * 3)
+_array_type = type(Array)
def _other_endian(typ):
"""Return the type with the 'other' byte order. Simple types like
c_int and so on already have __ctype_be__ and __ctype_le__
attributes which contain the types, for more complicated types
- only arrays are supported.
+ arrays and structures are supported.
"""
- try:
+ # check _OTHER_ENDIAN attribute (present if typ is primitive type)
+ if hasattr(typ, _OTHER_ENDIAN):
return getattr(typ, _OTHER_ENDIAN)
- except AttributeError:
- if type(typ) == _array_type:
- return _other_endian(typ._type_) * typ._length_
- raise TypeError("This type does not support other endian: %s" % typ)
+ # if typ is array
+ if isinstance(typ, _array_type):
+ return _other_endian(typ._type_) * typ._length_
+ # if typ is structure
+ if issubclass(typ, Structure):
+ return typ
+ raise TypeError("This type does not support other endian: %s" % typ)
class _swapped_meta(type(Structure)):
def __setattr__(self, attrname, value):
diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py
--- a/lib-python/2.7/ctypes/test/test_as_parameter.py
+++ b/lib-python/2.7/ctypes/test/test_as_parameter.py
@@ -74,6 +74,7 @@
def test_callbacks(self):
f = dll._testfunc_callback_i_if
f.restype = c_int
+ f.argtypes = None
MyCallback = CFUNCTYPE(c_int, c_int)
diff --git a/lib-python/2.7/ctypes/test/test_buffers.py b/lib-python/2.7/ctypes/test/test_buffers.py
--- a/lib-python/2.7/ctypes/test/test_buffers.py
+++ b/lib-python/2.7/ctypes/test/test_buffers.py
@@ -20,6 +20,10 @@
self.assertEqual(b[::2], "ac")
self.assertEqual(b[::5], "a")
+ def test_buffer_interface(self):
+ self.assertEqual(len(bytearray(create_string_buffer(0))), 0)
+ self.assertEqual(len(bytearray(create_string_buffer(1))), 1)
+
def test_string_conversion(self):
b = create_string_buffer(u"abc")
self.assertEqual(len(b), 4) # trailing nul char
diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py
--- a/lib-python/2.7/ctypes/test/test_byteswap.py
+++ b/lib-python/2.7/ctypes/test/test_byteswap.py
@@ -1,4 +1,4 @@
-import sys, unittest, struct, math
+import sys, unittest, struct, math, ctypes
from binascii import hexlify
from ctypes import *
@@ -191,19 +191,34 @@
pass
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
+ @xfail
def test_struct_struct(self):
- # Nested structures with different byte order not (yet) supported
- if sys.byteorder == "little":
- base = BigEndianStructure
- else:
- base = LittleEndianStructure
+ # nested structures with different byteorders
- class T(Structure):
- _fields_ = [("a", c_int),
- ("b", c_int)]
- class S(base):
- pass
- self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
+ # create nested structures with given byteorders and set memory to data
+
+ for nested, data in (
+ (BigEndianStructure, b'\0\0\0\1\0\0\0\2'),
+ (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'),
+ ):
+ for parent in (
+ BigEndianStructure,
+ LittleEndianStructure,
+ Structure,
+ ):
+ class NestedStructure(nested):
+ _fields_ = [("x", c_uint32),
+ ("y", c_uint32)]
+
+ class TestStructure(parent):
+ _fields_ = [("point", NestedStructure)]
+
+ self.assertEqual(len(data), sizeof(TestStructure))
+ ptr = POINTER(TestStructure)
+ s = cast(data, ptr)[0]
+ del ctypes._pointer_type_cache[TestStructure]
+ self.assertEqual(s.point.x, 1)
+ self.assertEqual(s.point.y, 2)
@xfail
def test_struct_fields_2(self):
diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py
--- a/lib-python/2.7/ctypes/test/test_callbacks.py
+++ b/lib-python/2.7/ctypes/test/test_callbacks.py
@@ -142,6 +142,14 @@
if isinstance(x, X)]
self.assertEqual(len(live), 0)
+ def test_issue12483(self):
+ import gc
+ class Nasty:
+ def __del__(self):
+ gc.collect()
+ CFUNCTYPE(None)(lambda x=Nasty(): None)
+
+
try:
WINFUNCTYPE
except NameError:
diff --git a/lib-python/2.7/ctypes/test/test_functions.py b/lib-python/2.7/ctypes/test/test_functions.py
--- a/lib-python/2.7/ctypes/test/test_functions.py
+++ b/lib-python/2.7/ctypes/test/test_functions.py
@@ -253,6 +253,7 @@
def test_callbacks(self):
f = dll._testfunc_callback_i_if
f.restype = c_int
+ f.argtypes = None
MyCallback = CFUNCTYPE(c_int, c_int)
diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py
--- a/lib-python/2.7/ctypes/test/test_structures.py
+++ b/lib-python/2.7/ctypes/test/test_structures.py
@@ -239,6 +239,14 @@
pass
self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)])
+ def test_invalid_name(self):
+ # field name must be string
+ def declare_with_name(name):
+ class S(Structure):
+ _fields_ = [(name, c_int)]
+
+ self.assertRaises(TypeError, declare_with_name, u"x\xe9")
+
def test_intarray_fields(self):
class SomeInts(Structure):
_fields_ = [("a", c_int * 4)]
@@ -324,6 +332,18 @@
else:
self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers")
+ def test_huge_field_name(self):
+ # issue12881: segfault with large structure field names
+ def create_class(length):
+ class S(Structure):
+ _fields_ = [('x' * length, c_int)]
+
+ for length in [10 ** i for i in range(0, 8)]:
+ try:
+ create_class(length)
+ except MemoryError:
+ # MemoryErrors are OK, we just don't want to segfault
+ pass
def get_except(self, func, *args):
try:
diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py
--- a/lib-python/2.7/ctypes/util.py
+++ b/lib-python/2.7/ctypes/util.py
@@ -182,28 +182,6 @@
else:
- def _findLib_ldconfig(name):
- # XXX assuming GLIBC's ldconfig (with option -p)
- expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
- f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null')
- try:
- data = f.read()
- finally:
- f.close()
- res = re.search(expr, data)
- if not res:
- # Hm, this works only for libs needed by the python executable.
- cmd = 'ldd %s 2>/dev/null' % sys.executable
- f = os.popen(cmd)
- try:
- data = f.read()
- finally:
- f.close()
- res = re.search(expr, data)
- if not res:
- return None
- return res.group(0)
-
def _findSoname_ldconfig(name):
import struct
if struct.calcsize('l') == 4:
@@ -220,8 +198,7 @@
abi_type = mach_map.get(machine, 'libc6')
# XXX assuming GLIBC's ldconfig (with option -p)
- expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \
- % (abi_type, re.escape(name))
+ expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type)
f = os.popen('/sbin/ldconfig -p 2>/dev/null')
try:
data = f.read()
diff --git a/lib-python/2.7/decimal.py b/lib-python/2.7/decimal.py
--- a/lib-python/2.7/decimal.py
+++ b/lib-python/2.7/decimal.py
@@ -21,7 +21,7 @@
This is a Py2.3 implementation of decimal floating point arithmetic based on
the General Decimal Arithmetic Specification:
- www2.hursley.ibm.com/decimal/decarith.html
+ http://speleotrove.com/decimal/decarith.html
and IEEE standard 854-1987:
@@ -1942,9 +1942,9 @@
nonzero. For efficiency, other._exp should not be too large,
so that 10**abs(other._exp) is a feasible calculation."""
- # In the comments below, we write x for the value of self and
- # y for the value of other. Write x = xc*10**xe and y =
- # yc*10**ye.
+ # In the comments below, we write x for the value of self and y for the
+ # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc
+ # and yc positive integers not divisible by 10.
# The main purpose of this method is to identify the *failure*
# of x**y to be exactly representable with as little effort as
@@ -1952,13 +1952,12 @@
# eliminate the possibility of x**y being exact. Only if all
# these tests are passed do we go on to actually compute x**y.
- # Here's the main idea. First normalize both x and y. We
- # express y as a rational m/n, with m and n relatively prime
- # and n>0. Then for x**y to be exactly representable (at
- # *any* precision), xc must be the nth power of a positive
- # integer and xe must be divisible by n. If m is negative
- # then additionally xc must be a power of either 2 or 5, hence
- # a power of 2**n or 5**n.
+ # Here's the main idea. Express y as a rational number m/n, with m and
+ # n relatively prime and n>0. Then for x**y to be exactly
+ # representable (at *any* precision), xc must be the nth power of a
+ # positive integer and xe must be divisible by n. If y is negative
+ # then additionally xc must be a power of either 2 or 5, hence a power
+ # of 2**n or 5**n.
#
# There's a limit to how small |y| can be: if y=m/n as above
# then:
@@ -2030,21 +2029,43 @@
return None
# now xc is a power of 2; e is its exponent
e = _nbits(xc)-1
- # find e*y and xe*y; both must be integers
- if ye >= 0:
- y_as_int = yc*10**ye
- e = e*y_as_int
- xe = xe*y_as_int
- else:
- ten_pow = 10**-ye
- e, remainder = divmod(e*yc, ten_pow)
- if remainder:
- return None
- xe, remainder = divmod(xe*yc, ten_pow)
- if remainder:
- return None
-
- if e*65 >= p*93: # 93/65 > log(10)/log(5)
+
+ # We now have:
+ #
+ # x = 2**e * 10**xe, e > 0, and y < 0.
+ #
+ # The exact result is:
+ #
+ # x**y = 5**(-e*y) * 10**(e*y + xe*y)
+ #
+ # provided that both e*y and xe*y are integers. Note that if
+ # 5**(-e*y) >= 10**p, then the result can't be expressed
+ # exactly with p digits of precision.
+ #
+ # Using the above, we can guard against large values of ye.
+ # 93/65 is an upper bound for log(10)/log(5), so if
+ #
+ # ye >= len(str(93*p//65))
+ #
+ # then
+ #
+ # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5),
+ #
+ # so 5**(-e*y) >= 10**p, and the coefficient of the result
+ # can't be expressed in p digits.
+
+ # emax >= largest e such that 5**e < 10**p.
+ emax = p*93//65
+ if ye >= len(str(emax)):
+ return None
+
+ # Find -e*y and -xe*y; both must be integers
+ e = _decimal_lshift_exact(e * yc, ye)
+ xe = _decimal_lshift_exact(xe * yc, ye)
+ if e is None or xe is None:
+ return None
+
+ if e > emax:
return None
xc = 5**e
@@ -2058,19 +2079,20 @@
while xc % 5 == 0:
xc //= 5
e -= 1
- if ye >= 0:
- y_as_integer = yc*10**ye
- e = e*y_as_integer
- xe = xe*y_as_integer
- else:
- ten_pow = 10**-ye
- e, remainder = divmod(e*yc, ten_pow)
- if remainder:
- return None
- xe, remainder = divmod(xe*yc, ten_pow)
- if remainder:
- return None
- if e*3 >= p*10: # 10/3 > log(10)/log(2)
+
+ # Guard against large values of ye, using the same logic as in
+ # the 'xc is a power of 2' branch. 10/3 is an upper bound for
+ # log(10)/log(2).
+ emax = p*10//3
+ if ye >= len(str(emax)):
+ return None
+
+ e = _decimal_lshift_exact(e * yc, ye)
+ xe = _decimal_lshift_exact(xe * yc, ye)
+ if e is None or xe is None:
+ return None
+
+ if e > emax:
return None
xc = 2**e
else:
@@ -5463,6 +5485,27 @@
hex_n = "%x" % n
return 4*len(hex_n) - correction[hex_n[0]]
+def _decimal_lshift_exact(n, e):
+ """ Given integers n and e, return n * 10**e if it's an integer, else None.
+
+ The computation is designed to avoid computing large powers of 10
+ unnecessarily.
+
+ >>> _decimal_lshift_exact(3, 4)
+ 30000
+ >>> _decimal_lshift_exact(300, -999999999) # returns None
+
+ """
+ if n == 0:
+ return 0
+ elif e >= 0:
+ return n * 10**e
+ else:
+ # val_n = largest power of 10 dividing n.
+ str_n = str(abs(n))
+ val_n = len(str_n) - len(str_n.rstrip('0'))
+ return None if val_n < -e else n // 10**-e
+
def _sqrt_nearest(n, a):
"""Closest integer to the square root of the positive integer n. a is
an initial approximation to the square root. Any positive integer
diff --git a/lib-python/2.7/distutils/__init__.py b/lib-python/2.7/distutils/__init__.py
--- a/lib-python/2.7/distutils/__init__.py
+++ b/lib-python/2.7/distutils/__init__.py
@@ -15,5 +15,5 @@
# Updated automatically by the Python release process.
#
#--start constants--
-__version__ = "2.7.2"
+__version__ = "2.7.3"
#--end constants--
diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py
--- a/lib-python/2.7/distutils/ccompiler.py
+++ b/lib-python/2.7/distutils/ccompiler.py
@@ -18,58 +18,6 @@
from distutils.util import split_quoted, execute
from distutils import log
-_sysconfig = __import__('sysconfig')
-
-def customize_compiler(compiler):
- """Do any platform-specific customization of a CCompiler instance.
-
- Mainly needed on Unix, so we can plug in the information that
- varies across Unices and is stored in Python's Makefile.
- """
- if compiler.compiler_type == "unix":
- (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
- _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
- 'CCSHARED', 'LDSHARED', 'SO', 'AR',
- 'ARFLAGS')
-
- if 'CC' in os.environ:
- cc = os.environ['CC']
- if 'CXX' in os.environ:
- cxx = os.environ['CXX']
- if 'LDSHARED' in os.environ:
- ldshared = os.environ['LDSHARED']
- if 'CPP' in os.environ:
- cpp = os.environ['CPP']
- else:
- cpp = cc + " -E" # not always
- if 'LDFLAGS' in os.environ:
- ldshared = ldshared + ' ' + os.environ['LDFLAGS']
- if 'CFLAGS' in os.environ:
- cflags = opt + ' ' + os.environ['CFLAGS']
- ldshared = ldshared + ' ' + os.environ['CFLAGS']
- if 'CPPFLAGS' in os.environ:
- cpp = cpp + ' ' + os.environ['CPPFLAGS']
- cflags = cflags + ' ' + os.environ['CPPFLAGS']
- ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
- if 'AR' in os.environ:
- ar = os.environ['AR']
- if 'ARFLAGS' in os.environ:
- archiver = ar + ' ' + os.environ['ARFLAGS']
- else:
- archiver = ar + ' ' + ar_flags
-
- cc_cmd = cc + ' ' + cflags
- compiler.set_executables(
- preprocessor=cpp,
- compiler=cc_cmd,
- compiler_so=cc_cmd + ' ' + ccshared,
- compiler_cxx=cxx,
- linker_so=ldshared,
- linker_exe=cc,
- archiver=archiver)
-
- compiler.shared_lib_extension = so_ext
-
class CCompiler:
"""Abstract base class to define the interface that must be implemented
by real compiler classes. Also has some utility methods used by
diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py
--- a/lib-python/2.7/distutils/command/bdist_dumb.py
+++ b/lib-python/2.7/distutils/command/bdist_dumb.py
@@ -58,7 +58,7 @@
self.format = None
self.keep_temp = 0
self.dist_dir = None
- self.skip_build = 0
+ self.skip_build = None
self.relative = 0
self.owner = None
self.group = None
@@ -78,7 +78,8 @@
self.set_undefined_options('bdist',
('dist_dir', 'dist_dir'),
- ('plat_name', 'plat_name'))
+ ('plat_name', 'plat_name'),
+ ('skip_build', 'skip_build'))
def run(self):
if not self.skip_build:
diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py
--- a/lib-python/2.7/distutils/command/bdist_msi.py
+++ b/lib-python/2.7/distutils/command/bdist_msi.py
@@ -131,18 +131,22 @@
self.no_target_optimize = 0
self.target_version = None
self.dist_dir = None
- self.skip_build = 0
+ self.skip_build = None
self.install_script = None
self.pre_install_script = None
self.versions = None
def finalize_options (self):
+ self.set_undefined_options('bdist', ('skip_build', 'skip_build'))
+
if self.bdist_dir is None:
bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'msi')
+
short_version = get_python_version()
if (not self.target_version) and self.distribution.has_ext_modules():
self.target_version = short_version
+
if self.target_version:
self.versions = [self.target_version]
if not self.skip_build and self.distribution.has_ext_modules()\
diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py
--- a/lib-python/2.7/distutils/command/bdist_wininst.py
+++ b/lib-python/2.7/distutils/command/bdist_wininst.py
@@ -71,7 +71,7 @@
self.dist_dir = None
self.bitmap = None
self.title = None
- self.skip_build = 0
+ self.skip_build = None
self.install_script = None
self.pre_install_script = None
self.user_access_control = None
@@ -80,6 +80,8 @@
def finalize_options (self):
+ self.set_undefined_options('bdist', ('skip_build', 'skip_build'))
+
if self.bdist_dir is None:
if self.skip_build and self.plat_name:
# If build is skipped and plat_name is overridden, bdist will
@@ -89,8 +91,10 @@
# next the command will be initialized using that name
bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'wininst')
+
if not self.target_version:
self.target_version = ""
+
if not self.skip_build and self.distribution.has_ext_modules():
short_version = get_python_version()
if self.target_version and self.target_version != short_version:
diff --git a/lib-python/2.7/distutils/command/build_clib.py b/lib-python/2.7/distutils/command/build_clib.py
--- a/lib-python/2.7/distutils/command/build_clib.py
+++ b/lib-python/2.7/distutils/command/build_clib.py
@@ -19,7 +19,7 @@
import os
from distutils.core import Command
from distutils.errors import DistutilsSetupError
-from distutils.ccompiler import customize_compiler
+from distutils.sysconfig import customize_compiler
from distutils import log
def show_compilers():
diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py
--- a/lib-python/2.7/distutils/command/build_ext.py
+++ b/lib-python/2.7/distutils/command/build_ext.py
@@ -160,8 +160,7 @@
if plat_py_include != py_include:
self.include_dirs.append(plat_py_include)
- if isinstance(self.libraries, str):
- self.libraries = [self.libraries]
+ self.ensure_string_list('libraries')
# Life is easier if we're not forever checking for None, so
# simplify these options to empty lists if unset
diff --git a/lib-python/2.7/distutils/command/check.py b/lib-python/2.7/distutils/command/check.py
--- a/lib-python/2.7/distutils/command/check.py
+++ b/lib-python/2.7/distutils/command/check.py
@@ -5,6 +5,7 @@
__revision__ = "$Id$"
from distutils.core import Command
+from distutils.dist import PKG_INFO_ENCODING
from distutils.errors import DistutilsSetupError
try:
@@ -108,6 +109,8 @@
def check_restructuredtext(self):
"""Checks if the long string fields are reST-compliant."""
data = self.distribution.get_long_description()
+ if not isinstance(data, unicode):
+ data = data.decode(PKG_INFO_ENCODING)
for warning in self._check_rst_data(data):
line = warning[-1].get('line')
if line is None:
diff --git a/lib-python/2.7/distutils/command/config.py b/lib-python/2.7/distutils/command/config.py
--- a/lib-python/2.7/distutils/command/config.py
+++ b/lib-python/2.7/distutils/command/config.py
@@ -16,7 +16,7 @@
from distutils.core import Command
from distutils.errors import DistutilsExecError
-from distutils.ccompiler import customize_compiler
+from distutils.sysconfig import customize_compiler
from distutils import log
LANG_EXT = {'c': '.c', 'c++': '.cxx'}
diff --git a/lib-python/2.7/distutils/command/register.py b/lib-python/2.7/distutils/command/register.py
--- a/lib-python/2.7/distutils/command/register.py
+++ b/lib-python/2.7/distutils/command/register.py
@@ -10,7 +10,6 @@
import urllib2
import getpass
import urlparse
-import StringIO
from warnings import warn
from distutils.core import PyPIRCCommand
@@ -260,21 +259,30 @@
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
sep_boundary = '\n--' + boundary
end_boundary = sep_boundary + '--'
- body = StringIO.StringIO()
+ chunks = []
for key, value in data.items():
# handle multiple entries for the same name
if type(value) not in (type([]), type( () )):
value = [value]
for value in value:
- body.write(sep_boundary)
- body.write('\nContent-Disposition: form-data; name="%s"'%key)
- body.write("\n\n")
- body.write(value)
+ chunks.append(sep_boundary)
+ chunks.append('\nContent-Disposition: form-data; name="%s"'%key)
+ chunks.append("\n\n")
+ chunks.append(value)
if value and value[-1] == '\r':
- body.write('\n') # write an extra newline (lurve Macs)
- body.write(end_boundary)
- body.write("\n")
- body = body.getvalue()
+ chunks.append('\n') # write an extra newline (lurve Macs)
+ chunks.append(end_boundary)
+ chunks.append("\n")
+
+ # chunks may be bytes (str) or unicode objects that we need to encode
+ body = []
+ for chunk in chunks:
+ if isinstance(chunk, unicode):
+ body.append(chunk.encode('utf-8'))
+ else:
+ body.append(chunk)
+
+ body = ''.join(body)
# build the Request
headers = {
diff --git a/lib-python/2.7/distutils/command/sdist.py b/lib-python/2.7/distutils/command/sdist.py
--- a/lib-python/2.7/distutils/command/sdist.py
+++ b/lib-python/2.7/distutils/command/sdist.py
@@ -182,14 +182,20 @@
reading the manifest, or just using the default file set -- it all
depends on the user's options.
"""
- # new behavior:
+ # new behavior when using a template:
# the file list is recalculated everytime because
# even if MANIFEST.in or setup.py are not changed
# the user might have added some files in the tree that
# need to be included.
#
- # This makes --force the default and only behavior.
+ # This makes --force the default and only behavior with templates.
template_exists = os.path.isfile(self.template)
+ if not template_exists and self._manifest_is_not_generated():
+ self.read_manifest()
+ self.filelist.sort()
+ self.filelist.remove_duplicates()
+ return
+
if not template_exists:
self.warn(("manifest template '%s' does not exist " +
"(using default file list)") %
@@ -314,7 +320,10 @@
try:
self.filelist.process_template_line(line)
- except DistutilsTemplateError, msg:
+ # the call above can raise a DistutilsTemplateError for
+ # malformed lines, or a ValueError from the lower-level
+ # convert_path function
+ except (DistutilsTemplateError, ValueError) as msg:
self.warn("%s, line %d: %s" % (template.filename,
template.current_line,
msg))
@@ -352,23 +361,28 @@
by 'add_defaults()' and 'read_template()') to the manifest file
named by 'self.manifest'.
"""
- if os.path.isfile(self.manifest):
- fp = open(self.manifest)
- try:
- first_line = fp.readline()
- finally:
- fp.close()
-
- if first_line != '# file GENERATED by distutils, do NOT edit\n':
- log.info("not writing to manually maintained "
- "manifest file '%s'" % self.manifest)
- return
+ if self._manifest_is_not_generated():
+ log.info("not writing to manually maintained "
+ "manifest file '%s'" % self.manifest)
+ return
content = self.filelist.files[:]
content.insert(0, '# file GENERATED by distutils, do NOT edit')
self.execute(file_util.write_file, (self.manifest, content),
"writing manifest file '%s'" % self.manifest)
+ def _manifest_is_not_generated(self):
+ # check for special comment used in 2.7.1 and higher
+ if not os.path.isfile(self.manifest):
+ return False
+
+ fp = open(self.manifest, 'rU')
+ try:
+ first_line = fp.readline()
+ finally:
+ fp.close()
+ return first_line != '# file GENERATED by distutils, do NOT edit\n'
+
def read_manifest(self):
"""Read the manifest file (named by 'self.manifest') and use it to
fill in 'self.filelist', the list of files to include in the source
@@ -376,12 +390,11 @@
"""
log.info("reading manifest file '%s'", self.manifest)
manifest = open(self.manifest)
- while 1:
- line = manifest.readline()
- if line == '': # end of file
- break
- if line[-1] == '\n':
- line = line[0:-1]
+ for line in manifest:
+ # ignore comments and blank lines
+ line = line.strip()
+ if line.startswith('#') or not line:
+ continue
self.filelist.append(line)
manifest.close()
diff --git a/lib-python/2.7/distutils/dep_util.py b/lib-python/2.7/distutils/dep_util.py
--- a/lib-python/2.7/distutils/dep_util.py
+++ b/lib-python/2.7/distutils/dep_util.py
@@ -7,6 +7,7 @@
__revision__ = "$Id$"
import os
+from stat import ST_MTIME
from distutils.errors import DistutilsFileError
def newer(source, target):
@@ -27,7 +28,7 @@
if not os.path.exists(target):
return True
- return os.stat(source).st_mtime > os.stat(target).st_mtime
+ return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME]
def newer_pairwise(sources, targets):
"""Walk two filename lists in parallel, testing if each source is newer
@@ -71,7 +72,7 @@
# is more recent than 'target', then 'target' is out-of-date and
# we can immediately return true. If we fall through to the end
# of the loop, then 'target' is up-to-date and we return false.
- target_mtime = os.stat(target).st_mtime
+ target_mtime = os.stat(target)[ST_MTIME]
for source in sources:
if not os.path.exists(source):
@@ -82,7 +83,7 @@
elif missing == 'newer': # missing source means target is
return True # out-of-date
- if os.stat(source).st_mtime > target_mtime:
+ if os.stat(source)[ST_MTIME] > target_mtime:
return True
return False
diff --git a/lib-python/2.7/distutils/dist.py b/lib-python/2.7/distutils/dist.py
--- a/lib-python/2.7/distutils/dist.py
+++ b/lib-python/2.7/distutils/dist.py
@@ -1111,7 +1111,8 @@
"""Write the PKG-INFO format data to a file object.
"""
version = '1.0'
- if self.provides or self.requires or self.obsoletes:
+ if (self.provides or self.requires or self.obsoletes or
+ self.classifiers or self.download_url):
version = '1.1'
self._write_field(file, 'Metadata-Version', version)
diff --git a/lib-python/2.7/distutils/filelist.py b/lib-python/2.7/distutils/filelist.py
--- a/lib-python/2.7/distutils/filelist.py
+++ b/lib-python/2.7/distutils/filelist.py
@@ -210,6 +210,7 @@
Return 1 if files are found.
"""
+ # XXX docstring lying about what the special chars are?
files_found = 0
pattern_re = translate_pattern(pattern, anchor, prefix, is_regex)
self.debug_print("include_pattern: applying regex r'%s'" %
@@ -297,11 +298,14 @@
# IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix,
# and by extension they shouldn't match such "special characters" under
# any OS. So change all non-escaped dots in the RE to match any
- # character except the special characters.
- # XXX currently the "special characters" are just slash -- i.e. this is
- # Unix-only.
- pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', r'\1[^/]', pattern_re)
-
+ # character except the special characters (currently: just os.sep).
+ sep = os.sep
+ if os.sep == '\\':
+ # we're using a regex to manipulate a regex, so we need
+ # to escape the backslash twice
+ sep = r'\\\\'
+ escaped = r'\1[^%s]' % sep
+ pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re)
return pattern_re
@@ -328,7 +332,10 @@
# ditch end of pattern character
empty_pattern = glob_to_re('')
prefix_re = glob_to_re(prefix)[:-len(empty_pattern)]
- pattern_re = "^" + os.path.join(prefix_re, ".*" + pattern_re)
+ sep = os.sep
+ if os.sep == '\\':
+ sep = r'\\'
+ pattern_re = "^" + sep.join((prefix_re, ".*" + pattern_re))
else: # no prefix -- respect anchor flag
if anchor:
pattern_re = "^" + pattern_re
diff --git a/lib-python/2.7/distutils/msvc9compiler.py b/lib-python/2.7/distutils/msvc9compiler.py
--- a/lib-python/2.7/distutils/msvc9compiler.py
+++ b/lib-python/2.7/distutils/msvc9compiler.py
@@ -640,16 +640,7 @@
self.library_filename(dll_name))
ld_args.append ('/IMPLIB:' + implib_file)
- # Embedded manifests are recommended - see MSDN article titled
- # "How to: Embed a Manifest Inside a C/C++ Application"
- # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
- # Ask the linker to generate the manifest in the temp dir, so
- # we can embed it later.
- temp_manifest = os.path.join(
- build_temp,
- os.path.basename(output_filename) + ".manifest")
- ld_args.append('/MANIFEST')
- ld_args.append('/MANIFESTFILE:' + temp_manifest)
+ self.manifest_setup_ldargs(output_filename, build_temp, ld_args)
if extra_preargs:
ld_args[:0] = extra_preargs
@@ -667,20 +658,55 @@
# will still consider the DLL up-to-date, but it will not have a
# manifest. Maybe we should link to a temp file? OTOH, that
# implies a build environment error that shouldn't go undetected.
- if target_desc == CCompiler.EXECUTABLE:
- mfid = 1
- else:
- mfid = 2
- self._remove_visual_c_ref(temp_manifest)
- out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
- try:
- self.spawn(['mt.exe', '-nologo', '-manifest',
- temp_manifest, out_arg])
- except DistutilsExecError, msg:
- raise LinkError(msg)
+ mfinfo = self.manifest_get_embed_info(target_desc, ld_args)
+ if mfinfo is not None:
+ mffilename, mfid = mfinfo
+ out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
+ try:
+ self.spawn(['mt.exe', '-nologo', '-manifest',
+ mffilename, out_arg])
+ except DistutilsExecError, msg:
+ raise LinkError(msg)
else:
log.debug("skipping %s (up-to-date)", output_filename)
+ def manifest_setup_ldargs(self, output_filename, build_temp, ld_args):
+ # If we need a manifest at all, an embedded manifest is recommended.
+ # See MSDN article titled
+ # "How to: Embed a Manifest Inside a C/C++ Application"
+ # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
+ # Ask the linker to generate the manifest in the temp dir, so
+ # we can check it, and possibly embed it, later.
+ temp_manifest = os.path.join(
+ build_temp,
+ os.path.basename(output_filename) + ".manifest")
+ ld_args.append('/MANIFEST')
+ ld_args.append('/MANIFESTFILE:' + temp_manifest)
+
+ def manifest_get_embed_info(self, target_desc, ld_args):
+ # If a manifest should be embedded, return a tuple of
+ # (manifest_filename, resource_id). Returns None if no manifest
+ # should be embedded. See http://bugs.python.org/issue7833 for why
+ # we want to avoid any manifest for extension modules if we can)
+ for arg in ld_args:
+ if arg.startswith("/MANIFESTFILE:"):
+ temp_manifest = arg.split(":", 1)[1]
+ break
+ else:
+ # no /MANIFESTFILE so nothing to do.
+ return None
+ if target_desc == CCompiler.EXECUTABLE:
+ # by default, executables always get the manifest with the
+ # CRT referenced.
+ mfid = 1
+ else:
+ # Extension modules try and avoid any manifest if possible.
+ mfid = 2
+ temp_manifest = self._remove_visual_c_ref(temp_manifest)
+ if temp_manifest is None:
+ return None
+ return temp_manifest, mfid
+
def _remove_visual_c_ref(self, manifest_file):
try:
# Remove references to the Visual C runtime, so they will
@@ -689,6 +715,8 @@
# runtimes are not in WinSxS folder, but in Python's own
# folder), the runtimes do not need to be in every folder
# with .pyd's.
+ # Returns either the filename of the modified manifest or
+ # None if no manifest should be embedded.
manifest_f = open(manifest_file)
try:
manifest_buf = manifest_f.read()
@@ -701,9 +729,18 @@
manifest_buf = re.sub(pattern, "", manifest_buf)
pattern = "<dependentAssembly>\s*</dependentAssembly>"
manifest_buf = re.sub(pattern, "", manifest_buf)
+ # Now see if any other assemblies are referenced - if not, we
+ # don't want a manifest embedded.
+ pattern = re.compile(
+ r"""<assemblyIdentity.*?name=(?:"|')(.+?)(?:"|')"""
+ r""".*?(?:/>|</assemblyIdentity>)""", re.DOTALL)
+ if re.search(pattern, manifest_buf) is None:
+ return None
+
manifest_f = open(manifest_file, 'w')
try:
manifest_f.write(manifest_buf)
+ return manifest_file
finally:
manifest_f.close()
except IOError:
diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py
--- a/lib-python/2.7/distutils/spawn.py
+++ b/lib-python/2.7/distutils/spawn.py
@@ -96,17 +96,43 @@
raise DistutilsExecError, \
"command '%s' failed with exit status %d" % (cmd[0], rc)
+if sys.platform == 'darwin':
+ from distutils import sysconfig
+ _cfg_target = None
+ _cfg_target_split = None
def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):
log.info(' '.join(cmd))
if dry_run:
return
exec_fn = search_path and os.execvp or os.execv
+ exec_args = [cmd[0], cmd]
+ if sys.platform == 'darwin':
+ global _cfg_target, _cfg_target_split
+ if _cfg_target is None:
+ _cfg_target = sysconfig.get_config_var(
+ 'MACOSX_DEPLOYMENT_TARGET') or ''
+ if _cfg_target:
+ _cfg_target_split = [int(x) for x in _cfg_target.split('.')]
+ if _cfg_target:
+ # ensure that the deployment target of build process is not less
+ # than that used when the interpreter was built. This ensures
+ # extension modules are built with correct compatibility values
+ cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target)
+ if _cfg_target_split > [int(x) for x in cur_target.split('.')]:
+ my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: '
+ 'now "%s" but "%s" during configure'
+ % (cur_target, _cfg_target))
+ raise DistutilsPlatformError(my_msg)
+ env = dict(os.environ,
+ MACOSX_DEPLOYMENT_TARGET=cur_target)
+ exec_fn = search_path and os.execvpe or os.execve
+ exec_args.append(env)
pid = os.fork()
if pid == 0: # in the child
try:
- exec_fn(cmd[0], cmd)
+ exec_fn(*exec_args)
except OSError, e:
sys.stderr.write("unable to execute %s: %s\n" %
(cmd[0], e.strerror))
diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py
--- a/lib-python/2.7/distutils/sysconfig.py
+++ b/lib-python/2.7/distutils/sysconfig.py
@@ -26,4 +26,5 @@
from distutils.sysconfig_cpython import _config_vars # needed by setuptools
from distutils.sysconfig_cpython import _variable_rx # read_setup_file()
+_USE_CLANG = None
diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py
--- a/lib-python/2.7/distutils/sysconfig_cpython.py
+++ b/lib-python/2.7/distutils/sysconfig_cpython.py
@@ -149,12 +149,43 @@
varies across Unices and is stored in Python's Makefile.
"""
if compiler.compiler_type == "unix":
- (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \
+ (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
- 'CCSHARED', 'LDSHARED', 'SO')
+ 'CCSHARED', 'LDSHARED', 'SO', 'AR',
+ 'ARFLAGS')
+ newcc = None
if 'CC' in os.environ:
- cc = os.environ['CC']
+ newcc = os.environ['CC']
+ elif sys.platform == 'darwin' and cc == 'gcc-4.2':
+ # Issue #13590:
+ # Since Apple removed gcc-4.2 in Xcode 4.2, we can no
+ # longer assume it is available for extension module builds.
+ # If Python was built with gcc-4.2, check first to see if
+ # it is available on this system; if not, try to use clang
+ # instead unless the caller explicitly set CC.
+ global _USE_CLANG
+ if _USE_CLANG is None:
+ from distutils import log
+ from subprocess import Popen, PIPE
+ p = Popen("! type gcc-4.2 && type clang && exit 2",
+ shell=True, stdout=PIPE, stderr=PIPE)
+ p.wait()
+ if p.returncode == 2:
+ _USE_CLANG = True
+ log.warn("gcc-4.2 not found, using clang instead")
+ else:
+ _USE_CLANG = False
+ if _USE_CLANG:
+ newcc = 'clang'
+ if newcc:
+ # On OS X, if CC is overridden, use that as the default
+ # command for LDSHARED as well
+ if (sys.platform == 'darwin'
+ and 'LDSHARED' not in os.environ
+ and ldshared.startswith(cc)):
+ ldshared = newcc + ldshared[len(cc):]
+ cc = newcc
if 'CXX' in os.environ:
cxx = os.environ['CXX']
if 'LDSHARED' in os.environ:
@@ -172,6 +203,12 @@
cpp = cpp + ' ' + os.environ['CPPFLAGS']
cflags = cflags + ' ' + os.environ['CPPFLAGS']
ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
+ if 'AR' in os.environ:
+ ar = os.environ['AR']
+ if 'ARFLAGS' in os.environ:
+ archiver = ar + ' ' + os.environ['ARFLAGS']
+ else:
+ archiver = ar + ' ' + ar_flags
cc_cmd = cc + ' ' + cflags
compiler.set_executables(
@@ -180,7 +217,8 @@
compiler_so=cc_cmd + ' ' + ccshared,
compiler_cxx=cxx,
linker_so=ldshared,
- linker_exe=cc)
+ linker_exe=cc,
+ archiver=archiver)
compiler.shared_lib_extension = so_ext
@@ -380,21 +418,6 @@
raise DistutilsPlatformError(my_msg)
- # On MacOSX we need to check the setting of the environment variable
- # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
- # it needs to be compatible.
- # If it isn't set we set it to the configure-time value
- if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g:
- cfg_target = g['MACOSX_DEPLOYMENT_TARGET']
- cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
- if cur_target == '':
- cur_target = cfg_target
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target
- elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')):
- my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure'
- % (cur_target, cfg_target))
- raise DistutilsPlatformError(my_msg)
-
# On AIX, there are wrong paths to the linker scripts in the Makefile
# -- these paths are relative to the Python source, but when installed
# the scripts are in another directory.
diff --git a/lib-python/2.7/distutils/tests/Setup.sample b/lib-python/2.7/distutils/tests/Setup.sample
old mode 100755
new mode 100644
diff --git a/lib-python/2.7/distutils/tests/support.py b/lib-python/2.7/distutils/tests/support.py
--- a/lib-python/2.7/distutils/tests/support.py
+++ b/lib-python/2.7/distutils/tests/support.py
@@ -1,7 +1,10 @@
"""Support code for distutils test cases."""
import os
+import sys
import shutil
import tempfile
+import unittest
+import sysconfig
from copy import deepcopy
import warnings
@@ -9,6 +12,7 @@
from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL
from distutils.core import Distribution
+
def capture_warnings(func):
def _capture_warnings(*args, **kw):
with warnings.catch_warnings():
@@ -16,6 +20,7 @@
return func(*args, **kw)
return _capture_warnings
+
class LoggingSilencer(object):
def setUp(self):
@@ -49,6 +54,7 @@
def clear_logs(self):
self.logs = []
+
class TempdirManager(object):
"""Mix-in class that handles temporary directories for test cases.
@@ -57,9 +63,13 @@
def setUp(self):
super(TempdirManager, self).setUp()
+ self.old_cwd = os.getcwd()
self.tempdirs = []
def tearDown(self):
+ # Restore working dir, for Solaris and derivatives, where rmdir()
+ # on the current directory fails.
+ os.chdir(self.old_cwd)
super(TempdirManager, self).tearDown()
while self.tempdirs:
d = self.tempdirs.pop()
@@ -105,6 +115,7 @@
return pkg_dir, dist
+
class DummyCommand:
"""Class to store options for retrieval via set_undefined_options()."""
@@ -115,6 +126,7 @@
def ensure_finalized(self):
pass
+
class EnvironGuard(object):
def setUp(self):
@@ -131,3 +143,79 @@
del os.environ[key]
super(EnvironGuard, self).tearDown()
+
+
+def copy_xxmodule_c(directory):
More information about the pypy-commit
mailing list