Commit c3eaff85 authored by Philip Jenvey's avatar Philip Jenvey

update the Python 3 stdlib to v3.2.5

parent e418f553
......@@ -114,7 +114,7 @@ division = _Feature((2, 2, 0, "alpha", 2),
CO_FUTURE_DIVISION)
absolute_import = _Feature((2, 5, 0, "alpha", 1),
(2, 7, 0, "alpha", 0),
(3, 0, 0, "alpha", 0),
CO_FUTURE_ABSOLUTE_IMPORT)
with_statement = _Feature((2, 5, 0, "alpha", 1),
......
......@@ -184,12 +184,12 @@ class Set(Sized, Iterable, Container):
def __gt__(self, other):
if not isinstance(other, Set):
return NotImplemented
return other < self
return other.__lt__(self)
def __ge__(self, other):
if not isinstance(other, Set):
return NotImplemented
return other <= self
return other.__le__(self)
def __eq__(self, other):
if not isinstance(other, Set):
......
This diff is collapsed.
......@@ -298,7 +298,7 @@ class IOBase(metaclass=abc.ABCMeta):
def seek(self, pos, whence=0):
"""Change stream position.
Change the stream position to byte offset offset. offset is
Change the stream position to byte offset pos. Argument pos is
interpreted relative to the position indicated by whence. Values
for whence are ints:
......@@ -889,12 +889,18 @@ class BytesIO(BufferedIOBase):
return pos
def readable(self):
if self.closed:
raise ValueError("I/O operation on closed file.")
return True
def writable(self):
if self.closed:
raise ValueError("I/O operation on closed file.")
return True
def seekable(self):
if self.closed:
raise ValueError("I/O operation on closed file.")
return True
......@@ -1567,6 +1573,8 @@ class TextIOWrapper(TextIOBase):
return self._buffer
def seekable(self):
if self.closed:
raise ValueError("I/O operation on closed file.")
return self._seekable
def readable(self):
......
......@@ -339,7 +339,7 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
raise ValueError("unconverted data remains: %s" %
data_string[found.end():])
year = 1900
year = None
month = day = 1
hour = minute = second = fraction = 0
tz = -1
......@@ -444,6 +444,12 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
else:
tz = value
break
leap_year_fix = False
if year is None and month == 2 and day == 29:
year = 1904 # 1904 is first leap year of 20th century
leap_year_fix = True
elif year is None:
year = 1900
# If we know the week of the year and what day of that week, we can figure
# out the Julian day of the year.
if julian == -1 and week_of_year != -1 and weekday != -1:
......@@ -472,6 +478,12 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
else:
gmtoff = None
if leap_year_fix:
# the caller didn't supply a year but asked for Feb 29th. We couldn't
# use the default of 1900 for computations. We set it back to ensure
# that February 29th is smaller than March 1st.
year = 1900
return (year, month, day,
hour, minute, second,
weekday, julian, tz, gmtoff, tzname), fraction
......
......@@ -63,7 +63,7 @@ class WeakSet:
yield item
def __len__(self):
return sum(x() is not None for x in self.data)
return len(self.data) - len(self._pending_removals)
def __contains__(self, item):
try:
......@@ -114,36 +114,21 @@ class WeakSet:
def update(self, other):
if self._pending_removals:
self._commit_removals()
if isinstance(other, self.__class__):
self.data.update(other.data)
else:
for element in other:
self.add(element)
for element in other:
self.add(element)
def __ior__(self, other):
self.update(other)
return self
# Helper functions for simple delegating methods.
def _apply(self, other, method):
if not isinstance(other, self.__class__):
other = self.__class__(other)
newdata = method(other.data)
newset = self.__class__()
newset.data = newdata
return newset
def difference(self, other):
return self._apply(other, self.data.difference)
newset = self.copy()
newset.difference_update(other)
return newset
__sub__ = difference
def difference_update(self, other):
if self._pending_removals:
self._commit_removals()
if self is other:
self.data.clear()
else:
self.data.difference_update(ref(item) for item in other)
self.__isub__(other)
def __isub__(self, other):
if self._pending_removals:
self._commit_removals()
......@@ -154,13 +139,11 @@ class WeakSet:
return self
def intersection(self, other):
return self._apply(other, self.data.intersection)
return self.__class__(item for item in other if item in self)
__and__ = intersection
def intersection_update(self, other):
if self._pending_removals:
self._commit_removals()
self.data.intersection_update(ref(item) for item in other)
self.__iand__(other)
def __iand__(self, other):
if self._pending_removals:
self._commit_removals()
......@@ -169,17 +152,17 @@ class WeakSet:
def issubset(self, other):
return self.data.issubset(ref(item) for item in other)
__lt__ = issubset
__le__ = issubset
def __le__(self, other):
return self.data <= set(ref(item) for item in other)
def __lt__(self, other):
return self.data < set(ref(item) for item in other)
def issuperset(self, other):
return self.data.issuperset(ref(item) for item in other)
__gt__ = issuperset
__ge__ = issuperset
def __ge__(self, other):
return self.data >= set(ref(item) for item in other)
def __gt__(self, other):
return self.data > set(ref(item) for item in other)
def __eq__(self, other):
if not isinstance(other, self.__class__):
......@@ -187,27 +170,24 @@ class WeakSet:
return self.data == set(ref(item) for item in other)
def symmetric_difference(self, other):
return self._apply(other, self.data.symmetric_difference)
newset = self.copy()
newset.symmetric_difference_update(other)
return newset
__xor__ = symmetric_difference
def symmetric_difference_update(self, other):
if self._pending_removals:
self._commit_removals()
if self is other:
self.data.clear()
else:
self.data.symmetric_difference_update(ref(item) for item in other)
self.__ixor__(other)
def __ixor__(self, other):
if self._pending_removals:
self._commit_removals()
if self is other:
self.data.clear()
else:
self.data.symmetric_difference_update(ref(item) for item in other)
self.data.symmetric_difference_update(ref(item, self._remove) for item in other)
return self
def union(self, other):
return self._apply(other, self.data.union)
return self.__class__(e for s in (self, other) for e in s)
__or__ = union
def isdisjoint(self, other):
......
......@@ -692,7 +692,9 @@ class Aifc_write:
self._patchheader()
def close(self):
if self._file:
if self._file is None:
return
try:
self._ensure_header_written(0)
if self._datawritten & 1:
# quick pad to even size
......@@ -703,10 +705,12 @@ class Aifc_write:
self._datalength != self._datawritten or \
self._marklength:
self._patchheader()
finally:
# Prevent ref cycles
self._convert = None
self._file.close()
f = self._file
self._file = None
f.close()
#
# Internal methods.
......
......@@ -736,10 +736,10 @@ class Action(_AttributeHolder):
- default -- The value to be produced if the option is not specified.
- type -- The type which the command-line arguments should be converted
to, should be one of 'string', 'int', 'float', 'complex' or a
callable object that accepts a single string argument. If None,
'string' is assumed.
- type -- A callable that accepts a single string argument, and
returns the converted value. The standard Python types str, int,
float, and complex are useful examples of such callables. If None,
str is used.
- choices -- A container of values that should be allowed. If not None,
after a command-line argument has been converted to the appropriate
......@@ -1701,9 +1701,12 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
return args
def parse_known_args(self, args=None, namespace=None):
# args default to the system args
if args is None:
# args default to the system args
args = _sys.argv[1:]
else:
# make sure that args are mutable
args = list(args)
# default Namespace built from parser defaults
if namespace is None:
......@@ -1714,10 +1717,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
if action.dest is not SUPPRESS:
if not hasattr(namespace, action.dest):
if action.default is not SUPPRESS:
default = action.default
if isinstance(action.default, str):
default = self._get_value(action, default)
setattr(namespace, action.dest, default)
setattr(namespace, action.dest, action.default)
# add any parser defaults that aren't present
for dest in self._defaults:
......@@ -1945,12 +1945,23 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
if positionals:
self.error(_('too few arguments'))
# make sure all required actions were present
# make sure all required actions were present, and convert defaults.
for action in self._actions:
if action.required:
if action not in seen_actions:
if action not in seen_actions:
if action.required:
name = _get_action_name(action)
self.error(_('argument %s is required') % name)
else:
# Convert action default now instead of doing it before
# parsing arguments to avoid calling convert functions
# twice (which may fail) if the argument was given, but
# only if it was defined already in the namespace
if (action.default is not None and
isinstance(action.default, str) and
hasattr(namespace, action.dest) and
action.default is getattr(namespace, action.dest)):
setattr(namespace, action.dest,
self._get_value(action, action.default))
# make sure all required groups had one option present
for group in self._mutually_exclusive_groups:
......@@ -1976,7 +1987,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
for arg_string in arg_strings:
# for regular arguments, just add them back into the list
if arg_string[0] not in self.fromfile_prefix_chars:
if not arg_string or arg_string[0] not in self.fromfile_prefix_chars:
new_arg_strings.append(arg_string)
# replace arguments referencing files with the file content
......@@ -2186,9 +2197,12 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# Value conversion methods
# ========================
def _get_values(self, action, arg_strings):
# for everything but PARSER args, strip out '--'
# for everything but PARSER, REMAINDER args, strip out first '--'
if action.nargs not in [PARSER, REMAINDER]:
arg_strings = [s for s in arg_strings if s != '--']
try:
arg_strings.remove('--')
except ValueError:
pass
# optional argument produces a default when not present
if not arg_strings and action.nargs == OPTIONAL:
......
......@@ -225,6 +225,7 @@ class dispatcher:
debug = False
connected = False
accepting = False
connecting = False
closing = False
addr = None
ignore_log_types = frozenset(['warning'])
......@@ -248,7 +249,7 @@ class dispatcher:
try:
self.addr = sock.getpeername()
except socket.error as err:
if err.args[0] == ENOTCONN:
if err.args[0] in (ENOTCONN, EINVAL):
# To handle the case where we got an unconnected
# socket.
self.connected = False
......@@ -342,9 +343,11 @@ class dispatcher:
def connect(self, address):
self.connected = False
self.connecting = True
err = self.socket.connect_ex(address)
if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \
or err == EINVAL and os.name in ('nt', 'ce'):
self.addr = address
return
if err in (0, EISCONN):
self.addr = address
......@@ -390,7 +393,7 @@ class dispatcher:
else:
return data
except socket.error as why:
# winsock sometimes throws ENOTCONN
# winsock sometimes raises ENOTCONN
if why.args[0] in _DISCONNECTED:
self.handle_close()
return b''
......@@ -400,6 +403,7 @@ class dispatcher:
def close(self):
self.connected = False
self.accepting = False
self.connecting = False
self.del_channel()
try:
self.socket.close()
......@@ -438,7 +442,8 @@ class dispatcher:
# sockets that are connected
self.handle_accept()
elif not self.connected:
self.handle_connect_event()
if self.connecting:
self.handle_connect_event()
self.handle_read()
else:
self.handle_read()
......@@ -449,6 +454,7 @@ class dispatcher:
raise socket.error(err, _strerror(err))
self.handle_connect()
self.connected = True
self.connecting = False
def handle_write_event(self):
if self.accepting:
......@@ -457,12 +463,8 @@ class dispatcher:
return
if not self.connected:
#check for errors
err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
if err != 0:
raise socket.error(err, _strerror(err))
self.handle_connect_event()
if self.connecting:
self.handle_connect_event()
self.handle_write()
def handle_expt_event(self):
......
......@@ -22,6 +22,7 @@ class Bdb:
self.skip = set(skip) if skip else None
self.breaks = {}
self.fncache = {}
self.frame_returning = None
def canonic(self, filename):
if filename == "<" + filename[1:-1] + ">":
......@@ -80,7 +81,11 @@ class Bdb:
def dispatch_return(self, frame, arg):
if self.stop_here(frame) or frame == self.returnframe:
self.user_return(frame, arg)
try:
self.frame_returning = frame
self.user_return(frame, arg)
finally:
self.frame_returning = None
if self.quitting: raise BdbQuit
return self.trace_dispatch
......@@ -186,6 +191,14 @@ class Bdb:
def set_step(self):
"""Stop after one line of code."""
# Issue #13183: pdb skips frames after hitting a breakpoint and running
# step commands.
# Restore the trace function in the caller (that may not have been set
# for performance reasons) when returning from the current frame.
if self.frame_returning:
caller_frame = self.frame_returning.f_back
if caller_frame and not caller_frame.f_trace:
caller_frame.f_trace = self.trace_dispatch
self._set_stopinfo(None, None)
def set_next(self, frame):
......
......@@ -161,7 +161,11 @@ class Calendar(object):
oneday = datetime.timedelta(days=1)
while True:
yield date
date += oneday
try:
date += oneday
except OverflowError:
# Adding one day could fail after datetime.MAXYEAR
break
if date.month != month and date.weekday() == self.firstweekday:
break
......
......@@ -214,17 +214,17 @@ def parse_multipart(fp, pdict):
"""
import http.client
boundary = ""
boundary = b""
if 'boundary' in pdict:
boundary = pdict['boundary']
if not valid_boundary(boundary):
raise ValueError('Invalid boundary in multipart form: %r'
% (boundary,))
nextpart = "--" + boundary
lastpart = "--" + boundary + "--"
nextpart = b"--" + boundary
lastpart = b"--" + boundary + b"--"
partdict = {}
terminator = ""
terminator = b""
while terminator != lastpart:
bytes = -1
......@@ -243,7 +243,7 @@ def parse_multipart(fp, pdict):
raise ValueError('Maximum content length exceeded')
data = fp.read(bytes)
else:
data = ""
data = b""
# Read lines until end of part.
lines = []
while 1:
......@@ -251,7 +251,7 @@ def parse_multipart(fp, pdict):
if not line:
terminator = lastpart # End outer loop
break
if line.startswith("--"):
if line.startswith(b"--"):
terminator = line.rstrip()
if terminator in (nextpart, lastpart):
break
......@@ -263,12 +263,12 @@ def parse_multipart(fp, pdict):
if lines:
# Strip final line terminator
line = lines[-1]
if line[-2:] == "\r\n":
if line[-2:] == b"\r\n":
line = line[:-2]
elif line[-1:] == "\n":
elif line[-1:] == b"\n":
line = line[:-1]
lines[-1] = line
data = "".join(lines)
data = b"".join(lines)
line = headers['content-disposition']
if not line:
continue
......
......@@ -293,14 +293,19 @@ class Hook:
if self.logdir is not None:
suffix = ['.txt', '.html'][self.format=="html"]
(fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)
try:
file = os.fdopen(fd, 'w')
file.write(doc)
file.close()
msg = '<p> %s contains the description of this error.' % path
msg = '%s contains the description of this error.' % path
except:
msg = '<p> Tried to save traceback to %s, but failed.' % path
self.file.write(msg + '\n')
msg = 'Tried to save traceback to %s, but failed.' % path
if self.format == 'html':
self.file.write('<p>%s</p>\n' % msg)
else:
self.file.write(msg + '\n')
try:
self.file.flush()
except: pass
......
......@@ -281,6 +281,10 @@ class {typename}(tuple):
'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
def __getstate__(self):
'Exclude the OrderedDict from pickling'
return None
{field_defs}
'''
......
......@@ -112,12 +112,14 @@ class _AllCompletedWaiter(_Waiter):
def __init__(self, num_pending_calls, stop_on_exception):
self.num_pending_calls = num_pending_calls
self.stop_on_exception = stop_on_exception
self.lock = threading.Lock()
super().__init__()
def _decrement_pending_calls(self):