Merge pull request #3910 from youknowone/update-container-tests

Update multiple unittests from CPython 3.10.5
This commit is contained in:
Jeong YunWon authored and GitHub committed 2022-07-18 22:19:11 +09:00
commit 79f4b33956
39 files changed
+8517 -7224

No files matched your search

+102 -30
View File
@@ -52,7 +52,7 @@ def _find_executable(executable, path=None):
return executable
def _read_output(commandstring):
def _read_output(commandstring, capture_stderr=False):
"""Output from successful command execution or None"""
# Similar to os.popen(commandstring, "r").read(),
# but without actually using os.popen because that
@@ -67,7 +67,10 @@ def _read_output(commandstring):
os.getpid(),), "w+b")
with contextlib.closing(fp) as fp:
cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
if capture_stderr:
cmd = "%s >'%s' 2>&1" % (commandstring, fp.name)
else:
cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
return fp.read().decode('utf-8').strip() if not os.system(cmd) else None
@@ -93,7 +96,7 @@ def _get_system_version():
if _SYSTEM_VERSION is None:
_SYSTEM_VERSION = ''
try:
f = open('/System/Library/CoreServices/SystemVersion.plist')
f = open('/System/Library/CoreServices/SystemVersion.plist', encoding="utf-8")
except OSError:
# We're on a plain darwin box, fall back to the default
# behaviour.
@@ -110,6 +113,26 @@ def _get_system_version():
return _SYSTEM_VERSION
_SYSTEM_VERSION_TUPLE = None
def _get_system_version_tuple():
"""
Return the macOS system version as a tuple
The return value is safe to use to compare
two version numbers.
"""
global _SYSTEM_VERSION_TUPLE
if _SYSTEM_VERSION_TUPLE is None:
osx_version = _get_system_version()
if osx_version:
try:
_SYSTEM_VERSION_TUPLE = tuple(int(i) for i in osx_version.split('.'))
except ValueError:
_SYSTEM_VERSION_TUPLE = ()
return _SYSTEM_VERSION_TUPLE
def _remove_original_values(_config_vars):
"""Remove original unmodified values for testing"""
# This is needed for higher-level cross-platform tests of get_platform.
@@ -125,6 +148,33 @@ def _save_modified_value(_config_vars, cv, newvalue):
_config_vars[_INITPRE + cv] = oldvalue
_config_vars[cv] = newvalue
_cache_default_sysroot = None
def _default_sysroot(cc):
""" Returns the root of the default SDK for this system, or '/' """
global _cache_default_sysroot
if _cache_default_sysroot is not None:
return _cache_default_sysroot
contents = _read_output('%s -c -E -v - </dev/null' % (cc,), True)
in_incdirs = False
for line in contents.splitlines():
if line.startswith("#include <...>"):
in_incdirs = True
elif line.startswith("End of search list"):
in_incdirs = False
elif in_incdirs:
line = line.strip()
if line == '/usr/include':
_cache_default_sysroot = '/'
elif line.endswith(".sdk/usr/include"):
_cache_default_sysroot = line[:-12]
if _cache_default_sysroot is None:
_cache_default_sysroot = '/'
return _cache_default_sysroot
def _supports_universal_builds():
"""Returns True if universal builds are supported on this system"""
# As an approximation, we assume that if we are running on 10.4 or above,
@@ -132,14 +182,18 @@ def _supports_universal_builds():
# builds, in particular -isysroot and -arch arguments to the compiler. This
# is in support of allowing 10.4 universal builds to run on 10.3.x systems.
osx_version = _get_system_version()
if osx_version:
try:
osx_version = tuple(int(i) for i in osx_version.split('.'))
except ValueError:
osx_version = ''
osx_version = _get_system_version_tuple()
return bool(osx_version >= (10, 4)) if osx_version else False
def _supports_arm64_builds():
"""Returns True if arm64 builds are supported on this system"""
# There are two sets of systems supporting macOS/arm64 builds:
# 1. macOS 11 and later, unconditionally
# 2. macOS 10.15 with Xcode 12.2 or later
# For now the second category is ignored.
osx_version = _get_system_version_tuple()
return osx_version >= (11, 0) if osx_version else False
def _find_appropriate_compiler(_config_vars):
"""Find appropriate C compiler for extension module builds"""
@@ -211,7 +265,7 @@ def _remove_universal_flags(_config_vars):
if cv in _config_vars and cv not in os.environ:
flags = _config_vars[cv]
flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII)
flags = re.sub('-isysroot [^ \t]*', ' ', flags)
flags = re.sub(r'-isysroot\s*\S+', ' ', flags)
_save_modified_value(_config_vars, cv, flags)
return _config_vars
@@ -287,7 +341,7 @@ def _check_for_unavailable_sdk(_config_vars):
# to /usr and /System/Library by either a standalone CLT
# package or the CLT component within Xcode.
cflags = _config_vars.get('CFLAGS', '')
m = re.search(r'-isysroot\s+(\S+)', cflags)
m = re.search(r'-isysroot\s*(\S+)', cflags)
if m is not None:
sdk = m.group(1)
if not os.path.exists(sdk):
@@ -295,7 +349,7 @@ def _check_for_unavailable_sdk(_config_vars):
# Do not alter a config var explicitly overridden by env var
if cv in _config_vars and cv not in os.environ:
flags = _config_vars[cv]
flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags)
flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags)
_save_modified_value(_config_vars, cv, flags)
return _config_vars
@@ -320,7 +374,7 @@ def compiler_fixup(compiler_so, cc_args):
stripArch = stripSysroot = True
else:
stripArch = '-arch' in cc_args
stripSysroot = '-isysroot' in cc_args
stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot'))
if stripArch or 'ARCHFLAGS' in os.environ:
while True:
@@ -331,6 +385,12 @@ def compiler_fixup(compiler_so, cc_args):
except ValueError:
break
elif not _supports_arm64_builds():
# Look for "-arch arm64" and drop that
for idx in reversed(range(len(compiler_so))):
if compiler_so[idx] == '-arch' and compiler_so[idx+1] == "arm64":
del compiler_so[idx:idx+2]
if 'ARCHFLAGS' in os.environ and not stripArch:
# User specified different -arch flags in the environ,
# see also distutils.sysconfig
@@ -338,29 +398,39 @@ def compiler_fixup(compiler_so, cc_args):
if stripSysroot:
while True:
try:
index = compiler_so.index('-isysroot')
indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
if not indices:
break
index = indices[0]
if compiler_so[index] == '-isysroot':
# Strip this argument and the next one:
del compiler_so[index:index+2]
except ValueError:
break
else:
# It's '-isysroot/some/path' in one arg
del compiler_so[index:index+1]
# Check if the SDK that is used during compilation actually exists,
# the universal build requires the usage of a universal SDK and not all
# users have that installed by default.
sysroot = None
if '-isysroot' in cc_args:
idx = cc_args.index('-isysroot')
sysroot = cc_args[idx+1]
elif '-isysroot' in compiler_so:
idx = compiler_so.index('-isysroot')
sysroot = compiler_so[idx+1]
argvar = cc_args
indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')]
if not indices:
argvar = compiler_so
indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
for idx in indices:
if argvar[idx] == '-isysroot':
sysroot = argvar[idx+1]
break
else:
sysroot = argvar[idx][len('-isysroot'):]
break
if sysroot and not os.path.isdir(sysroot):
from distutils import log
log.warn("Compiling with an SDK that doesn't seem to exist: %s",
sysroot)
log.warn("Please check your Xcode installation")
sys.stderr.write(f"Compiling with an SDK that doesn't seem to exist: {sysroot}\n")
sys.stderr.write("Please check your Xcode installation\n")
sys.stderr.flush()
return compiler_so
@@ -411,7 +481,7 @@ def customize_compiler(_config_vars):
This customization is performed when the first
extension module build is requested
in distutils.sysconfig.customize_compiler).
in distutils.sysconfig.customize_compiler.
"""
# Find a compiler to use for extension module builds
@@ -454,10 +524,10 @@ def get_platform_osx(_config_vars, osname, release, machine):
try:
macrelease = tuple(int(i) for i in macrelease.split('.')[0:2])
except ValueError:
macrelease = (10, 0)
macrelease = (10, 3)
else:
# assume no universal support
macrelease = (10, 0)
macrelease = (10, 3)
if (macrelease >= (10, 4)) and '-arch' in cflags.strip():
# The universal build will build fat binaries, but not on
@@ -470,6 +540,8 @@ def get_platform_osx(_config_vars, osname, release, machine):
if len(archs) == 1:
machine = archs[0]
elif archs == ('arm64', 'x86_64'):
machine = 'universal2'
elif archs == ('i386', 'ppc'):
machine = 'fat'
elif archs == ('i386', 'x86_64'):
+87 -101
View File
@@ -27,7 +27,6 @@ __all__ = [
]
import _collections_abc
import heapq as _heapq
import sys as _sys
from itertools import chain as _chain
@@ -56,22 +55,6 @@ except ImportError:
from ._defaultdict import defaultdict
def __getattr__(name):
# For backwards compatibility, continue to make the collections ABCs
# through Python 3.6 available through the collections module.
# Note, no new collections ABCs were added in Python 3.7
if name in _collections_abc.__all__:
obj = getattr(_collections_abc, name)
import warnings
warnings.warn("Using or importing the ABCs from 'collections' instead "
"of from 'collections.abc' is deprecated since Python 3.3, "
"and in 3.10 it will stop working",
DeprecationWarning, stacklevel=2)
globals()[name] = obj
return obj
raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
################################################################################
### OrderedDict
################################################################################
@@ -111,17 +94,10 @@ class OrderedDict(dict):
# Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict.
def __init__(*args, **kwds):
def __init__(self, other=(), /, **kwds):
'''Initialize an ordered dictionary. The signature is the same as
regular dictionaries. Keyword argument order is preserved.
'''
if not args:
raise TypeError("descriptor '__init__' of 'OrderedDict' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__root
except AttributeError:
@@ -129,7 +105,7 @@ class OrderedDict(dict):
self.__root = root = _proxy(self.__hardroot)
root.prev = root.next = root
self.__map = {}
self.__update(*args, **kwds)
self.__update(other, **kwds)
def __setitem__(self, key, value,
dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
@@ -455,8 +431,8 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non
_make.__func__.__doc__ = (f'Make a new {typename} object from a sequence '
'or iterable')
def _replace(_self, /, **kwds):
result = _self._make(_map(kwds.pop, field_names, _self))
def _replace(self, /, **kwds):
result = self._make(_map(kwds.pop, field_names, self))
if kwds:
raise ValueError(f'Got unexpected field names: {list(kwds)!r}')
return result
@@ -500,6 +476,7 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non
'__repr__': __repr__,
'_asdict': _asdict,
'__getnewargs__': __getnewargs__,
'__match_args__': field_names,
}
for index, name in enumerate(field_names):
doc = _sys.intern(f'Alias for field number {index}')
@@ -589,7 +566,7 @@ class Counter(dict):
# http://code.activestate.com/recipes/259174/
# Knuth, TAOCP Vol. II section 4.6.3
def __init__(*args, **kwds):
def __init__(self, iterable=None, /, **kwds):
'''Create a new, empty Counter object. And if given, count elements
from an input iterable. Or, initialize the count from another mapping
of elements to their counts.
@@ -600,20 +577,18 @@ class Counter(dict):
>>> c = Counter(a=4, b=2) # a new counter from keyword args
'''
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
super(Counter, self).__init__()
self.update(*args, **kwds)
super().__init__()
self.update(iterable, **kwds)
def __missing__(self, key):
'The count of elements not in the Counter is zero.'
# Needed so that self[missing_item] does not raise KeyError
return 0
def total(self):
'Sum of the counts'
return sum(self.values())
def most_common(self, n=None):
'''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
@@ -625,7 +600,10 @@ class Counter(dict):
# Emulate Bag.sortedByCount from Smalltalk
if n is None:
return sorted(self.items(), key=_itemgetter(1), reverse=True)
return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
# Lazy import to speedup Python startup time
import heapq
return heapq.nlargest(n, self.items(), key=_itemgetter(1))
def elements(self):
'''Iterator over elements repeating each as many times as its count.
@@ -663,7 +641,7 @@ class Counter(dict):
raise NotImplementedError(
'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
def update(*args, **kwds):
def update(self, iterable=None, /, **kwds):
'''Like dict.update() but add counts instead of replacing them.
Source can be an iterable, a dictionary, or another Counter instance.
@@ -683,14 +661,6 @@ class Counter(dict):
# contexts. Instead, we implement straight-addition. Both the inputs
# and outputs are allowed to contain zero and negative counts.
if not args:
raise TypeError("descriptor 'update' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
iterable = args[0] if args else None
if iterable is not None:
if isinstance(iterable, _collections_abc.Mapping):
if self:
@@ -699,13 +669,13 @@ class Counter(dict):
self[elem] = count + self_get(elem, 0)
else:
# fast path when counter is empty
super(Counter, self).update(iterable)
super().update(iterable)
else:
_count_elements(self, iterable)
if kwds:
self.update(kwds)
def subtract(*args, **kwds):
def subtract(self, iterable=None, /, **kwds):
'''Like dict.update() but subtracts counts instead of replacing them.
Counts can be reduced below zero. Both the inputs and outputs are
allowed to contain zero and negative counts.
@@ -721,14 +691,6 @@ class Counter(dict):
-1
'''
if not args:
raise TypeError("descriptor 'subtract' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
iterable = args[0] if args else None
if iterable is not None:
self_get = self.get
if isinstance(iterable, _collections_abc.Mapping):
@@ -752,6 +714,42 @@ class Counter(dict):
if elem in self:
super().__delitem__(elem)
def __eq__(self, other):
'True if all counts agree. Missing counts are treated as zero.'
if not isinstance(other, Counter):
return NotImplemented
return all(self[e] == other[e] for c in (self, other) for e in c)
def __ne__(self, other):
'True if any counts disagree. Missing counts are treated as zero.'
if not isinstance(other, Counter):
return NotImplemented
return not self == other
def __le__(self, other):
'True if all counts in self are a subset of those in other.'
if not isinstance(other, Counter):
return NotImplemented
return all(self[e] <= other[e] for c in (self, other) for e in c)
def __lt__(self, other):
'True if all counts in self are a proper subset of those in other.'
if not isinstance(other, Counter):
return NotImplemented
return self <= other and self != other
def __ge__(self, other):
'True if all counts in self are a superset of those in other.'
if not isinstance(other, Counter):
return NotImplemented
return all(self[e] >= other[e] for c in (self, other) for e in c)
def __gt__(self, other):
'True if all counts in self are a proper superset of those in other.'
if not isinstance(other, Counter):
return NotImplemented
return self >= other and self != other
def __repr__(self):
if not self:
return f'{self.__class__.__name__}()'
@@ -772,12 +770,30 @@ class Counter(dict):
# To strip negative and zero counts, add-in an empty counter:
# c += Counter()
#
# Rich comparison operators for multiset subset and superset tests
# are deliberately omitted due to semantic conflicts with the
# existing inherited dict equality method. Subset and superset
# semantics ignore zero counts and require that p≤q ∧ p≥q → p=q;
# however, that would not be the case for p=Counter(a=1, b=0)
# and q=Counter(a=1) where the dictionaries are not equal.
# Results are ordered according to when an element is first
# encountered in the left operand and then by the order
# encountered in the right operand.
#
# When the multiplicities are all zero or one, multiset operations
# are guaranteed to be equivalent to the corresponding operations
# for regular sets.
# Given counter multisets such as:
# cp = Counter(a=1, b=0, c=1)
# cq = Counter(c=1, d=0, e=1)
# The corresponding regular sets would be:
# sp = {'a', 'c'}
# sq = {'c', 'e'}
# All of the following relations would hold:
# set(cp + cq) == sp | sq
# set(cp - cq) == sp - sq
# set(cp | cq) == sp | sq
# set(cp & cq) == sp & sq
# (cp == cq) == (sp == sq)
# (cp != cq) == (sp != sq)
# (cp <= cq) == (sp <= sq)
# (cp < cq) == (sp < sq)
# (cp >= cq) == (sp >= sq)
# (cp > cq) == (sp > sq)
def __add__(self, other):
'''Add counts from two counters.
@@ -1006,12 +1022,15 @@ class ChainMap(_collections_abc.MutableMapping):
__copy__ = copy
def new_child(self, m=None): # like Django's Context.push()
def new_child(self, m=None, **kwargs): # like Django's Context.push()
'''New ChainMap with a new map followed by all previous maps.
If no map is provided, an empty dict is used.
Keyword arguments update the map or new empty dict.
'''
if m is None:
m = {}
m = kwargs
elif kwargs:
m.update(kwargs)
return self.__class__(m, *self.maps)
@property
@@ -1073,34 +1092,16 @@ class ChainMap(_collections_abc.MutableMapping):
class UserDict(_collections_abc.MutableMapping):
# Start by filling-out the abstract methods
def __init__(*args, **kwargs):
if not args:
raise TypeError("descriptor '__init__' of 'UserDict' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
if args:
dict = args[0]
elif 'dict' in kwargs:
dict = kwargs.pop('dict')
import warnings
warnings.warn("Passing 'dict' as keyword argument is deprecated",
DeprecationWarning, stacklevel=2)
else:
dict = None
def __init__(self, dict=None, /, **kwargs):
self.data = {}
if dict is not None:
self.update(dict)
if len(kwargs):
if kwargs:
self.update(kwargs)
def __len__(self):
return len(self.data)
def __bool__(self):
return bool(self.data)
def __getitem__(self, key):
if key in self.data:
return self.data[key]
@@ -1153,9 +1154,6 @@ class UserDict(_collections_abc.MutableMapping):
inst.__dict__["data"] = self.__dict__["data"].copy()
return inst
def __sizeof__(self):
return _sys.getsizeof(self.data)
def copy(self):
if self.__class__ is UserDict:
return UserDict(self.data.copy())
@@ -1222,9 +1220,6 @@ class UserList(_collections_abc.MutableSequence):
def __len__(self):
return len(self.data)
def __bool__(self):
return bool(self.data)
def __getitem__(self, i):
if isinstance(i, slice):
return self.__class__(self.data[i])
@@ -1276,9 +1271,6 @@ class UserList(_collections_abc.MutableSequence):
inst.__dict__["data"] = self.__dict__["data"][:]
return inst
def __sizeof__(self):
return _sys.getsizeof(self.data)
def append(self, item):
self.data.append(item)
@@ -1381,9 +1373,6 @@ class UserString(_collections_abc.Sequence):
char = char.data
return char in self.data
def __bool__(self):
return bool(self.data)
def __len__(self):
return len(self.data)
@@ -1413,9 +1402,6 @@ class UserString(_collections_abc.Sequence):
def __rmod__(self, template):
return self.__class__(str(template) % self)
def __sizeof__(self):
return _sys.getsizeof(self.data)
# the following methods are defined in alphabetical order:
def capitalize(self):
return self.__class__(self.data.capitalize())
@@ -1571,4 +1557,4 @@ class UserString(_collections_abc.Sequence):
return self.__class__(self.data.upper())
def zfill(self, width):
return self.__class__(self.data.zfill(width))
return self.__class__(self.data.zfill(width))
+1
View File
@@ -1,2 +1,3 @@
from _collections_abc import *
from _collections_abc import __all__
from _collections_abc import _CallableGenericAlias
+1 -1
View File
@@ -298,7 +298,7 @@ class _PySimpleQueue:
def put_nowait(self, item):
'''Put an item into the queue without blocking.
This is exactly equivalent to `put(item)` and is only provided
This is exactly equivalent to `put(item, block=False)` and is only provided
for compatibility with the Queue class.
'''
return self.put(item, block=False)
+150 -142
View File
@@ -6,7 +6,8 @@ This module allows high-level and efficient I/O multiplexing, built upon the
from abc import ABCMeta, abstractmethod
from collections import namedtuple, Mapping
from collections import namedtuple
from collections.abc import Mapping
import math
import select
import sys
@@ -56,6 +57,7 @@ if sys.version_info >= (3, 5):
SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object.
For example, this could be used to store a per-client session ID.''')
class _SelectorMapping(Mapping):
"""Mapping of file objects to selector keys."""
@@ -251,7 +253,6 @@ class _BaseSelectorImpl(BaseSelector):
return key
def modify(self, fileobj, events, data=None):
# TODO: Subclasses can probably optimize this even further.
try:
key = self._fd_to_key[self._fileobj_lookup(fileobj)]
except KeyError:
@@ -338,92 +339,115 @@ class SelectSelector(_BaseSelectorImpl):
return ready
class _PollLikeSelector(_BaseSelectorImpl):
"""Base class shared between poll, epoll and devpoll selectors."""
_selector_cls = None
_EVENT_READ = None
_EVENT_WRITE = None
def __init__(self):
super().__init__()
self._selector = self._selector_cls()
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
poller_events = 0
if events & EVENT_READ:
poller_events |= self._EVENT_READ
if events & EVENT_WRITE:
poller_events |= self._EVENT_WRITE
try:
self._selector.register(key.fd, poller_events)
except:
super().unregister(fileobj)
raise
return key
def unregister(self, fileobj):
key = super().unregister(fileobj)
try:
self._selector.unregister(key.fd)
except OSError:
# This can happen if the FD was closed since it
# was registered.
pass
return key
def modify(self, fileobj, events, data=None):
try:
key = self._fd_to_key[self._fileobj_lookup(fileobj)]
except KeyError:
raise KeyError(f"{fileobj!r} is not registered") from None
changed = False
if events != key.events:
selector_events = 0
if events & EVENT_READ:
selector_events |= self._EVENT_READ
if events & EVENT_WRITE:
selector_events |= self._EVENT_WRITE
try:
self._selector.modify(key.fd, selector_events)
except:
super().unregister(fileobj)
raise
changed = True
if data != key.data:
changed = True
if changed:
key = key._replace(events=events, data=data)
self._fd_to_key[key.fd] = key
return key
def select(self, timeout=None):
# This is shared between poll() and epoll().
# epoll() has a different signature and handling of timeout parameter.
if timeout is None:
timeout = None
elif timeout <= 0:
timeout = 0
else:
# poll() has a resolution of 1 millisecond, round away from
# zero to wait *at least* timeout seconds.
timeout = math.ceil(timeout * 1e3)
ready = []
try:
fd_event_list = self._selector.poll(timeout)
except InterruptedError:
return ready
for fd, event in fd_event_list:
events = 0
if event & ~self._EVENT_READ:
events |= EVENT_WRITE
if event & ~self._EVENT_WRITE:
events |= EVENT_READ
key = self._key_from_fd(fd)
if key:
ready.append((key, events & key.events))
return ready
if hasattr(select, 'poll'):
class PollSelector(_BaseSelectorImpl):
class PollSelector(_PollLikeSelector):
"""Poll-based selector."""
def __init__(self):
super().__init__()
self._poll = select.poll()
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
poll_events = 0
if events & EVENT_READ:
poll_events |= select.POLLIN
if events & EVENT_WRITE:
poll_events |= select.POLLOUT
self._poll.register(key.fd, poll_events)
return key
def unregister(self, fileobj):
key = super().unregister(fileobj)
self._poll.unregister(key.fd)
return key
def select(self, timeout=None):
if timeout is None:
timeout = None
elif timeout <= 0:
timeout = 0
else:
# poll() has a resolution of 1 millisecond, round away from
# zero to wait *at least* timeout seconds.
timeout = math.ceil(timeout * 1e3)
ready = []
try:
fd_event_list = self._poll.poll(timeout)
except InterruptedError:
return ready
for fd, event in fd_event_list:
events = 0
if event & ~select.POLLIN:
events |= EVENT_WRITE
if event & ~select.POLLOUT:
events |= EVENT_READ
key = self._key_from_fd(fd)
if key:
ready.append((key, events & key.events))
return ready
_selector_cls = select.poll
_EVENT_READ = select.POLLIN
_EVENT_WRITE = select.POLLOUT
if hasattr(select, 'epoll'):
class EpollSelector(_BaseSelectorImpl):
class EpollSelector(_PollLikeSelector):
"""Epoll-based selector."""
def __init__(self):
super().__init__()
self._epoll = select.epoll()
_selector_cls = select.epoll
_EVENT_READ = select.EPOLLIN
_EVENT_WRITE = select.EPOLLOUT
def fileno(self):
return self._epoll.fileno()
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
epoll_events = 0
if events & EVENT_READ:
epoll_events |= select.EPOLLIN
if events & EVENT_WRITE:
epoll_events |= select.EPOLLOUT
try:
self._epoll.register(key.fd, epoll_events)
except BaseException:
super().unregister(fileobj)
raise
return key
def unregister(self, fileobj):
key = super().unregister(fileobj)
try:
self._epoll.unregister(key.fd)
except OSError:
# This can happen if the FD was closed since it
# was registered.
pass
return key
return self._selector.fileno()
def select(self, timeout=None):
if timeout is None:
@@ -442,7 +466,7 @@ if hasattr(select, 'epoll'):
ready = []
try:
fd_event_list = self._epoll.poll(timeout, max_ev)
fd_event_list = self._selector.poll(timeout, max_ev)
except InterruptedError:
return ready
for fd, event in fd_event_list:
@@ -458,65 +482,23 @@ if hasattr(select, 'epoll'):
return ready
def close(self):
self._epoll.close()
self._selector.close()
super().close()
if hasattr(select, 'devpoll'):
class DevpollSelector(_BaseSelectorImpl):
class DevpollSelector(_PollLikeSelector):
"""Solaris /dev/poll selector."""
def __init__(self):
super().__init__()
self._devpoll = select.devpoll()
_selector_cls = select.devpoll
_EVENT_READ = select.POLLIN
_EVENT_WRITE = select.POLLOUT
def fileno(self):
return self._devpoll.fileno()
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
poll_events = 0
if events & EVENT_READ:
poll_events |= select.POLLIN
if events & EVENT_WRITE:
poll_events |= select.POLLOUT
self._devpoll.register(key.fd, poll_events)
return key
def unregister(self, fileobj):
key = super().unregister(fileobj)
self._devpoll.unregister(key.fd)
return key
def select(self, timeout=None):
if timeout is None:
timeout = None
elif timeout <= 0:
timeout = 0
else:
# devpoll() has a resolution of 1 millisecond, round away from
# zero to wait *at least* timeout seconds.
timeout = math.ceil(timeout * 1e3)
ready = []
try:
fd_event_list = self._devpoll.poll(timeout)
except InterruptedError:
return ready
for fd, event in fd_event_list:
events = 0
if event & ~select.POLLIN:
events |= EVENT_WRITE
if event & ~select.POLLOUT:
events |= EVENT_READ
key = self._key_from_fd(fd)
if key:
ready.append((key, events & key.events))
return ready
return self._selector.fileno()
def close(self):
self._devpoll.close()
self._selector.close()
super().close()
@@ -527,10 +509,10 @@ if hasattr(select, 'kqueue'):
def __init__(self):
super().__init__()
self._kqueue = select.kqueue()
self._selector = select.kqueue()
def fileno(self):
return self._kqueue.fileno()
return self._selector.fileno()
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
@@ -538,12 +520,12 @@ if hasattr(select, 'kqueue'):
if events & EVENT_READ:
kev = select.kevent(key.fd, select.KQ_FILTER_READ,
select.KQ_EV_ADD)
self._kqueue.control([kev], 0, 0)
self._selector.control([kev], 0, 0)
if events & EVENT_WRITE:
kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
select.KQ_EV_ADD)
self._kqueue.control([kev], 0, 0)
except BaseException:
self._selector.control([kev], 0, 0)
except:
super().unregister(fileobj)
raise
return key
@@ -554,7 +536,7 @@ if hasattr(select, 'kqueue'):
kev = select.kevent(key.fd, select.KQ_FILTER_READ,
select.KQ_EV_DELETE)
try:
self._kqueue.control([kev], 0, 0)
self._selector.control([kev], 0, 0)
except OSError:
# This can happen if the FD was closed since it
# was registered.
@@ -563,7 +545,7 @@ if hasattr(select, 'kqueue'):
kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
select.KQ_EV_DELETE)
try:
self._kqueue.control([kev], 0, 0)
self._selector.control([kev], 0, 0)
except OSError:
# See comment above.
pass
@@ -571,10 +553,13 @@ if hasattr(select, 'kqueue'):
def select(self, timeout=None):
timeout = None if timeout is None else max(timeout, 0)
max_ev = len(self._fd_to_key)
# If max_ev is 0, kqueue will ignore the timeout. For consistent
# behavior with the other selector classes, we prevent that here
# (using max). See https://bugs.python.org/issue29255
max_ev = max(len(self._fd_to_key), 1)
ready = []
try:
kev_list = self._kqueue.control(None, max_ev, timeout)
kev_list = self._selector.control(None, max_ev, timeout)
except InterruptedError:
return ready
for kev in kev_list:
@@ -592,20 +577,43 @@ if hasattr(select, 'kqueue'):
return ready
def close(self):
self._kqueue.close()
self._selector.close()
super().close()
def _can_use(method):
"""Check if we can use the selector depending upon the
operating system. """
# Implementation based upon https://github.com/sethmlarson/selectors2/blob/master/selectors2.py
selector = getattr(select, method, None)
if selector is None:
# select module does not implement method
return False
# check if the OS and Kernel actually support the method. Call may fail with
# OSError: [Errno 38] Function not implemented
try:
selector_obj = selector()
if method == 'poll':
# check that poll actually works
selector_obj.poll(0)
else:
# close epoll, kqueue, and devpoll fd
selector_obj.close()
return True
except OSError:
return False
# Choose the best implementation, roughly:
# epoll|kqueue|devpoll > poll > select.
# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
if 'KqueueSelector' in globals():
if _can_use('kqueue'):
DefaultSelector = KqueueSelector
elif 'EpollSelector' in globals():
elif _can_use('epoll'):
DefaultSelector = EpollSelector
elif 'DevpollSelector' in globals():
elif _can_use('devpoll'):
DefaultSelector = DevpollSelector
elif 'PollSelector' in globals():
elif _can_use('poll'):
DefaultSelector = PollSelector
else:
DefaultSelector = SelectSelector
+20 -16
View File
@@ -2,13 +2,13 @@
Tests common to list and UserList.UserList
"""
import unittest
import sys
import os
import unittest
from functools import cmp_to_key
from test import support, seq_tests
from test.support import os_helper
from test.support import ALWAYS_EQ, NEVER_EQ
class CommonTest(seq_tests.CommonTest):
@@ -67,20 +67,6 @@ class CommonTest(seq_tests.CommonTest):
a = self.type2test([a])
self.assertRaises(RecursionError, repr, a)
def test_print(self):
d = self.type2test(range(200))
d.append(d)
d.extend(range(200,400))
d.append(d)
d.append(400)
try:
with open(os_helper.TESTFN, "w") as fo:
fo.write(str(d))
with open(os_helper.TESTFN, "r") as fo:
self.assertEqual(fo.read(), repr(d))
finally:
os.remove(os_helper.TESTFN)
def test_set_subscript(self):
a = self.type2test(range(20))
self.assertRaises(ValueError, a.__setitem__, slice(0, 10, 0), [1,2,3])
@@ -318,6 +304,8 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(TypeError, a.pop, 42, 42)
a = self.type2test([0, 10, 20, 30, 40])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_remove(self):
a = self.type2test([0, 0, 1])
a.remove(1)
@@ -331,6 +319,20 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(TypeError, a.remove)
a = self.type2test([1, 2])
self.assertRaises(ValueError, a.remove, NEVER_EQ)
self.assertEqual(a, [1, 2])
a.remove(ALWAYS_EQ)
self.assertEqual(a, [2])
a = self.type2test([ALWAYS_EQ])
a.remove(1)
self.assertEqual(a, [])
a = self.type2test([ALWAYS_EQ])
a.remove(NEVER_EQ)
self.assertEqual(a, [])
a = self.type2test([NEVER_EQ])
self.assertRaises(ValueError, a.remove, ALWAYS_EQ)
class BadExc(Exception):
pass
@@ -363,6 +365,8 @@ class CommonTest(seq_tests.CommonTest):
# verify that original order and values are retained.
self.assertIs(x, y)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_index(self):
super().test_index()
a = self.type2test([-2, -1, 0, 0, 1, 2])
+21 -9
View File
@@ -6,6 +6,7 @@ import unittest
import sys
import pickle
from test import support
from test.support import ALWAYS_EQ, NEVER_EQ
# Various iterables
# This is used for checking the constructor (here and in test_deque.py)
@@ -209,6 +210,7 @@ class CommonTest(unittest.TestCase):
a = self.type2test([0,1,2,3,4])
self.assertEqual(a[ -pow(2,128): 3 ], self.type2test([0,1,2]))
self.assertEqual(a[ 3: pow(2,145) ], self.type2test([3,4]))
self.assertEqual(a[3::sys.maxsize], self.type2test([3]))
def test_contains(self):
u = self.type2test([0, 1, 2])
@@ -220,15 +222,15 @@ class CommonTest(unittest.TestCase):
self.assertRaises(TypeError, u.__contains__)
def test_contains_fake(self):
class AllEq:
# Sequences must use rich comparison against each item
# (unless "is" is true, or an earlier item answered)
# So instances of AllEq must be found in all non-empty sequences.
def __eq__(self, other):
return True
__hash__ = None # Can't meet hash invariant requirements
self.assertNotIn(AllEq(), self.type2test([]))
self.assertIn(AllEq(), self.type2test([1]))
# Sequences must use rich comparison against each item
# (unless "is" is true, or an earlier item answered)
# So ALWAYS_EQ must be found in all non-empty sequences.
self.assertNotIn(ALWAYS_EQ, self.type2test([]))
self.assertIn(ALWAYS_EQ, self.type2test([1]))
self.assertIn(1, self.type2test([ALWAYS_EQ]))
self.assertNotIn(NEVER_EQ, self.type2test([]))
self.assertNotIn(ALWAYS_EQ, self.type2test([NEVER_EQ]))
self.assertIn(NEVER_EQ, self.type2test([ALWAYS_EQ]))
def test_contains_order(self):
# Sequences must test in-order. If a rich comparison has side
@@ -349,6 +351,11 @@ class CommonTest(unittest.TestCase):
self.assertEqual(a.count(1), 3)
self.assertEqual(a.count(3), 0)
self.assertEqual(a.count(ALWAYS_EQ), 9)
self.assertEqual(self.type2test([ALWAYS_EQ, ALWAYS_EQ]).count(1), 2)
self.assertEqual(self.type2test([ALWAYS_EQ, ALWAYS_EQ]).count(NEVER_EQ), 2)
self.assertEqual(self.type2test([NEVER_EQ, NEVER_EQ]).count(ALWAYS_EQ), 0)
self.assertRaises(TypeError, a.count)
class BadExc(Exception):
@@ -377,6 +384,11 @@ class CommonTest(unittest.TestCase):
self.assertEqual(u.index(0, 3, 4), 3)
self.assertRaises(ValueError, u.index, 2, 0, -10)
self.assertEqual(u.index(ALWAYS_EQ), 0)
self.assertEqual(self.type2test([ALWAYS_EQ, ALWAYS_EQ]).index(1), 0)
self.assertEqual(self.type2test([ALWAYS_EQ, ALWAYS_EQ]).index(NEVER_EQ), 0)
self.assertRaises(ValueError, self.type2test([NEVER_EQ, NEVER_EQ]).index, ALWAYS_EQ)
self.assertRaises(TypeError, u.index)
class BadExc(Exception):
+327 -331
View File
@@ -1,331 +1,327 @@
"""
Test suite for _osx_support: shared OS X support functions.
"""
import os
import platform
import stat
import sys
import unittest
from test.support import os_helper
import _osx_support
@unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
class Test_OSXSupport(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.prog_name = 'bogus_program_xxxx'
self.temp_path_dir = os.path.abspath(os.getcwd())
self.env = os_helper.EnvironmentVarGuard()
self.addCleanup(self.env.__exit__)
for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
if cv in self.env:
self.env.unset(cv)
def add_expected_saved_initial_values(self, config_vars, expected_vars):
# Ensure that the initial values for all modified config vars
# are also saved with modified keys.
expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
config_vars[k]) for k in config_vars
if config_vars[k] != expected_vars[k])
def test__find_executable(self):
if self.env['PATH']:
self.env['PATH'] = self.env['PATH'] + ':'
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
os_helper.unlink(self.prog_name)
self.assertIsNone(_osx_support._find_executable(self.prog_name))
self.addCleanup(os_helper.unlink, self.prog_name)
with open(self.prog_name, 'w') as f:
f.write("#!/bin/sh\n/bin/echo OK\n")
os.chmod(self.prog_name, stat.S_IRWXU)
self.assertEqual(self.prog_name,
_osx_support._find_executable(self.prog_name))
def test__read_output(self):
if self.env['PATH']:
self.env['PATH'] = self.env['PATH'] + ':'
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
os_helper.unlink(self.prog_name)
self.addCleanup(os_helper.unlink, self.prog_name)
with open(self.prog_name, 'w') as f:
f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
os.chmod(self.prog_name, stat.S_IRWXU)
self.assertEqual('ExpectedOutput',
_osx_support._read_output(self.prog_name))
def test__find_build_tool(self):
out = _osx_support._find_build_tool('cc')
self.assertTrue(os.path.isfile(out),
'cc not found - check xcode-select')
def test__get_system_version(self):
self.assertTrue(platform.mac_ver()[0].startswith(
_osx_support._get_system_version()))
def test__remove_original_values(self):
config_vars = {
'CC': 'gcc-test -pthreads',
}
expected_vars = {
'CC': 'clang -pthreads',
}
cv = 'CC'
newvalue = 'clang -pthreads'
_osx_support._save_modified_value(config_vars, cv, newvalue)
self.assertNotEqual(expected_vars, config_vars)
_osx_support._remove_original_values(config_vars)
self.assertEqual(expected_vars, config_vars)
def test__save_modified_value(self):
config_vars = {
'CC': 'gcc-test -pthreads',
}
expected_vars = {
'CC': 'clang -pthreads',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
cv = 'CC'
newvalue = 'clang -pthreads'
_osx_support._save_modified_value(config_vars, cv, newvalue)
self.assertEqual(expected_vars, config_vars)
def test__save_modified_value_unchanged(self):
config_vars = {
'CC': 'gcc-test -pthreads',
}
expected_vars = config_vars.copy()
cv = 'CC'
newvalue = 'gcc-test -pthreads'
_osx_support._save_modified_value(config_vars, cv, newvalue)
self.assertEqual(expected_vars, config_vars)
def test__supports_universal_builds(self):
import platform
mac_ver_tuple = tuple(int(i) for i in
platform.mac_ver()[0].split('.')[0:2])
self.assertEqual(mac_ver_tuple >= (10, 4),
_osx_support._supports_universal_builds())
def test__find_appropriate_compiler(self):
compilers = (
('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
('clang', 'clang version 3.1'),
)
config_vars = {
'CC': 'gcc-test -pthreads',
'CXX': 'cc++-test',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CC': 'clang -pthreads',
'CXX': 'clang++',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
for c_name, c_output in compilers:
os_helper.unlink(c_name)
self.addCleanup(os_helper.unlink, c_name)
with open(c_name, 'w') as f:
f.write("#!/bin/sh\n/bin/echo " + c_output)
os.chmod(c_name, stat.S_IRWXU)
self.assertEqual(expected_vars,
_osx_support._find_appropriate_compiler(
config_vars))
def test__remove_universal_flags(self):
config_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
'LDFLAGS': ' -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -g',
'LDSHARED': 'gcc-4.0 -bundle -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._remove_universal_flags(
config_vars))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test__remove_universal_flags_alternate(self):
# bpo-38360: also test the alternate single-argument form of -isysroot
config_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
'LDFLAGS': ' -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -g',
'LDSHARED': 'gcc-4.0 -bundle -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._remove_universal_flags(
config_vars))
def test__remove_unsupported_archs(self):
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch i386 ',
'LDFLAGS': ' -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
c_name = 'clang'
os_helper.unlink(c_name)
self.addCleanup(os_helper.unlink, c_name)
# exit status 255 means no PPC support in this compiler chain
with open(c_name, 'w') as f:
f.write("#!/bin/sh\nexit 255")
os.chmod(c_name, stat.S_IRWXU)
self.assertEqual(expected_vars,
_osx_support._remove_unsupported_archs(
config_vars))
def test__override_all_archs(self):
self.env['ARCHFLAGS'] = '-arch x86_64'
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch x86_64',
'LDFLAGS': ' -g -arch x86_64',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -g -arch x86_64',
'LDSHARED': 'gcc-4.0 -bundle -isysroot '
'/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._override_all_archs(
config_vars))
def test__check_for_unavailable_sdk(self):
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
' ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
' -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._check_for_unavailable_sdk(
config_vars))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test__check_for_unavailable_sdk_alternate(self):
# bpo-38360: also test the alternate single-argument form of -isysroot
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
'-isysroot/Developer/SDKs/MacOSX10.1.sdk',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot/Developer/SDKs/MacOSX10.1.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
' ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
' -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._check_for_unavailable_sdk(
config_vars))
def test_get_platform_osx(self):
# Note, get_platform_osx is currently tested more extensively
# indirectly by test_sysconfig and test_distutils
config_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
'MACOSX_DEPLOYMENT_TARGET': '10.6',
}
result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
self.assertEqual(('macosx', '10.6', 'fat'), result)
if __name__ == "__main__":
unittest.main()
"""
Test suite for _osx_support: shared OS X support functions.
"""
import os
import platform
import stat
import sys
import unittest
from test.support import os_helper
import _osx_support
@unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
class Test_OSXSupport(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.prog_name = 'bogus_program_xxxx'
self.temp_path_dir = os.path.abspath(os.getcwd())
self.env = os_helper.EnvironmentVarGuard()
self.addCleanup(self.env.__exit__)
for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
if cv in self.env:
self.env.unset(cv)
def add_expected_saved_initial_values(self, config_vars, expected_vars):
# Ensure that the initial values for all modified config vars
# are also saved with modified keys.
expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
config_vars[k]) for k in config_vars
if config_vars[k] != expected_vars[k])
def test__find_executable(self):
if self.env['PATH']:
self.env['PATH'] = self.env['PATH'] + ':'
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
os_helper.unlink(self.prog_name)
self.assertIsNone(_osx_support._find_executable(self.prog_name))
self.addCleanup(os_helper.unlink, self.prog_name)
with open(self.prog_name, 'w') as f:
f.write("#!/bin/sh\n/bin/echo OK\n")
os.chmod(self.prog_name, stat.S_IRWXU)
self.assertEqual(self.prog_name,
_osx_support._find_executable(self.prog_name))
def test__read_output(self):
if self.env['PATH']:
self.env['PATH'] = self.env['PATH'] + ':'
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
os_helper.unlink(self.prog_name)
self.addCleanup(os_helper.unlink, self.prog_name)
with open(self.prog_name, 'w') as f:
f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
os.chmod(self.prog_name, stat.S_IRWXU)
self.assertEqual('ExpectedOutput',
_osx_support._read_output(self.prog_name))
def test__find_build_tool(self):
out = _osx_support._find_build_tool('cc')
self.assertTrue(os.path.isfile(out),
'cc not found - check xcode-select')
def test__get_system_version(self):
self.assertTrue(platform.mac_ver()[0].startswith(
_osx_support._get_system_version()))
def test__remove_original_values(self):
config_vars = {
'CC': 'gcc-test -pthreads',
}
expected_vars = {
'CC': 'clang -pthreads',
}
cv = 'CC'
newvalue = 'clang -pthreads'
_osx_support._save_modified_value(config_vars, cv, newvalue)
self.assertNotEqual(expected_vars, config_vars)
_osx_support._remove_original_values(config_vars)
self.assertEqual(expected_vars, config_vars)
def test__save_modified_value(self):
config_vars = {
'CC': 'gcc-test -pthreads',
}
expected_vars = {
'CC': 'clang -pthreads',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
cv = 'CC'
newvalue = 'clang -pthreads'
_osx_support._save_modified_value(config_vars, cv, newvalue)
self.assertEqual(expected_vars, config_vars)
def test__save_modified_value_unchanged(self):
config_vars = {
'CC': 'gcc-test -pthreads',
}
expected_vars = config_vars.copy()
cv = 'CC'
newvalue = 'gcc-test -pthreads'
_osx_support._save_modified_value(config_vars, cv, newvalue)
self.assertEqual(expected_vars, config_vars)
def test__supports_universal_builds(self):
import platform
mac_ver_tuple = tuple(int(i) for i in
platform.mac_ver()[0].split('.')[0:2])
self.assertEqual(mac_ver_tuple >= (10, 4),
_osx_support._supports_universal_builds())
def test__find_appropriate_compiler(self):
compilers = (
('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
('clang', 'clang version 3.1'),
)
config_vars = {
'CC': 'gcc-test -pthreads',
'CXX': 'cc++-test',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CC': 'clang -pthreads',
'CXX': 'clang++',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
for c_name, c_output in compilers:
os_helper.unlink(c_name)
self.addCleanup(os_helper.unlink, c_name)
with open(c_name, 'w') as f:
f.write("#!/bin/sh\n/bin/echo " + c_output)
os.chmod(c_name, stat.S_IRWXU)
self.assertEqual(expected_vars,
_osx_support._find_appropriate_compiler(
config_vars))
def test__remove_universal_flags(self):
config_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
'LDFLAGS': ' -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -g',
'LDSHARED': 'gcc-4.0 -bundle -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._remove_universal_flags(
config_vars))
def test__remove_universal_flags_alternate(self):
# bpo-38360: also test the alternate single-argument form of -isysroot
config_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
'LDFLAGS': ' -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -g',
'LDSHARED': 'gcc-4.0 -bundle -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._remove_universal_flags(
config_vars))
def test__remove_unsupported_archs(self):
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch i386 ',
'LDFLAGS': ' -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
c_name = 'clang'
os_helper.unlink(c_name)
self.addCleanup(os_helper.unlink, c_name)
# exit status 255 means no PPC support in this compiler chain
with open(c_name, 'w') as f:
f.write("#!/bin/sh\nexit 255")
os.chmod(c_name, stat.S_IRWXU)
self.assertEqual(expected_vars,
_osx_support._remove_unsupported_archs(
config_vars))
def test__override_all_archs(self):
self.env['ARCHFLAGS'] = '-arch x86_64'
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch x86_64',
'LDFLAGS': ' -g -arch x86_64',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -g -arch x86_64',
'LDSHARED': 'gcc-4.0 -bundle -isysroot '
'/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._override_all_archs(
config_vars))
def test__check_for_unavailable_sdk(self):
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
' ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
' -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._check_for_unavailable_sdk(
config_vars))
def test__check_for_unavailable_sdk_alternate(self):
# bpo-38360: also test the alternate single-argument form of -isysroot
config_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
'-isysroot/Developer/SDKs/MacOSX10.1.sdk',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
'-isysroot/Developer/SDKs/MacOSX10.1.sdk -g',
}
expected_vars = {
'CC': 'clang',
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
' ',
'LDFLAGS': '-arch ppc -arch i386 -g',
'CPPFLAGS': '-I. ',
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
' -g',
}
self.add_expected_saved_initial_values(config_vars, expected_vars)
self.assertEqual(expected_vars,
_osx_support._check_for_unavailable_sdk(
config_vars))
def test_get_platform_osx(self):
# Note, get_platform_osx is currently tested more extensively
# indirectly by test_sysconfig and test_distutils
config_vars = {
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
'MACOSX_DEPLOYMENT_TARGET': '10.6',
}
result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
self.assertEqual(('macosx', '10.6', 'fat'), result)
if __name__ == "__main__":
unittest.main()
+102 -121
View File
@@ -2,15 +2,16 @@
Roger E. Masse
"""
import collections.abc
import unittest
from test import support
from test.support import _2G, os_helper
from test.support import os_helper
from test.support import _2G
import weakref
import pickle
import operator
import struct
import sys
import warnings
import array
from array import _array_reconstructor as array_reconstructor
@@ -29,12 +30,31 @@ typecodes = 'ubBhHiIlLfdqQ'
class MiscTest(unittest.TestCase):
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_array_is_sequence(self):
self.assertIsInstance(array.array("B"), collections.abc.MutableSequence)
self.assertIsInstance(array.array("B"), collections.abc.Reversible)
def test_bad_constructor(self):
self.assertRaises(TypeError, array.array)
self.assertRaises(TypeError, array.array, spam=42)
self.assertRaises(TypeError, array.array, 'xx')
self.assertRaises(ValueError, array.array, 'x')
@support.cpython_only
def test_disallow_instantiation(self):
my_array = array.array("I")
support.check_disallow_instantiation(
self, type(iter(my_array)), my_array
)
@support.cpython_only
def test_immutable(self):
# bpo-43908: check that array.array is immutable
with self.assertRaises(TypeError):
array.array.foo = 1
def test_empty(self):
# Exercise code for handling zero-length arrays
a = array.array('B')
@@ -335,6 +355,69 @@ class BaseTest:
self.assertEqual(list(empit), [self.outside])
self.assertEqual(list(a), list(self.example) + [self.outside])
def test_reverse_iterator(self):
a = array.array(self.typecode, self.example)
self.assertEqual(list(a), list(self.example))
self.assertEqual(list(reversed(a)), list(iter(a))[::-1])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_reverse_iterator_picking(self):
orig = array.array(self.typecode, self.example)
data = list(orig)
data2 = [self.outside] + data
rev_data = data[len(data)-2::-1] + [self.outside]
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
# initial iterator
itorig = reversed(orig)
d = pickle.dumps((itorig, orig), proto)
it, a = pickle.loads(d)
a.insert(0, self.outside)
self.assertEqual(type(it), type(itorig))
self.assertEqual(list(it), rev_data)
self.assertEqual(list(a), data2)
# running iterator
next(itorig)
d = pickle.dumps((itorig, orig), proto)
it, a = pickle.loads(d)
a.insert(0, self.outside)
self.assertEqual(type(it), type(itorig))
self.assertEqual(list(it), rev_data[1:])
self.assertEqual(list(a), data2)
# empty iterator
for i in range(1, len(data)):
next(itorig)
d = pickle.dumps((itorig, orig), proto)
it, a = pickle.loads(d)
a.insert(0, self.outside)
self.assertEqual(type(it), type(itorig))
self.assertEqual(list(it), [])
self.assertEqual(list(a), data2)
# exhausted iterator
self.assertRaises(StopIteration, next, itorig)
d = pickle.dumps((itorig, orig), proto)
it, a = pickle.loads(d)
a.insert(0, self.outside)
self.assertEqual(list(it), [])
self.assertEqual(list(a), data2)
def test_exhausted_reverse_iterator(self):
a = array.array(self.typecode, self.example)
self.assertEqual(list(a), list(self.example))
exhit = reversed(a)
empit = reversed(a)
for x in exhit: # exhaust the iterator
next(empit) # Pointing past the 0th position.
a.insert(0, self.outside)
self.assertEqual(list(exhit), [])
# The iterator index points past the 0th position so inserting
# an element in the beginning does not make it appear.
self.assertEqual(list(empit), [])
self.assertEqual(list(a), [self.outside] + list(self.example))
def test_insert(self):
a = array.array(self.typecode, self.example)
a.insert(0, self.example[0])
@@ -430,28 +513,6 @@ class BaseTest:
b.fromlist(a.tolist())
self.assertEqual(a, b)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_tofromstring(self):
# Warnings not raised when arguments are incorrect as Argument Clinic
# handles that before the warning can be raised.
nb_warnings = 2
with warnings.catch_warnings(record=True) as r:
warnings.filterwarnings("always",
message=r"(to|from)string\(\) is deprecated",
category=DeprecationWarning)
a = array.array(self.typecode, 2*self.example)
b = array.array(self.typecode)
self.assertRaises(TypeError, a.tostring, 42)
self.assertRaises(TypeError, b.fromstring)
self.assertRaises(TypeError, b.fromstring, 42)
b.fromstring(a.tostring())
self.assertEqual(a, b)
if a.itemsize>1:
self.assertRaises(ValueError, b.fromstring, "x")
nb_warnings += 1
self.assertEqual(len(r), nb_warnings)
def test_tofrombytes(self):
a = array.array(self.typecode, 2*self.example)
b = array.array(self.typecode)
@@ -869,6 +930,8 @@ class BaseTest:
del a[start:stop:step]
self.assertEqual(a, array.array(self.typecode, L))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_index(self):
example = 2*self.example
a = array.array(self.typecode, example)
@@ -878,6 +941,17 @@ class BaseTest:
self.assertRaises(ValueError, a.index, None)
self.assertRaises(ValueError, a.index, self.outside)
a = array.array('i', [-2, -1, 0, 0, 1, 2])
self.assertEqual(a.index(0), 2)
self.assertEqual(a.index(0, 2), 2)
self.assertEqual(a.index(0, -4), 2)
self.assertEqual(a.index(-2, -10), 0)
self.assertEqual(a.index(0, 3), 3)
self.assertEqual(a.index(0, -3), 3)
self.assertEqual(a.index(0, 3, 4), 3)
self.assertEqual(a.index(0, -3, -2), 3)
self.assertRaises(ValueError, a.index, 2, 0, -10)
def test_count(self):
example = 2*self.example
a = array.array(self.typecode, example)
@@ -1033,6 +1107,7 @@ class BaseTest:
p = weakref.proxy(s)
self.assertEqual(p.tobytes(), s.tobytes())
s = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, len, p)
@unittest.skipUnless(hasattr(sys, 'getrefcount'),
@@ -1111,105 +1186,11 @@ class UnicodeTest(StringTest, unittest.TestCase):
outside = str('\x33')
minitemsize = 2
def test_add(self):
super().test_add()
def test_buffer(self):
super().test_buffer()
def test_buffer_info(self):
super().test_buffer_info()
def test_byteswap(self):
super().test_byteswap()
def test_cmp(self):
super().test_cmp()
def test_constructor(self):
super().test_constructor()
def test_constructor_with_iterable_argument(self):
super().test_constructor_with_iterable_argument()
def test_copy(self):
super().test_copy()
def test_count(self):
super().test_count()
def test_coveritertraverse(self):
super().test_coveritertraverse()
def test_deepcopy(self):
super().test_deepcopy()
def test_delitem(self):
super().test_delitem()
def test_exhausted_iterator(self):
super().test_exhausted_iterator()
def test_extend(self):
super().test_extend()
def test_extended_getslice(self):
super().test_extended_getslice()
def test_extended_set_del_slice(self):
super().test_extended_set_del_slice()
def test_fromarray(self):
super().test_fromarray()
def test_getitem(self):
super().test_getitem()
def test_getslice(self):
super().test_getslice()
def test_iadd(self):
super().test_iadd()
def test_imul(self):
super().test_imul()
def test_index(self):
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_index(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_index()
def test_insert(self):
super().test_insert()
def test_len(self):
super().test_len()
def test_mul(self):
super().test_mul()
def test_pop(self):
super().test_pop()
def test_remove(self):
super().test_remove()
def test_repr(self):
super().test_repr()
def test_reverse(self):
super().test_reverse()
def test_setslice(self):
super().test_setslice()
def test_str(self):
super().test_str()
def test_tofrombytes(self):
super().test_tofrombytes()
def test_tofromlist(self):
super().test_tofromlist()
def test_unicode(self):
self.assertRaises(TypeError, array.array, 'b', 'foo')
+20 -16
View File
@@ -1,7 +1,6 @@
# Test properties of bool promised by PEP 285
import unittest
from test import support
from test.support import os_helper
import os
@@ -21,20 +20,11 @@ class BoolTest(unittest.TestCase):
self.assertRaises(TypeError, int.__new__, bool, 0)
def test_print(self):
try:
with open(os_helper.TESTFN, "w") as fo:
print(False, True, file=fo)
with open(os_helper.TESTFN, "r") as fi:
self.assertEqual(fi.read(), 'False True\n')
finally:
os.remove(os_helper.TESTFN)
def test_repr(self):
self.assertEqual(repr(False), 'False')
self.assertEqual(repr(True), 'True')
self.assertEqual(eval(repr(False)), False)
self.assertEqual(eval(repr(True)), True)
self.assertIs(eval(repr(False)), False)
self.assertIs(eval(repr(True)), True)
def test_str(self):
self.assertEqual(str(False), 'False')
@@ -246,7 +236,7 @@ class BoolTest(unittest.TestCase):
def test_fileclosed(self):
try:
with open(os_helper.TESTFN, "w") as f:
with open(os_helper.TESTFN, "w", encoding="utf-8") as f:
self.assertIs(f.closed, False)
self.assertIs(f.closed, True)
finally:
@@ -365,8 +355,22 @@ class BoolTest(unittest.TestCase):
self.assertIs(type(False.real), int)
self.assertIs(type(False.imag), int)
def test_main():
support.run_unittest(BoolTest)
def test_bool_called_at_least_once(self):
class X:
def __init__(self):
self.count = 0
def __bool__(self):
self.count += 1
return True
def f(x):
if x or True:
pass
x = X()
f(x)
self.assertGreaterEqual(x.count, 1)
if __name__ == "__main__":
test_main()
unittest.main()
+311 -84
View File
@@ -1,10 +1,12 @@
# Python test set -- built-in functions
import ast
import asyncio
import builtins
import collections
import decimal
import fractions
import gc
import io
import locale
import os
@@ -17,13 +19,18 @@ import traceback
import types
import unittest
import warnings
from functools import partial
from contextlib import ExitStack
from functools import partial
from inspect import CO_COROUTINE
from itertools import product
from textwrap import dedent
from types import AsyncGeneratorType, FunctionType
from operator import neg
from test.support import swap_attr
from test.support.warnings_helper import check_warnings
from test import support
from test.support import (swap_attr, maybe_get_event_loop_policy)
from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink)
from test.support.script_helper import assert_python_ok
from test.support.os_helper import EnvironmentVarGuard, TESTFN, unlink
from test.support.warnings_helper import check_warnings
from unittest.mock import MagicMock, patch
try:
import pty, signal
@@ -146,6 +153,8 @@ class BuiltinTest(unittest.TestCase):
it = pickle.loads(d)
self.assertEqual(list(it), seq[1:])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_import(self):
__import__('sys')
__import__('time')
@@ -156,6 +165,11 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
self.assertRaises(ValueError, __import__, '')
self.assertRaises(TypeError, __import__, 'sys', name='sys')
# Relative import outside of a package with no __package__ or __spec__ (bpo-37409).
with self.assertWarns(ImportWarning):
self.assertRaises(ImportError, __import__, '',
{'__package__': None, '__spec__': None, '__name__': '__main__'},
locals={}, fromlist=('foo',), level=1)
# embedded null character
self.assertRaises(ModuleNotFoundError, __import__, 'string\x00')
@@ -320,8 +334,8 @@ class BuiltinTest(unittest.TestCase):
bom = b'\xef\xbb\xbf'
compile(bom + b'print(1)\n', '', 'exec')
compile(source='pass', filename='?', mode='exec')
compile(dont_inherit=0, filename='tmp', source='0', mode='eval')
compile('pass', '?', dont_inherit=1, mode='exec')
compile(dont_inherit=False, filename='tmp', source='0', mode='eval')
compile('pass', '?', dont_inherit=True, mode='exec')
compile(memoryview(b"text"), "name", "exec")
self.assertRaises(TypeError, compile)
self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'badmode')
@@ -364,6 +378,147 @@ class BuiltinTest(unittest.TestCase):
rv = ns['f']()
self.assertEqual(rv, tuple(expected))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compile_top_level_await_no_coro(self):
"""Make sure top level non-await codes get the correct coroutine flags"""
modes = ('single', 'exec')
code_samples = [
'''def f():pass\n''',
'''[x for x in l]''',
'''{x for x in l}''',
'''(x for x in l)''',
'''{x:x for x in l}''',
]
for mode, code_sample in product(modes, code_samples):
source = dedent(code_sample)
co = compile(source,
'?',
mode,
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
self.assertNotEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE,
msg=f"source={source} mode={mode}")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compile_top_level_await(self):
"""Test whether code some top level await can be compiled.
Make sure it compiles only with the PyCF_ALLOW_TOP_LEVEL_AWAIT flag
set, and make sure the generated code object has the CO_COROUTINE flag
set in order to execute it with `await eval(.....)` instead of exec,
or via a FunctionType.
"""
# helper function just to check we can run top=level async-for
async def arange(n):
for i in range(n):
yield i
modes = ('single', 'exec')
code_samples = [
'''a = await asyncio.sleep(0, result=1)''',
'''async for i in arange(1):
a = 1''',
'''async with asyncio.Lock() as l:
a = 1''',
'''a = [x async for x in arange(2)][1]''',
'''a = 1 in {x async for x in arange(2)}''',
'''a = {x:1 async for x in arange(1)}[0]''',
'''a = [x async for x in arange(2) async for x in arange(2)][1]''',
'''a = [x async for x in (x async for x in arange(5))][1]''',
'''a, = [1 for x in {x async for x in arange(1)}]''',
'''a = [await asyncio.sleep(0, x) async for x in arange(2)][1]'''
]
policy = maybe_get_event_loop_policy()
try:
for mode, code_sample in product(modes, code_samples):
source = dedent(code_sample)
with self.assertRaises(
SyntaxError, msg=f"source={source} mode={mode}"):
compile(source, '?', mode)
co = compile(source,
'?',
mode,
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
self.assertEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE,
msg=f"source={source} mode={mode}")
# test we can create and advance a function type
globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange}
async_f = FunctionType(co, globals_)
asyncio.run(async_f())
self.assertEqual(globals_['a'], 1)
# test we can await-eval,
globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange}
asyncio.run(eval(co, globals_))
self.assertEqual(globals_['a'], 1)
finally:
asyncio.set_event_loop_policy(policy)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compile_top_level_await_invalid_cases(self):
# helper function just to check we can run top=level async-for
async def arange(n):
for i in range(n):
yield i
modes = ('single', 'exec')
code_samples = [
'''def f(): await arange(10)\n''',
'''def f(): [x async for x in arange(10)]\n''',
'''def f(): [await x async for x in arange(10)]\n''',
'''def f():
async for i in arange(1):
a = 1
''',
'''def f():
async with asyncio.Lock() as l:
a = 1
'''
]
policy = maybe_get_event_loop_policy()
try:
for mode, code_sample in product(modes, code_samples):
source = dedent(code_sample)
with self.assertRaises(
SyntaxError, msg=f"source={source} mode={mode}"):
compile(source, '?', mode)
with self.assertRaises(
SyntaxError, msg=f"source={source} mode={mode}"):
co = compile(source,
'?',
mode,
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
finally:
asyncio.set_event_loop_policy(policy)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compile_async_generator(self):
"""
With the PyCF_ALLOW_TOP_LEVEL_AWAIT flag added in 3.8, we want to
make sure AsyncGenerators are still properly not marked with the
CO_COROUTINE flag.
"""
code = dedent("""async def ticker():
for i in range(10):
yield i
await asyncio.sleep(0)""")
co = compile(code, '?', 'exec', flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
glob = {}
exec(co, glob)
self.assertEqual(type(glob['ticker']()), AsyncGeneratorType)
def test_delattr(self):
sys.spam = 1
delattr(sys, 'spam')
@@ -442,8 +597,8 @@ class BuiltinTest(unittest.TestCase):
# dir(traceback)
try:
raise IndexError
except:
self.assertEqual(len(dir(sys.exc_info()[2])), 4)
except IndexError as e:
self.assertEqual(len(dir(e.__traceback__)), 4)
# test that object has a __dir__()
self.assertEqual(sorted([].__dir__()), dir([]))
@@ -664,66 +819,6 @@ class BuiltinTest(unittest.TestCase):
f2 = filter(filter_char, "abcdeabcde")
self.check_iter_pickle(f1, list(f2), proto)
def test_zip_pickle_strict(self):
a = (1, 2, 3)
b = (4, 5, 6)
t = [(1, 4), (2, 5), (3, 6)]
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
z1 = zip(a, b, strict=True)
self.check_iter_pickle(z1, t, proto)
def test_zip_pickle_strict_fail(self):
a = (1, 2, 3)
b = (4, 5, 6, 7)
t = [(1, 4), (2, 5), (3, 6)]
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
z1 = zip(a, b, strict=True)
z2 = pickle.loads(pickle.dumps(z1, proto))
self.assertEqual(self.iter_error(z1, ValueError), t)
self.assertEqual(self.iter_error(z2, ValueError), t)
def test_zip_pickle_stability(self):
# Pickles of zip((1, 2, 3), (4, 5, 6)) dumped from 3.9:
pickles = [
b'citertools\nizip\np0\n(c__builtin__\niter\np1\n((I1\nI2\nI3\ntp2\ntp3\nRp4\nI0\nbg1\n((I4\nI5\nI6\ntp5\ntp6\nRp7\nI0\nbtp8\nRp9\n.',
b'citertools\nizip\nq\x00(c__builtin__\niter\nq\x01((K\x01K\x02K\x03tq\x02tq\x03Rq\x04K\x00bh\x01((K\x04K\x05K\x06tq\x05tq\x06Rq\x07K\x00btq\x08Rq\t.',
b'\x80\x02citertools\nizip\nq\x00c__builtin__\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05K\x06\x87q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t.',
b'\x80\x03cbuiltins\nzip\nq\x00cbuiltins\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05K\x06\x87q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t.',
b'\x80\x04\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05K\x06\x87\x94\x85\x94R\x94K\x00b\x86\x94R\x94.',
b'\x80\x05\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05K\x06\x87\x94\x85\x94R\x94K\x00b\x86\x94R\x94.',
]
for protocol, dump in enumerate(pickles):
z1 = zip((1, 2, 3), (4, 5, 6))
z2 = zip((1, 2, 3), (4, 5, 6), strict=False)
z3 = pickle.loads(dump)
l3 = list(z3)
self.assertEqual(type(z3), zip)
self.assertEqual(pickle.dumps(z1, protocol), dump)
self.assertEqual(pickle.dumps(z2, protocol), dump)
self.assertEqual(list(z1), l3)
self.assertEqual(list(z2), l3)
def test_zip_pickle_strict_stability(self):
# Pickles of zip((1, 2, 3), (4, 5), strict=True) dumped from 3.10:
pickles = [
b'citertools\nizip\np0\n(c__builtin__\niter\np1\n((I1\nI2\nI3\ntp2\ntp3\nRp4\nI0\nbg1\n((I4\nI5\ntp5\ntp6\nRp7\nI0\nbtp8\nRp9\nI01\nb.',
b'citertools\nizip\nq\x00(c__builtin__\niter\nq\x01((K\x01K\x02K\x03tq\x02tq\x03Rq\x04K\x00bh\x01((K\x04K\x05tq\x05tq\x06Rq\x07K\x00btq\x08Rq\tI01\nb.',
b'\x80\x02citertools\nizip\nq\x00c__builtin__\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05\x86q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t\x88b.',
b'\x80\x03cbuiltins\nzip\nq\x00cbuiltins\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05\x86q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t\x88b.',
b'\x80\x04\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05\x86\x94\x85\x94R\x94K\x00b\x86\x94R\x94\x88b.',
b'\x80\x05\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05\x86\x94\x85\x94R\x94K\x00b\x86\x94R\x94\x88b.',
]
a = (1, 2, 3)
b = (4, 5)
t = [(1, 4), (2, 5)]
for protocol, dump in enumerate(pickles):
z1 = zip(a, b, strict=True)
z2 = pickle.loads(dump)
self.assertEqual(pickle.dumps(z1, protocol), dump)
self.assertEqual(type(z2), zip)
self.assertEqual(self.iter_error(z1, ValueError), t)
self.assertEqual(self.iter_error(z2, ValueError), t)
def test_getattr(self):
self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
self.assertRaises(TypeError, getattr, sys, 1)
@@ -758,6 +853,7 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(hash('spam'), hash(b'spam'))
hash((0,1,2,3))
def f(): pass
hash(f)
self.assertRaises(TypeError, hash, [])
self.assertRaises(TypeError, hash, {})
# Bug 1536021: Allow hash to return long objects
@@ -931,6 +1027,8 @@ class BuiltinTest(unittest.TestCase):
m2 = map(map_char, "Is this the real life?")
self.check_iter_pickle(m1, list(m2), proto)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_max(self):
self.assertEqual(max('123123'), '3')
self.assertEqual(max(1, 2, 3), 3)
@@ -941,7 +1039,12 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(max(1, 2.0, 3), 3)
self.assertEqual(max(1.0, 2, 3), 3)
self.assertRaises(TypeError, max)
with self.assertRaisesRegex(
TypeError,
'max expected at least 1 argument, got 0'
):
max()
self.assertRaises(TypeError, max, 42)
self.assertRaises(ValueError, max, ())
class BadSeq:
@@ -985,6 +1088,8 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(max(data, key=f),
sorted(reversed(data), key=f)[-1])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_min(self):
self.assertEqual(min('123123'), '1')
self.assertEqual(min(1, 2, 3), 1)
@@ -995,7 +1100,12 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(min(1, 2.0, 3), 1)
self.assertEqual(min(1.0, 2, 3), 1.0)
self.assertRaises(TypeError, min)
with self.assertRaisesRegex(
TypeError,
'min expected at least 1 argument, got 0'
):
min()
self.assertRaises(TypeError, min, 42)
self.assertRaises(ValueError, min, ())
class BadSeq:
@@ -1073,7 +1183,7 @@ class BuiltinTest(unittest.TestCase):
def write_testfile(self):
# NB the first 4 lines are also used to test input, below
fp = open(TESTFN, 'w')
fp = open(TESTFN, 'w', encoding="utf-8")
self.addCleanup(unlink, TESTFN)
with fp:
fp.write('1+1\n')
@@ -1085,7 +1195,7 @@ class BuiltinTest(unittest.TestCase):
def test_open(self):
self.write_testfile()
fp = open(TESTFN, 'r')
fp = open(TESTFN, encoding="utf-8")
with fp:
self.assertEqual(fp.readline(4), '1+1\n')
self.assertEqual(fp.readline(), 'The quick brown fox jumps over the lazy dog.\n')
@@ -1113,7 +1223,9 @@ class BuiltinTest(unittest.TestCase):
self.write_testfile()
current_locale_encoding = locale.getpreferredencoding(False)
fp = open(TESTFN, 'w')
with warnings.catch_warnings():
warnings.simplefilter("ignore", EncodingWarning)
fp = open(TESTFN, 'w')
with fp:
self.assertEqual(fp.encoding, current_locale_encoding)
finally:
@@ -1122,7 +1234,7 @@ class BuiltinTest(unittest.TestCase):
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON Windows')
def test_open_non_inheritable(self):
fileobj = open(__file__)
fileobj = open(__file__, encoding="utf-8")
with fileobj:
self.assertFalse(os.get_inheritable(fileobj.fileno()))
@@ -1217,7 +1329,7 @@ class BuiltinTest(unittest.TestCase):
def test_input(self):
self.write_testfile()
fp = open(TESTFN, 'r')
fp = open(TESTFN, encoding="utf-8")
savestdin = sys.stdin
savestdout = sys.stdout # Eats the echo
try:
@@ -1387,6 +1499,24 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(sum(range(10), 1000), 1045)
self.assertEqual(sum(range(10), start=1000), 1045)
self.assertEqual(sum(range(10), 2**31-5), 2**31+40)
self.assertEqual(sum(range(10), 2**63-5), 2**63+40)
self.assertEqual(sum(i % 2 != 0 for i in range(10)), 5)
self.assertEqual(sum((i % 2 != 0 for i in range(10)), 2**31-3),
2**31+2)
self.assertEqual(sum((i % 2 != 0 for i in range(10)), 2**63-3),
2**63+2)
self.assertIs(sum([], False), False)
self.assertEqual(sum(i / 2 for i in range(10)), 22.5)
self.assertEqual(sum((i / 2 for i in range(10)), 1000), 1022.5)
self.assertEqual(sum((i / 2 for i in range(10)), 1000.25), 1022.75)
self.assertEqual(sum([0.5, 1]), 1.5)
self.assertEqual(sum([1, 0.5]), 1.5)
self.assertEqual(repr(sum([-0.0])), '0.0')
self.assertEqual(repr(sum([-0.0], -0.0)), '-0.0')
self.assertEqual(repr(sum([], -0.0)), '-0.0')
self.assertRaises(TypeError, sum)
self.assertRaises(TypeError, sum, 42)
@@ -1398,6 +1528,9 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(TypeError, sum, [[1], [2], [3]])
self.assertRaises(TypeError, sum, [{2:3}])
self.assertRaises(TypeError, sum, [{2:3}]*2, {2:3})
self.assertRaises(TypeError, sum, [], '')
self.assertRaises(TypeError, sum, [], b'')
self.assertRaises(TypeError, sum, [], bytearray())
class BadSeq:
def __getitem__(self, index):
@@ -1499,6 +1632,36 @@ class BuiltinTest(unittest.TestCase):
z1 = zip(a, b)
self.check_iter_pickle(z1, t, proto)
def test_zip_pickle_strict(self):
a = (1, 2, 3)
b = (4, 5, 6)
t = [(1, 4), (2, 5), (3, 6)]
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
z1 = zip(a, b, strict=True)
self.check_iter_pickle(z1, t, proto)
def test_zip_pickle_strict_fail(self):
a = (1, 2, 3)
b = (4, 5, 6, 7)
t = [(1, 4), (2, 5), (3, 6)]
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
z1 = zip(a, b, strict=True)
z2 = pickle.loads(pickle.dumps(z1, proto))
self.assertEqual(self.iter_error(z1, ValueError), t)
self.assertEqual(self.iter_error(z2, ValueError), t)
def test_zip_bad_iterable(self):
exception = TypeError()
class BadIterable:
def __iter__(self):
raise exception
with self.assertRaises(TypeError) as cm:
zip(BadIterable())
self.assertIs(cm.exception, exception)
def test_zip_strict(self):
self.assertEqual(tuple(zip((1, 2, 3), 'abc', strict=True)),
((1, 'a'), (2, 'b'), (3, 'c')))
@@ -1581,6 +1744,18 @@ class BuiltinTest(unittest.TestCase):
l8 = self.iter_error(zip(Iter(3), "AB", strict=True), ValueError)
self.assertEqual(l8, [(2, "A"), (1, "B")])
@support.cpython_only
def test_zip_result_gc(self):
# bpo-42536: zip's tuple-reuse speed trick breaks the GC's assumptions
# about what can be untracked. Make sure we re-track result tuples
# whenever we reuse them.
it = zip([[]])
gc.collect()
# That GC collection probably untracked the recycled internal result
# tuple, which is initialized to (None,). Make sure it's re-tracked when
# it's mutated and returned from __next__:
self.assertTrue(gc.is_tracked(next(it)))
def test_format(self):
# Test the basic machinery of the format() builtin. Don't test
# the specifics of the various formatters
@@ -1696,6 +1871,11 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(ValueError, x.translate, b"1", 1)
self.assertRaises(TypeError, x.translate, b"1"*256, 1)
def test_bytearray_extend_error(self):
array = bytearray()
bad_iter = map(int, "X")
self.assertRaises(ValueError, array.extend, bad_iter)
def test_construct_singletons(self):
for const in None, Ellipsis, NotImplemented:
tp = type(const)
@@ -1703,6 +1883,22 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(TypeError, tp, 1, 2)
self.assertRaises(TypeError, tp, a=1, b=2)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_warning_notimplemented(self):
# Issue #35712: NotImplemented is a sentinel value that should never
# be evaluated in a boolean context (virtually all such use cases
# are a result of accidental misuse implementing rich comparison
# operations in terms of one another).
# For the time being, it will continue to evaluate as a true value, but
# issue a deprecation warning (with the eventual intent to make it
# a TypeError).
self.assertWarns(DeprecationWarning, bool, NotImplemented)
with self.assertWarns(DeprecationWarning):
self.assertTrue(NotImplemented)
with self.assertWarns(DeprecationWarning):
self.assertFalse(not NotImplemented)
@unittest.skip("TODO: RUSTPYTHON, AttributeError: module 'sys' has no attribute '__breakpointhook__'")
class TestBreakpoint(unittest.TestCase):
@@ -1815,7 +2011,21 @@ class PtyTests(unittest.TestCase):
"""Tests that use a pseudo terminal to guarantee stdin and stdout are
terminals in the test environment"""
@staticmethod
def handle_sighup(signum, frame):
# bpo-40140: if the process is the session leader, os.close(fd)
# of "pid, fd = pty.fork()" can raise SIGHUP signal:
# just ignore the signal.
pass
def run_child(self, child, terminal_input):
old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup)
try:
return self._run_child(child, terminal_input)
finally:
signal.signal(signal.SIGHUP, old_sighup)
def _run_child(self, child, terminal_input):
r, w = os.pipe() # Pipe test results from child back to parent
try:
pid, fd = pty.fork()
@@ -1824,6 +2034,7 @@ class PtyTests(unittest.TestCase):
os.close(w)
self.skipTest("pty.fork() raised {}".format(e))
raise
if pid == 0:
# Child
try:
@@ -1837,11 +2048,13 @@ class PtyTests(unittest.TestCase):
finally:
# We don't want to return to unittest...
os._exit(0)
# Parent
os.close(w)
os.write(fd, terminal_input)
# Get results from the pipe
with open(r, "r") as rpipe:
with open(r, encoding="utf-8") as rpipe:
lines = []
while True:
line = rpipe.readline().strip()
@@ -1849,6 +2062,7 @@ class PtyTests(unittest.TestCase):
# The other end was closed => the child exited
break
lines.append(line)
# Check the result was got and corresponds to the user's terminal input
if len(lines) != 2:
# Something went wrong, try to get at stderr
@@ -1866,10 +2080,12 @@ class PtyTests(unittest.TestCase):
child_output = child_output.decode("ascii", "ignore")
self.fail("got %d lines in pipe but expected 2, child output was:\n%s"
% (len(lines), child_output))
# bpo-40155: Close the PTY before waiting for the child process
# completion, otherwise the child process hangs on AIX.
os.close(fd)
# Wait until the child process completes
os.waitpid(pid, 0)
support.wait_process(pid, exitcode=0)
return lines
@@ -1904,12 +2120,24 @@ class PtyTests(unittest.TestCase):
# is different and invokes GNU readline if available).
self.check_input_tty("prompt", b"quux")
def skip_if_readline(self):
# bpo-13886: When the readline module is loaded, PyOS_Readline() uses
# the readline implementation. In some cases, the Python readline
# callback rlhandler() is called by readline with a string without
# non-ASCII characters. Skip tests on non-ASCII characters if the
# readline module is loaded, since test_builtin is not intented to test
# the readline module, but the builtins module.
if 'readline' in sys.modules:
self.skipTest("the readline module is loaded")
def test_input_tty_non_ascii(self):
# Check stdin/stdout encoding is used when invoking GNU readline
self.skip_if_readline()
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
self.check_input_tty("prompté", b"quux\xe9", "utf-8")
def test_input_tty_non_ascii_unicode_errors(self):
# Check stdin/stdout error handler is used when invoking GNU readline
self.skip_if_readline()
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
self.check_input_tty("prompté", b"quux\xe9", "ascii")
def test_input_no_stdout_fileno(self):
@@ -1941,7 +2169,7 @@ class TestSorted(unittest.TestCase):
self.assertEqual(data, sorted(copy, key=lambda x: -x))
self.assertNotEqual(data, copy)
random.shuffle(copy)
self.assertEqual(data, sorted(copy, reverse=1))
self.assertEqual(data, sorted(copy, reverse=True))
self.assertNotEqual(data, copy)
def test_bad_arguments(self):
@@ -2178,9 +2406,8 @@ class TestType(unittest.TestCase):
def load_tests(loader, tests, pattern):
# XXX RustPython
# from doctest import DocTestSuite
# tests.addTest(DocTestSuite(builtins))
from doctest import DocTestSuite
tests.addTest(DocTestSuite(builtins))
return tests
if __name__ == "__main__":
+26 -2
View File
@@ -16,9 +16,11 @@ import textwrap
import unittest
import test.support
from test.support import import_helper
from test.support import warnings_helper
import test.string_tests
import test.list_tests
from test.support import bigaddrspacetest, MAX_Py_ssize_t, import_helper, warnings_helper
from test.support import bigaddrspacetest, MAX_Py_ssize_t
from test.support.script_helper import assert_python_failure
@@ -1177,6 +1179,28 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
self.assertEqual(bytes(ba), b'ab')
self.assertRaises(TypeError, bytes, bb)
def test_repeat_id_preserving(self):
a = b'123abc1@'
b = b'456zyx-+'
self.assertEqual(id(a), id(a))
self.assertNotEqual(id(a), id(b))
self.assertNotEqual(id(a), id(a * -4))
self.assertNotEqual(id(a), id(a * 0))
self.assertEqual(id(a), id(a * 1))
self.assertEqual(id(a), id(1 * a))
self.assertNotEqual(id(a), id(a * 2))
class SubBytes(bytes):
pass
s = SubBytes(b'qwerty()')
self.assertEqual(id(s), id(s))
self.assertNotEqual(id(s), id(s * -4))
self.assertNotEqual(id(s), id(s * 0))
self.assertNotEqual(id(s), id(s * 1))
self.assertNotEqual(id(s), id(1 * s))
self.assertNotEqual(id(s), id(s * 2))
class ByteArrayTest(BaseBytesTest, unittest.TestCase):
type2test = bytearray
@@ -1799,7 +1823,7 @@ class AssortedBytesTest(unittest.TestCase):
"BytesWarning is needed for this test: use -bb option")
def test_compare(self):
def bytes_warning():
return test.warnings_helper.check_warningswarnings(('', BytesWarning))
return warnings_helper.check_warnings(('', BytesWarning))
with bytes_warning():
b'' == ''
with bytes_warning():
+1 -1
View File
@@ -534,7 +534,7 @@ class ClassTests(unittest.TestCase):
# In debug mode, printed XXX undetected error and
# raises AttributeError
I()
except AttributeError as x:
except AttributeError:
pass
else:
self.fail("attribute error for I.__init__ got masked")
+82 -44
View File
@@ -7,6 +7,7 @@ import inspect
import operator
import pickle
from random import choice, randrange
from itertools import product, chain, combinations
import string
import sys
from test import support
@@ -51,12 +52,18 @@ class TestUserObjects(unittest.TestCase):
self.assertEqual(obj.data, obj_copy.data)
self.assertIs(obj.test, obj_copy.test)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_str_protocol(self):
self._superset_test(UserString, str)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_list_protocol(self):
self._superset_test(UserList, list)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_dict_protocol(self):
self._superset_test(UserDict, dict)
@@ -248,6 +255,10 @@ class TestChainMap(unittest.TestCase):
for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
self.assertEqual(d.get(k, 100), v)
c = ChainMap({'a': 1, 'b': 2})
d = c.new_child(b=20, c=30)
self.assertEqual(d.maps, [{'b': 20, 'c': 30}, {'a': 1, 'b': 2}])
def test_union_operators(self):
cm1 = ChainMap(dict(a=1, b=2), dict(c=3, d=4))
cm2 = ChainMap(dict(a=10, e=5), dict(b=20, d=4))
@@ -663,8 +674,7 @@ class TestNamedTuple(unittest.TestCase):
a.w = 5
self.assertEqual(a.__dict__, {'w': 5})
# TODO: RUSTPYTHON
@unittest.expectedFailure
@support.cpython_only
def test_field_descriptor(self):
Point = namedtuple('Point', 'x y')
p = Point(11, 22)
@@ -682,10 +692,17 @@ class TestNamedTuple(unittest.TestCase):
self.assertEqual(np.x, 1)
self.assertEqual(np.y, 2)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_new_builtins_issue_43102(self):
self.assertEqual(
namedtuple('C', ()).__new__.__globals__['__builtins__'],
{})
obj = namedtuple('C', ())
new_func = obj.__new__
self.assertEqual(new_func.__globals__['__builtins__'], {})
self.assertEqual(new_func.__builtins__, {})
def test_match_args(self):
Point = namedtuple('Point', 'x y')
self.assertEqual(Point.__match_args__, ('x', 'y'))
################################################################################
@@ -1516,7 +1533,7 @@ class TestCollectionABCs(ABCTestCase):
items = [5,43,2,1]
s = MySet(items)
r = s.pop()
self.assertEquals(len(s), len(items) - 1)
self.assertEqual(len(s), len(items) - 1)
self.assertNotIn(r, s)
self.assertIn(r, items)
@@ -1566,10 +1583,6 @@ class TestCollectionABCs(ABCTestCase):
def test_issue26915(self):
# Container membership test should check identity first
class CustomEqualObject:
def __eq__(self, other):
return False
class CustomSequence(Sequence):
def __init__(self, seq):
self._seq = seq
@@ -1579,7 +1592,7 @@ class TestCollectionABCs(ABCTestCase):
return len(self._seq)
nan = float('nan')
obj = CustomEqualObject
obj = support.NEVER_EQ
seq = CustomSequence([nan, obj, nan])
containers = [
seq,
@@ -1599,7 +1612,7 @@ class TestCollectionABCs(ABCTestCase):
self.assertSetEqual(set(s1), set(s2))
def test_Set_from_iterable(self):
"""Verify _from_iterable overriden to an instance method works."""
"""Verify _from_iterable overridden to an instance method works."""
class SetUsingInstanceFromIterable(MutableSet):
def __init__(self, values, created_by):
if not created_by:
@@ -1994,6 +2007,14 @@ class TestCollectionABCs(ABCTestCase):
self.assertEqual(len(mss), len(mss2))
self.assertEqual(list(mss), list(mss2))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_illegal_patma_flags(self):
with self.assertRaises(TypeError):
class Both(Collection):
__abc_tpflags__ = (Sequence.__flags__ | Mapping.__flags__)
################################################################################
### Counter
@@ -2087,6 +2108,10 @@ class TestCounter(unittest.TestCase):
self.assertRaises(TypeError, Counter, (), ())
self.assertRaises(TypeError, Counter.__init__)
def test_total(self):
c = Counter(a=10, b=5, c=0)
self.assertEqual(c.total(), 15)
def test_order_preservation(self):
# Input order dictates items() order
self.assertEqual(list(Counter('abracadabra').items()),
@@ -2240,31 +2265,6 @@ class TestCounter(unittest.TestCase):
set_result = setop(set(p.elements()), set(q.elements()))
self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_subset_superset_not_implemented(self):
# Verify that multiset comparison operations are not implemented.
# These operations were intentionally omitted because multiset
# comparison semantics conflict with existing dict equality semantics.
# For multisets, we would expect that if p<=q and p>=q are both true,
# then p==q. However, dict equality semantics require that p!=q when
# one of sets contains an element with a zero count and the other
# doesn't.
p = Counter(a=1, b=0)
q = Counter(a=1, c=0)
self.assertNotEqual(p, q)
with self.assertRaises(TypeError):
p < q
with self.assertRaises(TypeError):
p <= q
with self.assertRaises(TypeError):
p > q
with self.assertRaises(TypeError):
p >= q
def test_inplace_operations(self):
elements = 'abcd'
for i in range(1000):
@@ -2339,23 +2339,61 @@ class TestCounter(unittest.TestCase):
self.assertTrue(c.called)
self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
def test_multiset_operations_equivalent_to_set_operations(self):
# When the multiplicities are all zero or one, multiset operations
# are guaranteed to be equivalent to the corresponding operations
# for regular sets.
s = list(product(('a', 'b', 'c'), range(2)))
powerset = chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
counters = [Counter(dict(groups)) for groups in powerset]
for cp, cq in product(counters, repeat=2):
sp = set(cp.elements())
sq = set(cq.elements())
self.assertEqual(set(cp + cq), sp | sq)
self.assertEqual(set(cp - cq), sp - sq)
self.assertEqual(set(cp | cq), sp | sq)
self.assertEqual(set(cp & cq), sp & sq)
self.assertEqual(cp == cq, sp == sq)
self.assertEqual(cp != cq, sp != sq)
self.assertEqual(cp <= cq, sp <= sq)
self.assertEqual(cp >= cq, sp >= sq)
self.assertEqual(cp < cq, sp < sq)
self.assertEqual(cp > cq, sp > sq)
def test_eq(self):
self.assertEqual(Counter(a=3, b=2, c=0), Counter('ababa'))
self.assertNotEqual(Counter(a=3, b=2), Counter('babab'))
def test_le(self):
self.assertTrue(Counter(a=3, b=2, c=0) <= Counter('ababa'))
self.assertFalse(Counter(a=3, b=2) <= Counter('babab'))
def test_lt(self):
self.assertTrue(Counter(a=3, b=1, c=0) < Counter('ababa'))
self.assertFalse(Counter(a=3, b=2, c=0) < Counter('ababa'))
def test_ge(self):
self.assertTrue(Counter(a=2, b=1, c=0) >= Counter('aab'))
self.assertFalse(Counter(a=3, b=2, c=0) >= Counter('aabd'))
def test_gt(self):
self.assertTrue(Counter(a=3, b=2, c=0) > Counter('aab'))
self.assertFalse(Counter(a=2, b=1, c=0) > Counter('aab'))
################################################################################
### Run tests
################################################################################
def test_main(verbose=None):
# TODO: RUSTPYTHON
# NamedTupleDocs = doctest.DocTestSuite(module=collections)
# test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
test_classes = [TestNamedTuple, TestOneTrickPonyABCs,
NamedTupleDocs = doctest.DocTestSuite(module=collections)
test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
TestCollectionABCs, TestCounter, TestChainMap,
TestUserObjects,
]
support.run_unittest(*test_classes)
# TODO: RUSTPYTHON
# support.run_doctest(collections, verbose)
support.run_doctest(collections, verbose)
if __name__ == "__main__":
test_main(verbose=True)
test_main(verbose=True)
+2 -7
View File
@@ -1,5 +1,6 @@
from collections import deque
import unittest
from test.support import NEVER_EQ
class base_set:
@@ -70,13 +71,7 @@ class TestContains(unittest.TestCase):
# containment and equality tests involving elements that are
# not necessarily equal to themselves
class MyNonReflexive(object):
def __eq__(self, other):
return False
def __hash__(self):
return 28
values = float('nan'), 1, None, 'abc', MyNonReflexive()
values = float('nan'), 1, None, 'abc', NEVER_EQ
constructors = list, tuple, dict.fromkeys, set, frozenset, deque
for constructor in constructors:
container = constructor(values)
+5783 -5720
View File
File diff suppressed because it is too large. Load diff
+40 -33
View File
@@ -72,27 +72,6 @@ class TestDefaultDict(unittest.TestCase):
d3[13]
self.assertEqual(repr(d3), "defaultdict(%s, {13: 43})" % repr(foo))
def test_print(self):
d1 = defaultdict()
def foo(): return 42
d2 = defaultdict(foo, {1: 2})
# NOTE: We can't use tempfile.[Named]TemporaryFile since this
# code must exercise the tp_print C code, which only gets
# invoked for *real* files.
tfn = tempfile.mktemp()
try:
f = open(tfn, "w+")
try:
print(d1, file=f)
print(d2, file=f)
f.seek(0)
self.assertEqual(f.readline(), repr(d1) + "\n")
self.assertEqual(f.readline(), repr(d2) + "\n")
finally:
f.close()
finally:
os.remove(tfn)
def test_copy(self):
d1 = defaultdict()
d2 = d1.copy()
@@ -160,18 +139,6 @@ class TestDefaultDict(unittest.TestCase):
r"sub\(<bound method .*sub\._factory "
r"of sub\(\.\.\., \{\}\)>, \{\}\)")
# NOTE: printing a subclass of a builtin type does not call its
# tp_print slot. So this part is essentially the same test as above.
tfn = tempfile.mktemp()
try:
f = open(tfn, "w+")
try:
print(d, file=f)
finally:
f.close()
finally:
os.remove(tfn)
def test_callable_arg(self):
self.assertRaises(TypeError, defaultdict, {})
@@ -183,5 +150,45 @@ class TestDefaultDict(unittest.TestCase):
o = pickle.loads(s)
self.assertEqual(d, o)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union(self):
i = defaultdict(int, {1: 1, 2: 2})
s = defaultdict(str, {0: "zero", 1: "one"})
i_s = i | s
self.assertIs(i_s.default_factory, int)
self.assertDictEqual(i_s, {1: "one", 2: 2, 0: "zero"})
self.assertEqual(list(i_s), [1, 2, 0])
s_i = s | i
self.assertIs(s_i.default_factory, str)
self.assertDictEqual(s_i, {0: "zero", 1: 1, 2: 2})
self.assertEqual(list(s_i), [0, 1, 2])
i_ds = i | dict(s)
self.assertIs(i_ds.default_factory, int)
self.assertDictEqual(i_ds, {1: "one", 2: 2, 0: "zero"})
self.assertEqual(list(i_ds), [1, 2, 0])
ds_i = dict(s) | i
self.assertIs(ds_i.default_factory, int)
self.assertDictEqual(ds_i, {0: "zero", 1: 1, 2: 2})
self.assertEqual(list(ds_i), [0, 1, 2])
with self.assertRaises(TypeError):
i | list(s.items())
with self.assertRaises(TypeError):
list(s.items()) | i
# We inherit a fine |= from dict, so just a few sanity checks here:
i |= list(s.items())
self.assertIs(i.default_factory, int)
self.assertDictEqual(i, {1: "one", 2: 2, 0: "zero"})
self.assertEqual(list(i), [1, 2, 0])
with self.assertRaises(TypeError):
i |= None
if __name__ == "__main__":
unittest.main()
+34 -39
View File
@@ -1,7 +1,6 @@
from collections import deque
import unittest
from test import support, seq_tests
from test.support import os_helper
import gc
import weakref
import copy
@@ -67,28 +66,9 @@ class TestBasic(unittest.TestCase):
self.assertEqual(list(d), [7, 8, 9])
d = deque(range(200), maxlen=10)
d.append(d)
os_helper.unlink(os_helper.TESTFN)
fo = open(os_helper.TESTFN, "w")
try:
fo.write(str(d))
fo.close()
fo = open(os_helper.TESTFN, "r")
self.assertEqual(fo.read(), repr(d))
finally:
fo.close()
os_helper.unlink(os_helper.TESTFN)
self.assertEqual(repr(d)[-30:], ', 198, 199, [...]], maxlen=10)')
d = deque(range(10), maxlen=None)
self.assertEqual(repr(d), 'deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])')
fo = open(os_helper.TESTFN, "w")
try:
fo.write(str(d))
fo.close()
fo = open(os_helper.TESTFN, "r")
self.assertEqual(fo.read(), repr(d))
finally:
fo.close()
os_helper.unlink(os_helper.TESTFN)
def test_maxlen_zero(self):
it = iter(range(100))
@@ -149,7 +129,8 @@ class TestBasic(unittest.TestCase):
self.assertEqual(d.count(None), 16)
def test_comparisons(self):
d = deque('xabc'); d.popleft()
d = deque('xabc')
d.popleft()
for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
self.assertEqual(d==e, type(d)==type(e) and list(d)==list(e))
self.assertEqual(d!=e, not(type(d)==type(e) and list(d)==list(e)))
@@ -184,6 +165,18 @@ class TestBasic(unittest.TestCase):
with self.assertRaises(RuntimeError):
n in d
def test_contains_count_stop_crashes(self):
class A:
def __eq__(self, other):
d.clear()
return NotImplemented
d = deque([A(), A()])
with self.assertRaises(RuntimeError):
_ = 3 in d
d = deque([A(), A()])
with self.assertRaises(RuntimeError):
_ = d.count(3)
def test_extend(self):
d = deque('a')
self.assertRaises(TypeError, d.extend, 1)
@@ -534,25 +527,11 @@ class TestBasic(unittest.TestCase):
e = eval(repr(d))
self.assertEqual(list(d), list(e))
d.append(d)
self.assertIn('...', repr(d))
def test_print(self):
d = deque(range(200))
d.append(d)
try:
os_helper.unlink(os_helper.TESTFN)
fo = open(os_helper.TESTFN, "w")
print(d, file=fo, end='')
fo.close()
fo = open(os_helper.TESTFN, "r")
self.assertEqual(fo.read(), repr(d))
finally:
fo.close()
os_helper.unlink(os_helper.TESTFN)
self.assertEqual(repr(d)[-20:], '7, 198, 199, [...]])')
def test_init(self):
self.assertRaises(TypeError, deque, 'abc', 2, 3);
self.assertRaises(TypeError, deque, 1);
self.assertRaises(TypeError, deque, 'abc', 2, 3)
self.assertRaises(TypeError, deque, 1)
def test_hash(self):
self.assertRaises(TypeError, hash, deque('abc'))
@@ -894,6 +873,7 @@ class TestSubclass(unittest.TestCase):
p = weakref.proxy(d)
self.assertEqual(str(p), str(d))
d = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, str, p)
def test_strange_subclass(self):
@@ -949,6 +929,21 @@ class TestSequence(seq_tests.CommonTest):
# For now, bypass tests that require slicing
self.skipTest("Exhausted deque iterator doesn't free a deque")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_contains_fake(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_contains_fake()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_count(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_count()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_index(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_index()
#==============================================================================
libreftest = """
+234 -3
View File
@@ -1,6 +1,6 @@
import collections
import collections.abc
# import gc // XXX RustPython
import gc
import pickle
import random
import string
@@ -37,6 +37,38 @@ class DictTest(unittest.TestCase):
dictliteral = '{' + ', '.join(formatted_items) + '}'
self.assertEqual(eval(dictliteral), dict(items))
def test_merge_operator(self):
a = {0: 0, 1: 1, 2: 1}
b = {1: 1, 2: 2, 3: 3}
c = a.copy()
c |= b
self.assertEqual(a | b, {0: 0, 1: 1, 2: 2, 3: 3})
self.assertEqual(c, {0: 0, 1: 1, 2: 2, 3: 3})
c = b.copy()
c |= a
self.assertEqual(b | a, {1: 1, 2: 1, 3: 3, 0: 0})
self.assertEqual(c, {1: 1, 2: 1, 3: 3, 0: 0})
c = a.copy()
c |= [(1, 1), (2, 2), (3, 3)]
self.assertEqual(c, {0: 0, 1: 1, 2: 2, 3: 3})
self.assertIs(a.__or__(None), NotImplemented)
self.assertIs(a.__or__(()), NotImplemented)
self.assertIs(a.__or__("BAD"), NotImplemented)
self.assertIs(a.__or__(""), NotImplemented)
self.assertRaises(TypeError, a.__ior__, None)
self.assertEqual(a.__ior__(()), {0: 0, 1: 1, 2: 1})
self.assertRaises(ValueError, a.__ior__, "BAD")
self.assertEqual(a.__ior__(""), {0: 0, 1: 1, 2: 1})
def test_bool(self):
self.assertIs(not {}, True)
self.assertTrue({1: 2})
@@ -73,6 +105,28 @@ class DictTest(unittest.TestCase):
self.assertRaises(TypeError, d.items, None)
self.assertEqual(repr(dict(a=1).items()), "dict_items([('a', 1)])")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_views_mapping(self):
mappingproxy = type(type.__dict__)
class Dict(dict):
pass
for cls in [dict, Dict]:
d = cls()
m1 = d.keys().mapping
m2 = d.values().mapping
m3 = d.items().mapping
for m in [m1, m2, m3]:
self.assertIsInstance(m, mappingproxy)
self.assertEqual(m, d)
d["foo"] = "bar"
for m in [m1, m2, m3]:
self.assertIsInstance(m, mappingproxy)
self.assertEqual(m, d)
def test_contains(self):
d = {}
self.assertNotIn('a', d)
@@ -668,6 +722,16 @@ class DictTest(unittest.TestCase):
self.assertEqual(k1 ^ k2, {(3,3)})
self.assertEqual(k1 ^ k3, {(1,1), (2,2), (4,4)})
def test_items_symmetric_difference(self):
rr = random.randrange
for _ in range(100):
left = {x:rr(3) for x in range(20) if rr(2)}
right = {x:rr(3) for x in range(20) if rr(2)}
with self.subTest(left=left, right=right):
expected = set(left.items()) ^ set(right.items())
actual = left.items() ^ right.items()
self.assertEqual(actual, expected)
def test_dictview_mixed_set_operations(self):
# Just a few for .keys()
self.assertTrue({1:1}.keys() == {1})
@@ -994,7 +1058,7 @@ class DictTest(unittest.TestCase):
@support.cpython_only
def test_splittable_pop_pending(self):
"""pop a pending key in a splitted table should not crash"""
"""pop a pending key in a split table should not crash"""
a, b = self.make_shared_key_dict(2)
a['a'] = 4
@@ -1230,7 +1294,7 @@ class DictTest(unittest.TestCase):
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_equal_operator_modifying_operand(self):
# test fix for seg fault reported in issue 27945 part 3.
# test fix for seg fault reported in bpo-27945 part 3.
class X():
def __del__(self):
dict_b.clear()
@@ -1246,6 +1310,16 @@ class DictTest(unittest.TestCase):
dict_b = {X(): X()}
self.assertTrue(dict_a == dict_b)
# test fix for seg fault reported in bpo-38588 part 1.
class Y:
def __eq__(self, other):
dict_d.clear()
return True
dict_c = {0: Y()}
dict_d = {0: set()}
self.assertTrue(dict_c == dict_d)
def test_fromkeys_operator_modifying_dict_operand(self):
# test fix for seg fault reported in issue 27945 part 4a.
class X(int):
@@ -1291,6 +1365,19 @@ class DictTest(unittest.TestCase):
d = {0: set()}
(0, X()) in d.items()
def test_dict_contain_use_after_free(self):
# bpo-40489
class S(str):
def __eq__(self, other):
d.clear()
return NotImplemented
def __hash__(self):
return hash('test')
d = {S(): 'value'}
self.assertFalse('test' in d)
def test_init_use_after_free(self):
class X:
def __hash__(self):
@@ -1321,6 +1408,31 @@ class DictTest(unittest.TestCase):
self.assertEqual(list(r), list('dcba'))
self.assertRaises(StopIteration, next, r)
def test_reverse_iterator_for_empty_dict(self):
# bpo-38525: reversed iterator should work properly
# empty dict is directly used for reference count test
self.assertEqual(list(reversed({})), [])
self.assertEqual(list(reversed({}.items())), [])
self.assertEqual(list(reversed({}.values())), [])
self.assertEqual(list(reversed({}.keys())), [])
# dict() and {} don't trigger the same code path
self.assertEqual(list(reversed(dict())), [])
self.assertEqual(list(reversed(dict().items())), [])
self.assertEqual(list(reversed(dict().values())), [])
self.assertEqual(list(reversed(dict().keys())), [])
def test_reverse_iterator_for_shared_shared_dicts(self):
class A:
def __init__(self, x, y):
if x: self.x = x
if y: self.y = y
self.assertEqual(list(reversed(A(1, 2).__dict__)), ['y', 'x'])
self.assertEqual(list(reversed(A(1, 0).__dict__)), ['x'])
self.assertEqual(list(reversed(A(0, 1).__dict__)), ['y'])
def test_dict_copy_order(self):
# bpo-34320
od = collections.OrderedDict([('a', 1), ('b', 2)])
@@ -1351,6 +1463,125 @@ class DictTest(unittest.TestCase):
d = CustomReversedDict(pairs)
self.assertEqual(pairs[::-1], list(dict(d).items()))
@support.cpython_only
def test_dict_items_result_gc(self):
# bpo-42536: dict.items's tuple-reuse speed trick breaks the GC's
# assumptions about what can be untracked. Make sure we re-track result
# tuples whenever we reuse them.
it = iter({None: []}.items())
gc.collect()
# That GC collection probably untracked the recycled internal result
# tuple, which is initialized to (None, None). Make sure it's re-tracked
# when it's mutated and returned from __next__:
self.assertTrue(gc.is_tracked(next(it)))
@support.cpython_only
def test_dict_items_result_gc_reversed(self):
# Same as test_dict_items_result_gc above, but reversed.
it = reversed({None: []}.items())
gc.collect()
self.assertTrue(gc.is_tracked(next(it)))
def test_str_nonstr(self):
# cpython uses a different lookup function if the dict only contains
# `str` keys. Make sure the unoptimized path is used when a non-`str`
# key appears.
class StrSub(str):
pass
eq_count = 0
# This class compares equal to the string 'key3'
class Key3:
def __hash__(self):
return hash('key3')
def __eq__(self, other):
nonlocal eq_count
if isinstance(other, Key3) or isinstance(other, str) and other == 'key3':
eq_count += 1
return True
return False
key3_1 = StrSub('key3')
key3_2 = Key3()
key3_3 = Key3()
dicts = []
# Create dicts of the form `{'key1': 42, 'key2': 43, key3: 44}` in a
# bunch of different ways. In all cases, `key3` is not of type `str`.
# `key3_1` is a `str` subclass and `key3_2` is a completely unrelated
# type.
for key3 in (key3_1, key3_2):
# A literal
dicts.append({'key1': 42, 'key2': 43, key3: 44})
# key3 inserted via `dict.__setitem__`
d = {'key1': 42, 'key2': 43}
d[key3] = 44
dicts.append(d)
# key3 inserted via `dict.setdefault`
d = {'key1': 42, 'key2': 43}
self.assertEqual(d.setdefault(key3, 44), 44)
dicts.append(d)
# key3 inserted via `dict.update`
d = {'key1': 42, 'key2': 43}
d.update({key3: 44})
dicts.append(d)
# key3 inserted via `dict.__ior__`
d = {'key1': 42, 'key2': 43}
d |= {key3: 44}
dicts.append(d)
# `dict(iterable)`
def make_pairs():
yield ('key1', 42)
yield ('key2', 43)
yield (key3, 44)
d = dict(make_pairs())
dicts.append(d)
# `dict.copy`
d = d.copy()
dicts.append(d)
# dict comprehension
d = {key: 42 + i for i,key in enumerate(['key1', 'key2', key3])}
dicts.append(d)
for d in dicts:
with self.subTest(d=d):
self.assertEqual(d.get('key1'), 42)
# Try to make an object that is of type `str` and is equal to
# `'key1'`, but (at least on cpython) is a different object.
noninterned_key1 = 'ke'
noninterned_key1 += 'y1'
if support.check_impl_detail(cpython=True):
# suppress a SyntaxWarning
interned_key1 = 'key1'
self.assertFalse(noninterned_key1 is interned_key1)
self.assertEqual(d.get(noninterned_key1), 42)
self.assertEqual(d.get('key3'), 44)
self.assertEqual(d.get(key3_1), 44)
self.assertEqual(d.get(key3_2), 44)
# `key3_3` itself is definitely not a dict key, so make sure
# that `__eq__` gets called.
#
# Note that this might not hold for `key3_1` and `key3_2`
# because they might be the same object as one of the dict keys,
# in which case implementations are allowed to skip the call to
# `__eq__`.
eq_count = 0
self.assertEqual(d.get(key3_3), 44)
self.assertGreaterEqual(eq_count, 1)
class CAPITest(unittest.TestCase):
+18 -1
View File
@@ -79,7 +79,7 @@ class DictComprehensionTest(unittest.TestCase):
compile("{x: y for y, x in ((1, 2), (3, 4))} = 5", "<test>",
"exec")
with self.assertRaisesRegex(SyntaxError, "cannot assign"):
with self.assertRaisesRegex(SyntaxError, "illegal expression"):
compile("{x: y for y, x in ((1, 2), (3, 4))} += 5", "<test>",
"exec")
@@ -113,5 +113,22 @@ class DictComprehensionTest(unittest.TestCase):
self.assertEqual(actual, expected)
self.assertEqual(actual_calls, expected_calls)
def test_assignment_idiom_in_comprehensions(self):
expected = {1: 1, 2: 4, 3: 9, 4: 16}
actual = {j: j*j for i in range(4) for j in [i+1]}
self.assertEqual(actual, expected)
expected = {3: 2, 5: 6, 7: 12, 9: 20}
actual = {j+k: j*k for i in range(4) for j in [i+1] for k in [j+1]}
self.assertEqual(actual, expected)
expected = {3: 2, 5: 6, 7: 12, 9: 20}
actual = {j+k: j*k for i in range(4) for j, k in [(i+1, i+2)]}
self.assertEqual(actual, expected)
def test_star_expression(self):
expected = {0: 0, 1: 1, 2: 4, 3: 9}
self.assertEqual({i: i*i for i in [*range(4)]}, expected)
self.assertEqual({i: i*i for i in (*range(4),)}, expected)
if __name__ == "__main__":
unittest.main()
+335 -290
View File
@@ -1,290 +1,335 @@
import collections.abc
import copy
import pickle
import sys
import unittest
class DictSetTest(unittest.TestCase):
def test_constructors_not_callable(self):
kt = type({}.keys())
self.assertRaises(TypeError, kt, {})
self.assertRaises(TypeError, kt)
it = type({}.items())
self.assertRaises(TypeError, it, {})
self.assertRaises(TypeError, it)
vt = type({}.values())
self.assertRaises(TypeError, vt, {})
self.assertRaises(TypeError, vt)
def test_dict_keys(self):
d = {1: 10, "a": "ABC"}
keys = d.keys()
self.assertEqual(len(keys), 2)
self.assertEqual(set(keys), {1, "a"})
self.assertEqual(keys, {1, "a"})
self.assertNotEqual(keys, {1, "a", "b"})
self.assertNotEqual(keys, {1, "b"})
self.assertNotEqual(keys, {1})
self.assertNotEqual(keys, 42)
self.assertIn(1, keys)
self.assertIn("a", keys)
self.assertNotIn(10, keys)
self.assertNotIn("Z", keys)
self.assertEqual(d.keys(), d.keys())
e = {1: 11, "a": "def"}
self.assertEqual(d.keys(), e.keys())
del e["a"]
self.assertNotEqual(d.keys(), e.keys())
def test_dict_items(self):
d = {1: 10, "a": "ABC"}
items = d.items()
self.assertEqual(len(items), 2)
self.assertEqual(set(items), {(1, 10), ("a", "ABC")})
self.assertEqual(items, {(1, 10), ("a", "ABC")})
self.assertNotEqual(items, {(1, 10), ("a", "ABC"), "junk"})
self.assertNotEqual(items, {(1, 10), ("a", "def")})
self.assertNotEqual(items, {(1, 10)})
self.assertNotEqual(items, 42)
self.assertIn((1, 10), items)
self.assertIn(("a", "ABC"), items)
self.assertNotIn((1, 11), items)
self.assertNotIn(1, items)
self.assertNotIn((), items)
self.assertNotIn((1,), items)
self.assertNotIn((1, 2, 3), items)
self.assertEqual(d.items(), d.items())
e = d.copy()
self.assertEqual(d.items(), e.items())
e["a"] = "def"
self.assertNotEqual(d.items(), e.items())
def test_dict_mixed_keys_items(self):
d = {(1, 1): 11, (2, 2): 22}
e = {1: 1, 2: 2}
self.assertEqual(d.keys(), e.items())
self.assertNotEqual(d.items(), e.keys())
def test_dict_values(self):
d = {1: 10, "a": "ABC"}
values = d.values()
self.assertEqual(set(values), {10, "ABC"})
self.assertEqual(len(values), 2)
def test_dict_repr(self):
d = {1: 10, "a": "ABC"}
self.assertIsInstance(repr(d), str)
r = repr(d.items())
self.assertIsInstance(r, str)
self.assertTrue(r == "dict_items([('a', 'ABC'), (1, 10)])" or
r == "dict_items([(1, 10), ('a', 'ABC')])")
r = repr(d.keys())
self.assertIsInstance(r, str)
self.assertTrue(r == "dict_keys(['a', 1])" or
r == "dict_keys([1, 'a'])")
r = repr(d.values())
self.assertIsInstance(r, str)
self.assertTrue(r == "dict_values(['ABC', 10])" or
r == "dict_values([10, 'ABC'])")
def test_keys_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 2}
d3 = {'d': 4, 'e': 5}
self.assertEqual(d1.keys() & d1.keys(), {'a', 'b'})
self.assertEqual(d1.keys() & d2.keys(), {'b'})
self.assertEqual(d1.keys() & d3.keys(), set())
self.assertEqual(d1.keys() & set(d1.keys()), {'a', 'b'})
self.assertEqual(d1.keys() & set(d2.keys()), {'b'})
self.assertEqual(d1.keys() & set(d3.keys()), set())
self.assertEqual(d1.keys() & tuple(d1.keys()), {'a', 'b'})
self.assertEqual(d1.keys() | d1.keys(), {'a', 'b'})
self.assertEqual(d1.keys() | d2.keys(), {'a', 'b', 'c'})
self.assertEqual(d1.keys() | d3.keys(), {'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() | set(d1.keys()), {'a', 'b'})
self.assertEqual(d1.keys() | set(d2.keys()), {'a', 'b', 'c'})
self.assertEqual(d1.keys() | set(d3.keys()),
{'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() | (1, 2), {'a', 'b', 1, 2})
self.assertEqual(d1.keys() ^ d1.keys(), set())
self.assertEqual(d1.keys() ^ d2.keys(), {'a', 'c'})
self.assertEqual(d1.keys() ^ d3.keys(), {'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() ^ set(d1.keys()), set())
self.assertEqual(d1.keys() ^ set(d2.keys()), {'a', 'c'})
self.assertEqual(d1.keys() ^ set(d3.keys()),
{'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() ^ tuple(d2.keys()), {'a', 'c'})
self.assertEqual(d1.keys() - d1.keys(), set())
self.assertEqual(d1.keys() - d2.keys(), {'a'})
self.assertEqual(d1.keys() - d3.keys(), {'a', 'b'})
self.assertEqual(d1.keys() - set(d1.keys()), set())
self.assertEqual(d1.keys() - set(d2.keys()), {'a'})
self.assertEqual(d1.keys() - set(d3.keys()), {'a', 'b'})
self.assertEqual(d1.keys() - (0, 1), {'a', 'b'})
self.assertFalse(d1.keys().isdisjoint(d1.keys()))
self.assertFalse(d1.keys().isdisjoint(d2.keys()))
self.assertFalse(d1.keys().isdisjoint(list(d2.keys())))
self.assertFalse(d1.keys().isdisjoint(set(d2.keys())))
self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'}))
self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z']))
self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z'])))
self.assertTrue(d1.keys().isdisjoint(set(['x', 'y'])))
self.assertTrue(d1.keys().isdisjoint(['x', 'y']))
self.assertTrue(d1.keys().isdisjoint({}))
self.assertTrue(d1.keys().isdisjoint(d3.keys()))
de = {}
self.assertTrue(de.keys().isdisjoint(set()))
self.assertTrue(de.keys().isdisjoint([]))
self.assertTrue(de.keys().isdisjoint(de.keys()))
self.assertTrue(de.keys().isdisjoint([1]))
def test_items_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'a': 2, 'b': 2}
d3 = {'d': 4, 'e': 5}
self.assertEqual(
d1.items() & d1.items(), {('a', 1), ('b', 2)})
self.assertEqual(d1.items() & d2.items(), {('b', 2)})
self.assertEqual(d1.items() & d3.items(), set())
self.assertEqual(d1.items() & set(d1.items()),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() & set(d2.items()), {('b', 2)})
self.assertEqual(d1.items() & set(d3.items()), set())
self.assertEqual(d1.items() | d1.items(),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() | d2.items(),
{('a', 1), ('a', 2), ('b', 2)})
self.assertEqual(d1.items() | d3.items(),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() | set(d1.items()),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() | set(d2.items()),
{('a', 1), ('a', 2), ('b', 2)})
self.assertEqual(d1.items() | set(d3.items()),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() ^ d1.items(), set())
self.assertEqual(d1.items() ^ d2.items(),
{('a', 1), ('a', 2)})
self.assertEqual(d1.items() ^ d3.items(),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() - d1.items(), set())
self.assertEqual(d1.items() - d2.items(), {('a', 1)})
self.assertEqual(d1.items() - d3.items(), {('a', 1), ('b', 2)})
self.assertEqual(d1.items() - set(d1.items()), set())
self.assertEqual(d1.items() - set(d2.items()), {('a', 1)})
self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)})
self.assertFalse(d1.items().isdisjoint(d1.items()))
self.assertFalse(d1.items().isdisjoint(d2.items()))
self.assertFalse(d1.items().isdisjoint(list(d2.items())))
self.assertFalse(d1.items().isdisjoint(set(d2.items())))
self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'}))
self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z']))
self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z'])))
self.assertTrue(d1.items().isdisjoint(set(['x', 'y'])))
self.assertTrue(d1.items().isdisjoint({}))
self.assertTrue(d1.items().isdisjoint(d3.items()))
de = {}
self.assertTrue(de.items().isdisjoint(set()))
self.assertTrue(de.items().isdisjoint([]))
self.assertTrue(de.items().isdisjoint(de.items()))
self.assertTrue(de.items().isdisjoint([1]))
def test_recursive_repr(self):
d = {}
d[42] = d.values()
r = repr(d)
# Cannot perform a stronger test, as the contents of the repr
# are implementation-dependent. All we can say is that we
# want a str result, not an exception of any sort.
self.assertIsInstance(r, str)
d[42] = d.items()
r = repr(d)
# Again.
self.assertIsInstance(r, str)
@unittest.skipIf(sys.platform == "win32", "thread 'main' has overflowed its stack")
def test_deeply_nested_repr(self):
d = {}
for i in range(sys.getrecursionlimit() + 100):
d = {42: d.values()}
self.assertRaises(RecursionError, repr, d)
def test_copy(self):
d = {1: 10, "a": "ABC"}
self.assertRaises(TypeError, copy.copy, d.keys())
self.assertRaises(TypeError, copy.copy, d.values())
self.assertRaises(TypeError, copy.copy, d.items())
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compare_error(self):
class Exc(Exception):
pass
class BadEq:
def __hash__(self):
return 7
def __eq__(self, other):
raise Exc
k1, k2 = BadEq(), BadEq()
v1, v2 = BadEq(), BadEq()
d = {k1: v1}
self.assertIn(k1, d)
self.assertIn(k1, d.keys())
self.assertIn(v1, d.values())
self.assertIn((k1, v1), d.items())
self.assertRaises(Exc, d.__contains__, k2)
self.assertRaises(Exc, d.keys().__contains__, k2)
self.assertRaises(Exc, d.items().__contains__, (k2, v1))
self.assertRaises(Exc, d.items().__contains__, (k1, v2))
with self.assertRaises(Exc):
v2 in d.values()
def test_pickle(self):
d = {1: 10, "a": "ABC"}
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.keys(), proto)
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.values(), proto)
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.items(), proto)
def test_abc_registry(self):
d = dict(a=1)
self.assertIsInstance(d.keys(), collections.abc.KeysView)
self.assertIsInstance(d.keys(), collections.abc.MappingView)
self.assertIsInstance(d.keys(), collections.abc.Set)
self.assertIsInstance(d.keys(), collections.abc.Sized)
self.assertIsInstance(d.keys(), collections.abc.Iterable)
self.assertIsInstance(d.keys(), collections.abc.Container)
self.assertIsInstance(d.values(), collections.abc.ValuesView)
self.assertIsInstance(d.values(), collections.abc.MappingView)
self.assertIsInstance(d.values(), collections.abc.Sized)
self.assertIsInstance(d.items(), collections.abc.ItemsView)
self.assertIsInstance(d.items(), collections.abc.MappingView)
self.assertIsInstance(d.items(), collections.abc.Set)
self.assertIsInstance(d.items(), collections.abc.Sized)
self.assertIsInstance(d.items(), collections.abc.Iterable)
self.assertIsInstance(d.items(), collections.abc.Container)
if __name__ == "__main__":
unittest.main()
import collections.abc
import copy
import pickle
import sys
import unittest
class DictSetTest(unittest.TestCase):
def test_constructors_not_callable(self):
kt = type({}.keys())
self.assertRaises(TypeError, kt, {})
self.assertRaises(TypeError, kt)
it = type({}.items())
self.assertRaises(TypeError, it, {})
self.assertRaises(TypeError, it)
vt = type({}.values())
self.assertRaises(TypeError, vt, {})
self.assertRaises(TypeError, vt)
def test_dict_keys(self):
d = {1: 10, "a": "ABC"}
keys = d.keys()
self.assertEqual(len(keys), 2)
self.assertEqual(set(keys), {1, "a"})
self.assertEqual(keys, {1, "a"})
self.assertNotEqual(keys, {1, "a", "b"})
self.assertNotEqual(keys, {1, "b"})
self.assertNotEqual(keys, {1})
self.assertNotEqual(keys, 42)
self.assertIn(1, keys)
self.assertIn("a", keys)
self.assertNotIn(10, keys)
self.assertNotIn("Z", keys)
self.assertEqual(d.keys(), d.keys())
e = {1: 11, "a": "def"}
self.assertEqual(d.keys(), e.keys())
del e["a"]
self.assertNotEqual(d.keys(), e.keys())
def test_dict_items(self):
d = {1: 10, "a": "ABC"}
items = d.items()
self.assertEqual(len(items), 2)
self.assertEqual(set(items), {(1, 10), ("a", "ABC")})
self.assertEqual(items, {(1, 10), ("a", "ABC")})
self.assertNotEqual(items, {(1, 10), ("a", "ABC"), "junk"})
self.assertNotEqual(items, {(1, 10), ("a", "def")})
self.assertNotEqual(items, {(1, 10)})
self.assertNotEqual(items, 42)
self.assertIn((1, 10), items)
self.assertIn(("a", "ABC"), items)
self.assertNotIn((1, 11), items)
self.assertNotIn(1, items)
self.assertNotIn((), items)
self.assertNotIn((1,), items)
self.assertNotIn((1, 2, 3), items)
self.assertEqual(d.items(), d.items())
e = d.copy()
self.assertEqual(d.items(), e.items())
e["a"] = "def"
self.assertNotEqual(d.items(), e.items())
def test_dict_mixed_keys_items(self):
d = {(1, 1): 11, (2, 2): 22}
e = {1: 1, 2: 2}
self.assertEqual(d.keys(), e.items())
self.assertNotEqual(d.items(), e.keys())
def test_dict_values(self):
d = {1: 10, "a": "ABC"}
values = d.values()
self.assertEqual(set(values), {10, "ABC"})
self.assertEqual(len(values), 2)
def test_dict_repr(self):
d = {1: 10, "a": "ABC"}
self.assertIsInstance(repr(d), str)
r = repr(d.items())
self.assertIsInstance(r, str)
self.assertTrue(r == "dict_items([('a', 'ABC'), (1, 10)])" or
r == "dict_items([(1, 10), ('a', 'ABC')])")
r = repr(d.keys())
self.assertIsInstance(r, str)
self.assertTrue(r == "dict_keys(['a', 1])" or
r == "dict_keys([1, 'a'])")
r = repr(d.values())
self.assertIsInstance(r, str)
self.assertTrue(r == "dict_values(['ABC', 10])" or
r == "dict_values([10, 'ABC'])")
def test_keys_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 2}
d3 = {'d': 4, 'e': 5}
d4 = {'d': 4}
class CustomSet(set):
def intersection(self, other):
return CustomSet(super().intersection(other))
self.assertEqual(d1.keys() & d1.keys(), {'a', 'b'})
self.assertEqual(d1.keys() & d2.keys(), {'b'})
self.assertEqual(d1.keys() & d3.keys(), set())
self.assertEqual(d1.keys() & set(d1.keys()), {'a', 'b'})
self.assertEqual(d1.keys() & set(d2.keys()), {'b'})
self.assertEqual(d1.keys() & set(d3.keys()), set())
self.assertEqual(d1.keys() & tuple(d1.keys()), {'a', 'b'})
self.assertEqual(d3.keys() & d4.keys(), {'d'})
self.assertEqual(d4.keys() & d3.keys(), {'d'})
self.assertEqual(d4.keys() & set(d3.keys()), {'d'})
self.assertIsInstance(d4.keys() & frozenset(d3.keys()), set)
self.assertIsInstance(frozenset(d3.keys()) & d4.keys(), set)
self.assertIs(type(d4.keys() & CustomSet(d3.keys())), set)
self.assertIs(type(d1.keys() & []), set)
self.assertIs(type([] & d1.keys()), set)
self.assertEqual(d1.keys() | d1.keys(), {'a', 'b'})
self.assertEqual(d1.keys() | d2.keys(), {'a', 'b', 'c'})
self.assertEqual(d1.keys() | d3.keys(), {'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() | set(d1.keys()), {'a', 'b'})
self.assertEqual(d1.keys() | set(d2.keys()), {'a', 'b', 'c'})
self.assertEqual(d1.keys() | set(d3.keys()),
{'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() | (1, 2), {'a', 'b', 1, 2})
self.assertEqual(d1.keys() ^ d1.keys(), set())
self.assertEqual(d1.keys() ^ d2.keys(), {'a', 'c'})
self.assertEqual(d1.keys() ^ d3.keys(), {'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() ^ set(d1.keys()), set())
self.assertEqual(d1.keys() ^ set(d2.keys()), {'a', 'c'})
self.assertEqual(d1.keys() ^ set(d3.keys()),
{'a', 'b', 'd', 'e'})
self.assertEqual(d1.keys() ^ tuple(d2.keys()), {'a', 'c'})
self.assertEqual(d1.keys() - d1.keys(), set())
self.assertEqual(d1.keys() - d2.keys(), {'a'})
self.assertEqual(d1.keys() - d3.keys(), {'a', 'b'})
self.assertEqual(d1.keys() - set(d1.keys()), set())
self.assertEqual(d1.keys() - set(d2.keys()), {'a'})
self.assertEqual(d1.keys() - set(d3.keys()), {'a', 'b'})
self.assertEqual(d1.keys() - (0, 1), {'a', 'b'})
self.assertFalse(d1.keys().isdisjoint(d1.keys()))
self.assertFalse(d1.keys().isdisjoint(d2.keys()))
self.assertFalse(d1.keys().isdisjoint(list(d2.keys())))
self.assertFalse(d1.keys().isdisjoint(set(d2.keys())))
self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'}))
self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z']))
self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z'])))
self.assertTrue(d1.keys().isdisjoint(set(['x', 'y'])))
self.assertTrue(d1.keys().isdisjoint(['x', 'y']))
self.assertTrue(d1.keys().isdisjoint({}))
self.assertTrue(d1.keys().isdisjoint(d3.keys()))
de = {}
self.assertTrue(de.keys().isdisjoint(set()))
self.assertTrue(de.keys().isdisjoint([]))
self.assertTrue(de.keys().isdisjoint(de.keys()))
self.assertTrue(de.keys().isdisjoint([1]))
def test_items_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'a': 2, 'b': 2}
d3 = {'d': 4, 'e': 5}
self.assertEqual(
d1.items() & d1.items(), {('a', 1), ('b', 2)})
self.assertEqual(d1.items() & d2.items(), {('b', 2)})
self.assertEqual(d1.items() & d3.items(), set())
self.assertEqual(d1.items() & set(d1.items()),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() & set(d2.items()), {('b', 2)})
self.assertEqual(d1.items() & set(d3.items()), set())
self.assertEqual(d1.items() | d1.items(),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() | d2.items(),
{('a', 1), ('a', 2), ('b', 2)})
self.assertEqual(d1.items() | d3.items(),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() | set(d1.items()),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() | set(d2.items()),
{('a', 1), ('a', 2), ('b', 2)})
self.assertEqual(d1.items() | set(d3.items()),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() ^ d1.items(), set())
self.assertEqual(d1.items() ^ d2.items(),
{('a', 1), ('a', 2)})
self.assertEqual(d1.items() ^ d3.items(),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() - d1.items(), set())
self.assertEqual(d1.items() - d2.items(), {('a', 1)})
self.assertEqual(d1.items() - d3.items(), {('a', 1), ('b', 2)})
self.assertEqual(d1.items() - set(d1.items()), set())
self.assertEqual(d1.items() - set(d2.items()), {('a', 1)})
self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)})
self.assertFalse(d1.items().isdisjoint(d1.items()))
self.assertFalse(d1.items().isdisjoint(d2.items()))
self.assertFalse(d1.items().isdisjoint(list(d2.items())))
self.assertFalse(d1.items().isdisjoint(set(d2.items())))
self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'}))
self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z']))
self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z'])))
self.assertTrue(d1.items().isdisjoint(set(['x', 'y'])))
self.assertTrue(d1.items().isdisjoint({}))
self.assertTrue(d1.items().isdisjoint(d3.items()))
de = {}
self.assertTrue(de.items().isdisjoint(set()))
self.assertTrue(de.items().isdisjoint([]))
self.assertTrue(de.items().isdisjoint(de.items()))
self.assertTrue(de.items().isdisjoint([1]))
def test_set_operations_with_iterator(self):
origin = {1: 2, 3: 4}
self.assertEqual(origin.keys() & iter([1, 2]), {1})
self.assertEqual(origin.keys() | iter([1, 2]), {1, 2, 3})
self.assertEqual(origin.keys() ^ iter([1, 2]), {2, 3})
self.assertEqual(origin.keys() - iter([1, 2]), {3})
items = origin.items()
self.assertEqual(items & iter([(1, 2)]), {(1, 2)})
self.assertEqual(items ^ iter([(1, 2)]), {(3, 4)})
self.assertEqual(items | iter([(1, 2)]), {(1, 2), (3, 4)})
self.assertEqual(items - iter([(1, 2)]), {(3, 4)})
def test_set_operations_with_noniterable(self):
with self.assertRaises(TypeError):
{}.keys() & 1
with self.assertRaises(TypeError):
{}.keys() | 1
with self.assertRaises(TypeError):
{}.keys() ^ 1
with self.assertRaises(TypeError):
{}.keys() - 1
with self.assertRaises(TypeError):
{}.items() & 1
with self.assertRaises(TypeError):
{}.items() | 1
with self.assertRaises(TypeError):
{}.items() ^ 1
with self.assertRaises(TypeError):
{}.items() - 1
def test_recursive_repr(self):
d = {}
d[42] = d.values()
r = repr(d)
# Cannot perform a stronger test, as the contents of the repr
# are implementation-dependent. All we can say is that we
# want a str result, not an exception of any sort.
self.assertIsInstance(r, str)
d[42] = d.items()
r = repr(d)
# Again.
self.assertIsInstance(r, str)
def test_deeply_nested_repr(self):
d = {}
for i in range(sys.getrecursionlimit() + 100):
d = {42: d.values()}
self.assertRaises(RecursionError, repr, d)
def test_copy(self):
d = {1: 10, "a": "ABC"}
self.assertRaises(TypeError, copy.copy, d.keys())
self.assertRaises(TypeError, copy.copy, d.values())
self.assertRaises(TypeError, copy.copy, d.items())
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_compare_error(self):
class Exc(Exception):
pass
class BadEq:
def __hash__(self):
return 7
def __eq__(self, other):
raise Exc
k1, k2 = BadEq(), BadEq()
v1, v2 = BadEq(), BadEq()
d = {k1: v1}
self.assertIn(k1, d)
self.assertIn(k1, d.keys())
self.assertIn(v1, d.values())
self.assertIn((k1, v1), d.items())
self.assertRaises(Exc, d.__contains__, k2)
self.assertRaises(Exc, d.keys().__contains__, k2)
self.assertRaises(Exc, d.items().__contains__, (k2, v1))
self.assertRaises(Exc, d.items().__contains__, (k1, v2))
with self.assertRaises(Exc):
v2 in d.values()
def test_pickle(self):
d = {1: 10, "a": "ABC"}
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.keys(), proto)
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.values(), proto)
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.items(), proto)
def test_abc_registry(self):
d = dict(a=1)
self.assertIsInstance(d.keys(), collections.abc.KeysView)
self.assertIsInstance(d.keys(), collections.abc.MappingView)
self.assertIsInstance(d.keys(), collections.abc.Set)
self.assertIsInstance(d.keys(), collections.abc.Sized)
self.assertIsInstance(d.keys(), collections.abc.Iterable)
self.assertIsInstance(d.keys(), collections.abc.Container)
self.assertIsInstance(d.values(), collections.abc.ValuesView)
self.assertIsInstance(d.values(), collections.abc.MappingView)
self.assertIsInstance(d.values(), collections.abc.Sized)
self.assertIsInstance(d.items(), collections.abc.ItemsView)
self.assertIsInstance(d.items(), collections.abc.MappingView)
self.assertIsInstance(d.items(), collections.abc.Set)
self.assertIsInstance(d.items(), collections.abc.Sized)
self.assertIsInstance(d.items(), collections.abc.Iterable)
self.assertIsInstance(d.items(), collections.abc.Container)
if __name__ == "__main__":
unittest.main()
+44 -6
View File
@@ -66,6 +66,9 @@ class GeneralFloatCases(unittest.TestCase):
# See bpo-34087
self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f')
def test_noargs(self):
self.assertEqual(float(), 0.0)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_underscores(self):
@@ -571,6 +574,27 @@ class GeneralFloatCases(unittest.TestCase):
#self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
#self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
def test_hash(self):
for x in range(-30, 30):
self.assertEqual(hash(float(x)), hash(x))
self.assertEqual(hash(float(sys.float_info.max)),
hash(int(sys.float_info.max)))
self.assertEqual(hash(float('inf')), sys.hash_info.inf)
self.assertEqual(hash(float('-inf')), -sys.hash_info.inf)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_hash_nan(self):
value = float('nan')
self.assertEqual(hash(value), object.__hash__(value))
class H:
def __hash__(self):
return 42
class F(float, H):
pass
value = F('nan')
self.assertEqual(hash(value), object.__hash__(value))
@requires_setformat
class FormatFunctionsTestCase(unittest.TestCase):
@@ -740,7 +764,7 @@ class FormatTestCase(unittest.TestCase):
@unittest.expectedFailure
@support.requires_IEEE_754
def test_format_testfile(self):
with open(format_testfile) as testfile:
with open(format_testfile, encoding="utf-8") as testfile:
for line in testfile:
if line.startswith('--'):
continue
@@ -782,7 +806,7 @@ class FormatTestCase(unittest.TestCase):
class ReprTestCase(unittest.TestCase):
def test_repr(self):
with open(os.path.join(os.path.split(__file__)[0],
'floating_points.txt')) as floats_file:
'floating_points.txt'), encoding="utf-8") as floats_file:
for line in floats_file:
line = line.strip()
if not line or line.startswith('#'):
@@ -1186,10 +1210,10 @@ class HexFloatTestCase(unittest.TestCase):
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_from_hex(self):
MIN = self.MIN;
MAX = self.MAX;
TINY = self.TINY;
EPS = self.EPS;
MIN = self.MIN
MAX = self.MAX
TINY = self.TINY
EPS = self.EPS
# two spellings of infinity, with optional signs; case-insensitive
self.identical(fromHex('inf'), INF)
@@ -1470,6 +1494,20 @@ class HexFloatTestCase(unittest.TestCase):
self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
# Regression test for a corner-case bug reported in b.p.o. 44954
self.identical(fromHex('0x.8p-1074'), 0.0)
self.identical(fromHex('0x.80p-1074'), 0.0)
self.identical(fromHex('0x.81p-1074'), TINY)
self.identical(fromHex('0x8p-1078'), 0.0)
self.identical(fromHex('0x8.0p-1078'), 0.0)
self.identical(fromHex('0x8.1p-1078'), TINY)
self.identical(fromHex('0x80p-1082'), 0.0)
self.identical(fromHex('0x81p-1082'), TINY)
self.identical(fromHex('.8p-1074'), 0.0)
self.identical(fromHex('8p-1078'), 0.0)
self.identical(fromHex('-.8p-1074'), -0.0)
self.identical(fromHex('+8p-1078'), 0.0)
def test_roundtrip(self):
def roundtrip(x):
return fromHex(toHex(x))
+103 -4
View File
@@ -533,6 +533,7 @@ class TestBasicOps(unittest.TestCase):
next(testIntermediate)
self.assertEqual(list(op(testIntermediate)), list(result2))
def test_count(self):
self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
@@ -1477,6 +1478,7 @@ class TestBasicOps(unittest.TestCase):
p = weakref.proxy(a)
self.assertEqual(getattr(p, '__class__'), type(b))
del a
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, getattr, p, '__class__')
ans = list('abc')
@@ -2435,10 +2437,37 @@ Samuele
... else:
... return starmap(func, repeat(args, times))
>>> def grouper(n, iterable, fillvalue=None):
... "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
>>> def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
... "Collect data into non-overlapping fixed-length chunks or blocks"
... # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
... # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
... # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
... args = [iter(iterable)] * n
... return zip_longest(*args, fillvalue=fillvalue)
... if incomplete == 'fill':
... return zip_longest(*args, fillvalue=fillvalue)
... if incomplete == 'strict':
... return zip(*args, strict=True)
... if incomplete == 'ignore':
... return zip(*args)
... else:
... raise ValueError('Expected fill, strict, or ignore')
>>> def triplewise(iterable):
... "Return overlapping triplets from an iterable"
... # pairwise('ABCDEFG') -> ABC BCD CDE DEF EFG
... for (a, _), (b, c) in pairwise(pairwise(iterable)):
... yield a, b, c
>>> import collections
>>> def sliding_window(iterable, n):
... # sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
... it = iter(iterable)
... window = collections.deque(islice(it, n), maxlen=n)
... if len(window) == n:
... yield tuple(window)
... for x in it:
... window.append(x)
... yield tuple(window)
>>> def roundrobin(*iterables):
... "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
@@ -2453,6 +2482,40 @@ Samuele
... pending -= 1
... nexts = cycle(islice(nexts, pending))
>>> def partition(pred, iterable):
... "Use a predicate to partition entries into false entries and true entries"
... # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9
... t1, t2 = tee(iterable)
... return filterfalse(pred, t1), filter(pred, t2)
>>> def before_and_after(predicate, it):
... ''' Variant of takewhile() that allows complete
... access to the remainder of the iterator.
...
... >>> all_upper, remainder = before_and_after(str.isupper, 'ABCdEfGhI')
... >>> str.join('', all_upper)
... 'ABC'
... >>> str.join('', remainder)
... 'dEfGhI'
...
... Note that the first iterator must be fully
... consumed before the second iterator can
... generate valid results.
... '''
... it = iter(it)
... transition = []
... def true_iterator():
... for elem in it:
... if predicate(elem):
... yield elem
... else:
... transition.append(elem)
... return
... def remainder_iterator():
... yield from transition
... yield from it
... return true_iterator(), remainder_iterator()
>>> def powerset(iterable):
... "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
... s = list(iterable)
@@ -2574,12 +2637,47 @@ True
>>> dotproduct([1,2,3], [4,5,6])
32
>>> list(grouper(3, 'abcdefg', 'x'))
>>> list(grouper('abcdefg', 3, fillvalue='x'))
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')]
>>> it = grouper('abcdefg', 3, incomplete='strict')
>>> next(it)
('a', 'b', 'c')
>>> next(it)
('d', 'e', 'f')
>>> next(it)
Traceback (most recent call last):
...
ValueError: zip() argument 2 is shorter than argument 1
>>> list(grouper('abcdefg', n=3, incomplete='ignore'))
[('a', 'b', 'c'), ('d', 'e', 'f')]
>>> list(triplewise('ABCDEFG'))
[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')]
>>> list(sliding_window('ABCDEFG', 4))
[('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')]
>>> list(roundrobin('abc', 'd', 'ef'))
['a', 'd', 'e', 'b', 'f', 'c']
>>> def is_odd(x):
... return x % 2 == 1
>>> evens, odds = partition(is_odd, range(10))
>>> list(evens)
[0, 2, 4, 6, 8]
>>> list(odds)
[1, 3, 5, 7, 9]
>>> it = iter('ABCdEfGhI')
>>> all_upper, remainder = before_and_after(str.isupper, it)
>>> ''.join(all_upper)
'ABC'
>>> ''.join(remainder)
'dEfGhI'
>>> list(powerset([1,2,3]))
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
@@ -2635,6 +2733,7 @@ def test_main(verbose=None):
counts[i] = sys.gettotalrefcount()
print(counts)
# doctest the examples in the library reference
support.run_doctest(sys.modules[__name__], verbose)
if __name__ == "__main__":
+74
View File
@@ -151,6 +151,11 @@ class ListTest(list_tests.CommonTest):
a[:] = data
self.assertEqual(list(it), [])
def test_step_overflow(self):
a = [0, 1, 2, 3, 4]
a[1::sys.maxsize] = [0]
self.assertEqual(a[3::sys.maxsize], [3])
def test_no_comdat_folding(self):
# Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
# optimization causes failures in code that relies on distinct
@@ -159,6 +164,32 @@ class ListTest(list_tests.CommonTest):
with self.assertRaises(TypeError):
(3,) + L([1,2])
@unittest.skip("TODO: RUSTPYTHON; hang")
def test_equal_operator_modifying_operand(self):
# test fix for seg fault reported in bpo-38588 part 2.
class X:
def __eq__(self,other) :
list2.clear()
return NotImplemented
class Y:
def __eq__(self, other):
list1.clear()
return NotImplemented
class Z:
def __eq__(self, other):
list3.clear()
return NotImplemented
list1 = [X()]
list2 = [Y()]
self.assertTrue(list1 == list2)
list3 = [Z()]
list4 = [1]
self.assertFalse(list3 == list4)
@cpython_only
def test_preallocation(self):
iterable = [0] * 10
@@ -167,5 +198,48 @@ class ListTest(list_tests.CommonTest):
self.assertEqual(iter_size, sys.getsizeof(list([0] * 10)))
self.assertEqual(iter_size, sys.getsizeof(list(range(10))))
@unittest.skip("TODO: RUSTPYTHON; hang")
def test_count_index_remove_crashes(self):
# bpo-38610: The count(), index(), and remove() methods were not
# holding strong references to list elements while calling
# PyObject_RichCompareBool().
class X:
def __eq__(self, other):
lst.clear()
return NotImplemented
lst = [X()]
with self.assertRaises(ValueError):
lst.index(lst)
class L(list):
def __eq__(self, other):
str(other)
return NotImplemented
lst = L([X()])
lst.count(lst)
lst = L([X()])
with self.assertRaises(ValueError):
lst.remove(lst)
# bpo-39453: list.__contains__ was not holding strong references
# to list elements while calling PyObject_RichCompareBool().
lst = [X(), X()]
3 in lst
lst = [X(), X()]
X() in lst
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_count(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_count()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_contains_fake(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_contains_fake()
if __name__ == "__main__":
unittest.main()
+5 -2
View File
@@ -6,15 +6,16 @@
import unittest
import test.support
from test.support import import_helper
import sys
# import gc # XXX: RUSTPYTHON
import gc
import weakref
import array
import io
import copy
import pickle
from test.support import import_helper
class AbstractMemoryTests:
source_bytes = b"abcdef"
@@ -418,9 +419,11 @@ class BaseArrayMemoryTests(AbstractMemoryTests):
itemsize = array.array('i').itemsize
format = 'i'
@unittest.skip('XXX test should be adapted for non-byte buffers')
def test_getbuffer(self):
pass
@unittest.skip('XXX NotImplementedError: tolist() only supports byte views')
def test_tolist(self):
pass
+13 -12
View File
@@ -6,7 +6,7 @@ import threading
import time
import unittest
import weakref
from test import support
from test.support import gc_collect
from test.support import import_helper
from test.support import threading_helper
@@ -420,11 +420,12 @@ class BaseSimpleQueueTest:
def setUp(self):
self.q = self.type2test()
def feed(self, q, seq, rnd):
def feed(self, q, seq, rnd, sentinel):
while True:
try:
val = seq.pop()
except IndexError:
q.put(sentinel)
return
q.put(val)
if rnd.random() > 0.5:
@@ -463,11 +464,10 @@ class BaseSimpleQueueTest:
return
results.append(val)
def run_threads(self, n_feeders, n_consumers, q, inputs,
feed_func, consume_func):
def run_threads(self, n_threads, q, inputs, feed_func, consume_func):
results = []
sentinel = None
seq = inputs + [sentinel] * n_consumers
seq = inputs.copy()
seq.reverse()
rnd = random.Random(42)
@@ -481,11 +481,11 @@ class BaseSimpleQueueTest:
return wrapper
feeders = [threading.Thread(target=log_exceptions(feed_func),
args=(q, seq, rnd))
for i in range(n_feeders)]
args=(q, seq, rnd, sentinel))
for i in range(n_threads)]
consumers = [threading.Thread(target=log_exceptions(consume_func),
args=(q, results, sentinel))
for i in range(n_consumers)]
for i in range(n_threads)]
with threading_helper.start_threads(feeders + consumers):
pass
@@ -543,7 +543,7 @@ class BaseSimpleQueueTest:
# Test a pair of concurrent put() and get()
q = self.q
inputs = list(range(100))
results = self.run_threads(1, 1, q, inputs, self.feed, self.consume)
results = self.run_threads(1, q, inputs, self.feed, self.consume)
# One producer, one consumer => results appended in well-defined order
self.assertEqual(results, inputs)
@@ -553,7 +553,7 @@ class BaseSimpleQueueTest:
N = 50
q = self.q
inputs = list(range(10000))
results = self.run_threads(N, N, q, inputs, self.feed, self.consume)
results = self.run_threads(N, q, inputs, self.feed, self.consume)
# Multiple consumers without synchronization append the
# results in random order
@@ -564,7 +564,7 @@ class BaseSimpleQueueTest:
N = 50
q = self.q
inputs = list(range(10000))
results = self.run_threads(N, N, q, inputs,
results = self.run_threads(N, q, inputs,
self.feed, self.consume_nonblock)
self.assertEqual(sorted(results), inputs)
@@ -574,7 +574,7 @@ class BaseSimpleQueueTest:
N = 50
q = self.q
inputs = list(range(1000))
results = self.run_threads(N, N, q, inputs,
results = self.run_threads(N, q, inputs,
self.feed, self.consume_timeout)
self.assertEqual(sorted(results), inputs)
@@ -591,6 +591,7 @@ class BaseSimpleQueueTest:
q.put(C())
for i in range(N):
wr = weakref.ref(q.get())
gc_collect() # For PyPy or other GCs.
self.assertIsNone(wr())
+65 -28
View File
@@ -4,6 +4,7 @@ import unittest
import sys
import pickle
import itertools
from test.support import ALWAYS_EQ
# pure Python implementations (3 args only), for comparison
def pyrange(start, stop, step):
@@ -90,6 +91,21 @@ class RangeTest(unittest.TestCase):
r = range(-sys.maxsize, sys.maxsize, 2)
self.assertEqual(len(r), sys.maxsize)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_range_constructor_error_messages(self):
with self.assertRaisesRegex(
TypeError,
"range expected at least 1 argument, got 0"
):
range()
with self.assertRaisesRegex(
TypeError,
"range expected at most 3 arguments, got 6"
):
range(1, 2, 3, 4, 5, 6)
def test_large_operands(self):
x = range(10**20, 10**20+10, 3)
self.assertEqual(len(x), 4)
@@ -289,11 +305,7 @@ class RangeTest(unittest.TestCase):
self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87)
self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86)
class AlwaysEqual(object):
def __eq__(self, other):
return True
always_equal = AlwaysEqual()
self.assertEqual(range(10).index(always_equal), 0)
self.assertEqual(range(10).index(ALWAYS_EQ), 0)
def test_user_index_method(self):
bignum = 2*sys.maxsize
@@ -344,11 +356,7 @@ class RangeTest(unittest.TestCase):
self.assertEqual(range(1, 2**100, 2).count(2**87), 0)
self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1)
class AlwaysEqual(object):
def __eq__(self, other):
return True
always_equal = AlwaysEqual()
self.assertEqual(range(10).count(always_equal), 10)
self.assertEqual(range(10).count(ALWAYS_EQ), 10)
self.assertEqual(len(range(sys.maxsize, sys.maxsize+10)), 10)
@@ -367,27 +375,50 @@ class RangeTest(unittest.TestCase):
self.assertEqual(list(pickle.loads(pickle.dumps(r, proto))),
list(r))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_iterator_pickling(self):
testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
(13, 21, 3), (-2, 2, 2), (2**65, 2**65+2)]
testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1), (13, 21, 3),
(-2, 2, 2)]
for M in 2**31, 2**63:
testcases += [
(M-3, M-1), (4*M, 4*M+2),
(M-2, M-1, 2), (-M+1, -M, -2),
(1, 2, M-1), (-1, -2, -M),
(1, M-1, M-1), (-1, -M, -M),
]
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
for t in testcases:
it = itorg = iter(range(*t))
data = list(range(*t))
with self.subTest(proto=proto, t=t):
it = itorg = iter(range(*t))
data = list(range(*t))
d = pickle.dumps(it, proto)
it = pickle.loads(d)
self.assertEqual(type(itorg), type(it))
self.assertEqual(list(it), data)
it = pickle.loads(d)
try:
next(it)
except StopIteration:
continue
d = pickle.dumps(it, proto)
it = pickle.loads(d)
self.assertEqual(list(it), data[1:])
def test_iterator_pickling_overflowing_index(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
it = iter(range(2**32 + 2))
_, _, idx = it.__reduce__()
self.assertEqual(idx, 0)
it.__setstate__(2**32 + 1) # undocumented way to set r->index
_, _, idx = it.__reduce__()
self.assertEqual(idx, 2**32 + 1)
d = pickle.dumps(it, proto)
it = pickle.loads(d)
self.assertEqual(type(itorg), type(it))
self.assertEqual(list(it), data)
it = pickle.loads(d)
try:
next(it)
except StopIteration:
continue
d = pickle.dumps(it, proto)
it = pickle.loads(d)
self.assertEqual(list(it), data[1:])
self.assertEqual(next(it), 2**32 + 1)
def test_exhausted_iterator_pickling(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
@@ -429,9 +460,7 @@ class RangeTest(unittest.TestCase):
self.assertIn(True, range(3))
self.assertIn(1+0j, range(3))
class C1:
def __eq__(self, other): return True
self.assertIn(C1(), range(3))
self.assertIn(ALWAYS_EQ, range(3))
# Objects are never coerced into other types for comparison.
class C2:
@@ -635,6 +664,8 @@ class RangeTest(unittest.TestCase):
range(0) >= range(0)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_attributes(self):
# test the start, stop and step attributes of range objects
self.assert_attrs(range(0), 0, 0, 1)
@@ -644,11 +675,17 @@ class RangeTest(unittest.TestCase):
self.assert_attrs(range(0, 10, 3), 0, 10, 3)
self.assert_attrs(range(10, 0, -1), 10, 0, -1)
self.assert_attrs(range(10, 0, -3), 10, 0, -3)
self.assert_attrs(range(True), 0, 1, 1)
self.assert_attrs(range(False, True), 0, 1, 1)
self.assert_attrs(range(False, True, True), 0, 1, 1)
def assert_attrs(self, rangeobj, start, stop, step):
self.assertEqual(rangeobj.start, start)
self.assertEqual(rangeobj.stop, stop)
self.assertEqual(rangeobj.step, step)
self.assertIs(type(rangeobj.start), int)
self.assertIs(type(rangeobj.stop), int)
self.assertIs(type(rangeobj.step), int)
with self.assertRaises(AttributeError):
rangeobj.start = 0
-3
View File
@@ -220,9 +220,6 @@ class MiscTest(unittest.TestCase):
for func in (do, operator.not_):
self.assertRaises(Exc, func, Bad())
# TODO: RUSTPYTHON
import sys
@unittest.skipIf(sys.platform == "win32", "TODO: RUSTPYTHON, thread 'main' has overflowed its stack")
@support.no_tracing
def test_recursion(self):
# Check that comparison for recursive objects fails gracefully
+200 -62
View File
@@ -1,7 +1,7 @@
import unittest
from test import support
from test.support import os_helper, warnings_helper
# import gc
from test.support import warnings_helper
import gc
import weakref
import operator
import copy
@@ -318,20 +318,6 @@ class TestJointOps:
name = repr(s).partition('(')[0] # strip class name
self.assertEqual(repr(s), '%s({%s(...)})' % (name, name))
def test_cyclical_print(self):
w = ReprWrapper()
s = self.thetype([w])
w.value = s
fo = open(os_helper.TESTFN, "w")
try:
fo.write(str(s))
fo.close()
fo = open(os_helper.TESTFN, "r")
self.assertEqual(fo.read(), repr(s))
finally:
fo.close()
os_helper.unlink(os_helper.TESTFN)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_do_not_rehash_dict_keys(self):
@@ -376,17 +362,14 @@ class TestSet(TestJointOps, unittest.TestCase):
thetype = set
basetype = set
def test_contains(self):
super().test_contains()
def test_init(self):
s = self.thetype()
s.__init__(self.word)
self.assertEqual(s, set(self.word))
s.__init__(self.otherword)
self.assertEqual(s, set(self.otherword))
self.assertRaises(TypeError, s.__init__, s, 2);
self.assertRaises(TypeError, s.__init__, 1);
self.assertRaises(TypeError, s.__init__, s, 2)
self.assertRaises(TypeError, s.__init__, 1)
def test_constructor_identity(self):
s = self.thetype(range(3))
@@ -618,6 +601,7 @@ class TestSet(TestJointOps, unittest.TestCase):
p = weakref.proxy(s)
self.assertEqual(str(p), str(s))
s = None
support.gc_collect() # For PyPy or other GCs.
self.assertRaises(ReferenceError, str, p)
def test_rich_compare(self):
@@ -668,17 +652,12 @@ class TestSetSubclass(TestSet):
thetype = SetSubclass
basetype = set
def test_pickling(self):
super().test_pickling()
def test_cyclical_repr(self):
super().test_cyclical_repr()
class SetSubclassWithKeywordArgs(set):
def __init__(self, iterable=[], newarg=None):
set.__init__(self, iterable)
class TestSetSubclassWithKeywordArgs(TestSet):
def test_keywords_in_subclass(self):
'SF bug #1486663 -- this used to erroneously raise a TypeError'
SetSubclassWithKeywordArgs(newarg=1)
@@ -692,15 +671,6 @@ class TestFrozenSet(TestJointOps, unittest.TestCase):
s.__init__(self.otherword)
self.assertEqual(s, set(self.word))
def test_singleton_empty_frozenset(self):
f = frozenset()
efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
frozenset(), frozenset([]), frozenset(()), frozenset(''),
frozenset(range(0)), frozenset(frozenset()),
frozenset(f), f]
# All of the empty frozensets should have just one id()
self.assertEqual(len(set(map(id, efs))), 1)
def test_constructor_identity(self):
s = self.thetype(range(3))
t = self.thetype(s)
@@ -774,9 +744,6 @@ class TestFrozenSetSubclass(TestFrozenSet):
thetype = FrozenSetSubclass
basetype = frozenset
def test_pickling(self):
super().test_pickling()
def test_constructor_identity(self):
s = self.thetype(range(3))
t = self.thetype(s)
@@ -825,17 +792,6 @@ class TestBasicOps:
sorted_repr_values.sort()
self.assertEqual(result, sorted_repr_values)
def test_print(self):
try:
fo = open(os_helper.TESTFN, "w")
fo.write(str(self.set))
fo.close()
fo = open(os_helper.TESTFN, "r")
self.assertEqual(fo.read(), repr(self.set))
finally:
fo.close()
os_helper.unlink(os_helper.TESTFN)
def test_length(self):
self.assertEqual(len(self.set), self.length)
@@ -917,6 +873,12 @@ class TestBasicOps:
self.assertEqual(self.set, copy,
"%s != %s" % (self.set, copy))
def test_issue_37219(self):
with self.assertRaises(TypeError):
set().difference(123)
with self.assertRaises(TypeError):
set().difference_update(123)
#------------------------------------------------------------------------------
class TestBasicOpsEmpty(TestBasicOps, unittest.TestCase):
@@ -1576,36 +1538,24 @@ class TestCopyingSingleton(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set(["hello"])
def test_deep_copy(self):
super().test_deep_copy()
#------------------------------------------------------------------------------
class TestCopyingTriple(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set(["zero", 0, None])
def test_deep_copy(self):
super().test_deep_copy()
#------------------------------------------------------------------------------
class TestCopyingTuple(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set([(1, 2)])
def test_deep_copy(self):
super().test_deep_copy()
#------------------------------------------------------------------------------
class TestCopyingNested(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set([((1, 2), (3, 4))])
def test_deep_copy(self):
super().test_deep_copy()
#==============================================================================
class TestIdentities(unittest.TestCase):
@@ -1828,6 +1778,194 @@ class TestWeirdBugs(unittest.TestCase):
s = {0}
s.update(other)
class TestOperationsMutating:
"""Regression test for bpo-46615"""
constructor1 = None
constructor2 = None
def make_sets_of_bad_objects(self):
class Bad:
def __eq__(self, other):
if not enabled:
return False
if randrange(20) == 0:
set1.clear()
if randrange(20) == 0:
set2.clear()
return bool(randrange(2))
def __hash__(self):
return randrange(2)
# Don't behave poorly during construction.
enabled = False
set1 = self.constructor1(Bad() for _ in range(randrange(50)))
set2 = self.constructor2(Bad() for _ in range(randrange(50)))
# Now start behaving poorly
enabled = True
return set1, set2
def check_set_op_does_not_crash(self, function):
for _ in range(100):
set1, set2 = self.make_sets_of_bad_objects()
try:
function(set1, set2)
except RuntimeError as e:
# Just make sure we don't crash here.
self.assertIn("changed size during iteration", str(e))
@unittest.skip("TODO: RUSTPYTHON; segfault")
class TestBinaryOpsMutating(TestOperationsMutating):
def test_eq_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a == b)
def test_ne_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a != b)
def test_lt_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a < b)
def test_le_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a <= b)
def test_gt_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a > b)
def test_ge_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a >= b)
def test_and_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a & b)
def test_or_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a | b)
def test_sub_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a - b)
def test_xor_with_mutation(self):
self.check_set_op_does_not_crash(lambda a, b: a ^ b)
def test_iadd_with_mutation(self):
def f(a, b):
a &= b
self.check_set_op_does_not_crash(f)
def test_ior_with_mutation(self):
def f(a, b):
a |= b
self.check_set_op_does_not_crash(f)
def test_isub_with_mutation(self):
def f(a, b):
a -= b
self.check_set_op_does_not_crash(f)
def test_ixor_with_mutation(self):
def f(a, b):
a ^= b
self.check_set_op_does_not_crash(f)
def test_iteration_with_mutation(self):
def f1(a, b):
for x in a:
pass
for y in b:
pass
def f2(a, b):
for y in b:
pass
for x in a:
pass
def f3(a, b):
for x, y in zip(a, b):
pass
self.check_set_op_does_not_crash(f1)
self.check_set_op_does_not_crash(f2)
self.check_set_op_does_not_crash(f3)
class TestBinaryOpsMutating_Set_Set(TestBinaryOpsMutating, unittest.TestCase):
constructor1 = set
constructor2 = set
class TestBinaryOpsMutating_Subclass_Subclass(TestBinaryOpsMutating, unittest.TestCase):
constructor1 = SetSubclass
constructor2 = SetSubclass
class TestBinaryOpsMutating_Set_Subclass(TestBinaryOpsMutating, unittest.TestCase):
constructor1 = set
constructor2 = SetSubclass
class TestBinaryOpsMutating_Subclass_Set(TestBinaryOpsMutating, unittest.TestCase):
constructor1 = SetSubclass
constructor2 = set
@unittest.skip("TODO: RUSTPYTHON; segfault")
class TestMethodsMutating(TestOperationsMutating):
def test_issubset_with_mutation(self):
self.check_set_op_does_not_crash(set.issubset)
def test_issuperset_with_mutation(self):
self.check_set_op_does_not_crash(set.issuperset)
def test_intersection_with_mutation(self):
self.check_set_op_does_not_crash(set.intersection)
def test_union_with_mutation(self):
self.check_set_op_does_not_crash(set.union)
def test_difference_with_mutation(self):
self.check_set_op_does_not_crash(set.difference)
def test_symmetric_difference_with_mutation(self):
self.check_set_op_does_not_crash(set.symmetric_difference)
def test_isdisjoint_with_mutation(self):
self.check_set_op_does_not_crash(set.isdisjoint)
def test_difference_update_with_mutation(self):
self.check_set_op_does_not_crash(set.difference_update)
def test_intersection_update_with_mutation(self):
self.check_set_op_does_not_crash(set.intersection_update)
def test_symmetric_difference_update_with_mutation(self):
self.check_set_op_does_not_crash(set.symmetric_difference_update)
def test_update_with_mutation(self):
self.check_set_op_does_not_crash(set.update)
class TestMethodsMutating_Set_Set(TestMethodsMutating, unittest.TestCase):
constructor1 = set
constructor2 = set
class TestMethodsMutating_Subclass_Subclass(TestMethodsMutating, unittest.TestCase):
constructor1 = SetSubclass
constructor2 = SetSubclass
class TestMethodsMutating_Set_Subclass(TestMethodsMutating, unittest.TestCase):
constructor1 = set
constructor2 = SetSubclass
class TestMethodsMutating_Subclass_Set(TestMethodsMutating, unittest.TestCase):
constructor1 = SetSubclass
constructor2 = set
class TestMethodsMutating_Set_Dict(TestMethodsMutating, unittest.TestCase):
constructor1 = set
constructor2 = dict.fromkeys
class TestMethodsMutating_Set_List(TestMethodsMutating, unittest.TestCase):
constructor1 = set
constructor2 = list
# Application tests (based on David Eppstein's graph recipes ====================================
def powerset(U):
+1 -1
View File
@@ -1,7 +1,7 @@
from test import support, seq_tests
import unittest
# import gc
import gc
import pickle
# For tuple hashes, we normally only run a test to ensure that we get
-6
View File
@@ -691,11 +691,6 @@ class TypingCallableTests(BaseCallableTests, BaseTestCase):
class CollectionsCallableTests(BaseCallableTests, BaseTestCase):
Callable = collections.abc.Callable
# TODO: RUSTPYTHON, pickle.PicklingError: Can't pickle <class 'collections.abc._CallableGenericAlias'>: it's not found as collections.abc._CallableGenericAlias
@unittest.expectedFailure
def test_pickle(self): # TODO: RUSTPYTHON, remove when this passes
super().test_pickle() # TODO: RUSTPYTHON, remove when this passes
# TODO: RUSTPYTHON, AssertionError: 'collections.abc.Callable[__main__.ParamSpec, typing.TypeVar]' != 'collections.abc.Callable[~P, ~T]'
@unittest.expectedFailure
def test_paramspec(self): # TODO: RUSTPYTHON, remove when this passes
@@ -5423,7 +5418,6 @@ class AllTests(BaseTestCase):
self.assertIn('SupportsComplex', a)
def test_all_exported_names(self):
actual_all = set(typing.__all__)
computed_all = {
k for k, v in vars(typing).items()
+183 -51
View File
@@ -11,11 +11,14 @@ import itertools
import operator
import struct
import sys
import textwrap
import unicodedata
import unittest
import warnings
from test.support import import_helper
from test.support import warnings_helper
from test import support, string_tests
from test.support import import_helper, warnings_helper
from test.support.script_helper import assert_python_failure
# Error handling (bad decoder return)
def search_function(encoding):
@@ -33,7 +36,6 @@ def search_function(encoding):
return (encode2, decode2, None, None)
else:
return None
codecs.register(search_function)
def duplicate_string(text):
"""
@@ -55,6 +57,10 @@ class UnicodeTest(string_tests.CommonTest,
type2test = str
def setUp(self):
codecs.register(search_function)
self.addCleanup(codecs.unregister, search_function)
def checkequalnofix(self, result, object, methodname, *args):
method = getattr(object, methodname)
realresult = method(*args)
@@ -505,6 +511,28 @@ class UnicodeTest(string_tests.CommonTest,
text = 'abc def'
self.assertIs(text.replace(pattern, pattern), text)
def test_repeat_id_preserving(self):
a = '123abc1@'
b = '456zyx-+'
self.assertEqual(id(a), id(a))
self.assertNotEqual(id(a), id(b))
self.assertNotEqual(id(a), id(a * -4))
self.assertNotEqual(id(a), id(a * 0))
self.assertEqual(id(a), id(a * 1))
self.assertEqual(id(a), id(1 * a))
self.assertNotEqual(id(a), id(a * 2))
class SubStr(str):
pass
s = SubStr('qwerty()')
self.assertEqual(id(s), id(s))
self.assertNotEqual(id(s), id(s * -4))
self.assertNotEqual(id(s), id(s * 0))
self.assertNotEqual(id(s), id(s * 1))
self.assertNotEqual(id(s), id(1 * s))
self.assertNotEqual(id(s), id(s * 2))
def test_bytes_comparison(self):
with warnings_helper.check_warnings():
warnings.simplefilter('ignore', BytesWarning)
@@ -728,6 +756,16 @@ class UnicodeTest(string_tests.CommonTest,
self.assertFalse("©".isidentifier())
self.assertFalse("0".isidentifier())
@support.cpython_only
@support.requires_legacy_unicode_capi
def test_isidentifier_legacy(self):
import _testcapi
u = '𝖀𝖓𝖎𝖈𝖔𝖉𝖊'
self.assertTrue(u.isidentifier())
with warnings_helper.check_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.assertTrue(_testcapi.unicode_legacy_string(u).isidentifier())
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_isprintable(self):
@@ -1103,6 +1141,12 @@ class UnicodeTest(string_tests.CommonTest,
self.assertEqual('{0:^8s}'.format('result'), ' result ')
self.assertEqual('{0:^9s}'.format('result'), ' result ')
self.assertEqual('{0:^10s}'.format('result'), ' result ')
self.assertEqual('{0:8s}'.format('result'), 'result ')
self.assertEqual('{0:0s}'.format('result'), 'result')
self.assertEqual('{0:08s}'.format('result'), 'result00')
self.assertEqual('{0:<08s}'.format('result'), 'result00')
self.assertEqual('{0:>08s}'.format('result'), '00result')
self.assertEqual('{0:^08s}'.format('result'), '0result0')
self.assertEqual('{0:10000}'.format('a'), 'a' + ' ' * 9999)
self.assertEqual('{0:10000}'.format(''), ' ' * 10000)
self.assertEqual('{0:10000000}'.format(''), ' ' * 10000000)
@@ -1230,8 +1274,11 @@ class UnicodeTest(string_tests.CommonTest,
0, 1, 2, 3, 4, 5, 6, 7)
# string format spec errors
self.assertRaises(ValueError, "{0:-s}".format, '')
self.assertRaises(ValueError, format, "", "-")
sign_msg = "Sign not allowed in string format specifier"
self.assertRaisesRegex(ValueError, sign_msg, "{0:-s}".format, '')
self.assertRaisesRegex(ValueError, sign_msg, format, "", "-")
space_msg = "Space not allowed in string format specifier"
self.assertRaisesRegex(ValueError, space_msg, "{: }".format, '')
self.assertRaises(ValueError, "{0:=s}".format, '')
# Alternate formatting is not supported
@@ -1789,7 +1836,7 @@ class UnicodeTest(string_tests.CommonTest,
# Issue #8271: during the decoding of an invalid UTF-8 byte sequence,
# only the start byte and the continuation byte(s) are now considered
# invalid, instead of the number of bytes specified by the start byte.
# See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (page 95,
# See https://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (page 95,
# table 3-8, Row 2) for more information about the algorithm used.
FFFD = '\ufffd'
sequences = [
@@ -2247,22 +2294,6 @@ class UnicodeTest(string_tests.CommonTest,
self.assertEqual(("abc" "def" "ghi"), "abcdefghi")
self.assertEqual(("abc" "def" "ghi"), "abcdefghi")
def test_printing(self):
class BitBucket:
def write(self, text):
pass
out = BitBucket()
print('abc', file=out)
print('abc', 'def', file=out)
print('abc', 'def', file=out)
print('abc', 'def', file=out)
print('abc\n', file=out)
print('abc\n', end=' ', file=out)
print('abc\n', end=' ', file=out)
print('def\n', file=out)
print('def\n', file=out)
def test_ucs4(self):
x = '\U00100000'
y = x.encode("raw-unicode-escape").decode("raw-unicode-escape")
@@ -2400,6 +2431,7 @@ class UnicodeTest(string_tests.CommonTest,
self.assertEqual(len(args), 1)
@support.cpython_only
@support.requires_legacy_unicode_capi
def test_resize(self):
from _testcapi import getargs_u
for length in range(1, 100, 7):
@@ -2407,12 +2439,14 @@ class UnicodeTest(string_tests.CommonTest,
text = 'a' * length + 'b'
# fill wstr internal field
abc = getargs_u(text)
with self.assertWarns(DeprecationWarning):
abc = getargs_u(text)
self.assertEqual(abc, text)
# resize text: wstr field must be cleared and then recomputed
text += 'c'
abcdef = getargs_u(text)
with self.assertWarns(DeprecationWarning):
abcdef = getargs_u(text)
self.assertNotEqual(abc, abcdef)
self.assertEqual(abcdef, text)
@@ -2496,6 +2530,68 @@ class UnicodeTest(string_tests.CommonTest,
support.check_free_after_iterating(self, iter, str)
support.check_free_after_iterating(self, reversed, str)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_check_encoding_errors(self):
# bpo-37388: str(bytes) and str.decode() must check encoding and errors
# arguments in dev mode
encodings = ('ascii', 'utf8', 'latin1')
invalid = 'Boom, Shaka Laka, Boom!'
code = textwrap.dedent(f'''
import sys
encodings = {encodings!r}
for data in (b'', b'short string'):
try:
str(data, encoding={invalid!r})
except LookupError:
pass
else:
sys.exit(21)
try:
str(data, errors={invalid!r})
except LookupError:
pass
else:
sys.exit(22)
for encoding in encodings:
try:
str(data, encoding, errors={invalid!r})
except LookupError:
pass
else:
sys.exit(22)
for data in ('', 'short string'):
try:
data.encode(encoding={invalid!r})
except LookupError:
pass
else:
sys.exit(23)
try:
data.encode(errors={invalid!r})
except LookupError:
pass
else:
sys.exit(24)
for encoding in encodings:
try:
data.encode(encoding, errors={invalid!r})
except LookupError:
pass
else:
sys.exit(24)
sys.exit(10)
''')
proc = assert_python_failure('-X', 'dev', '-c', code)
self.assertEqual(proc.rc, 10, proc)
class CAPITest(unittest.TestCase):
@@ -2503,11 +2599,13 @@ class CAPITest(unittest.TestCase):
def test_from_format(self):
import_helper.import_module('ctypes')
from ctypes import (
c_char_p,
pythonapi, py_object, sizeof,
c_int, c_long, c_longlong, c_ssize_t,
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
name = "PyUnicode_FromFormat"
_PyUnicode_FromFormat = getattr(pythonapi, name)
_PyUnicode_FromFormat.argtypes = (c_char_p,)
_PyUnicode_FromFormat.restype = py_object
def PyUnicode_FromFormat(format, *args):
@@ -2807,15 +2905,43 @@ class CAPITest(unittest.TestCase):
for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600',
'a\ud800b\udfffc', '\ud834\udd1e']:
l = len(s)
self.assertEqual(unicode_asucs4(s, l, 1), s+'\0')
self.assertEqual(unicode_asucs4(s, l, 0), s+'\uffff')
self.assertEqual(unicode_asucs4(s, l+1, 1), s+'\0\uffff')
self.assertEqual(unicode_asucs4(s, l+1, 0), s+'\0\uffff')
self.assertRaises(SystemError, unicode_asucs4, s, l-1, 1)
self.assertRaises(SystemError, unicode_asucs4, s, l-2, 0)
self.assertEqual(unicode_asucs4(s, l, True), s+'\0')
self.assertEqual(unicode_asucs4(s, l, False), s+'\uffff')
self.assertEqual(unicode_asucs4(s, l+1, True), s+'\0\uffff')
self.assertEqual(unicode_asucs4(s, l+1, False), s+'\0\uffff')
self.assertRaises(SystemError, unicode_asucs4, s, l-1, True)
self.assertRaises(SystemError, unicode_asucs4, s, l-2, False)
s = '\0'.join([s, s])
self.assertEqual(unicode_asucs4(s, len(s), 1), s+'\0')
self.assertEqual(unicode_asucs4(s, len(s), 0), s+'\uffff')
self.assertEqual(unicode_asucs4(s, len(s), True), s+'\0')
self.assertEqual(unicode_asucs4(s, len(s), False), s+'\uffff')
# Test PyUnicode_AsUTF8()
@support.cpython_only
def test_asutf8(self):
from _testcapi import unicode_asutf8
bmp = '\u0100'
bmp2 = '\uffff'
nonbmp = chr(0x10ffff)
self.assertEqual(unicode_asutf8(bmp), b'\xc4\x80')
self.assertEqual(unicode_asutf8(bmp2), b'\xef\xbf\xbf')
self.assertEqual(unicode_asutf8(nonbmp), b'\xf4\x8f\xbf\xbf')
self.assertRaises(UnicodeEncodeError, unicode_asutf8, 'a\ud800b\udfffc')
# Test PyUnicode_AsUTF8AndSize()
@support.cpython_only
def test_asutf8andsize(self):
from _testcapi import unicode_asutf8andsize
bmp = '\u0100'
bmp2 = '\uffff'
nonbmp = chr(0x10ffff)
self.assertEqual(unicode_asutf8andsize(bmp), (b'\xc4\x80', 2))
self.assertEqual(unicode_asutf8andsize(bmp2), (b'\xef\xbf\xbf', 3))
self.assertEqual(unicode_asutf8andsize(nonbmp), (b'\xf4\x8f\xbf\xbf', 4))
self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, 'a\ud800b\udfffc')
# Test PyUnicode_FindChar()
@support.cpython_only
@@ -2884,32 +3010,38 @@ class CAPITest(unittest.TestCase):
self.assertRaises(SystemError, unicode_copycharacters, s, 0, b'', 0, 0)
@support.cpython_only
@support.requires_legacy_unicode_capi
def test_encode_decimal(self):
from _testcapi import unicode_encodedecimal
self.assertEqual(unicode_encodedecimal('123'),
b'123')
self.assertEqual(unicode_encodedecimal('\u0663.\u0661\u0664'),
b'3.14')
self.assertEqual(unicode_encodedecimal("\N{EM SPACE}3.14\N{EN SPACE}"),
b' 3.14 ')
self.assertRaises(UnicodeEncodeError,
unicode_encodedecimal, "123\u20ac", "strict")
self.assertRaisesRegex(
ValueError,
"^'decimal' codec can't encode character",
unicode_encodedecimal, "123\u20ac", "replace")
with warnings_helper.check_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.assertEqual(unicode_encodedecimal('123'),
b'123')
self.assertEqual(unicode_encodedecimal('\u0663.\u0661\u0664'),
b'3.14')
self.assertEqual(unicode_encodedecimal(
"\N{EM SPACE}3.14\N{EN SPACE}"), b' 3.14 ')
self.assertRaises(UnicodeEncodeError,
unicode_encodedecimal, "123\u20ac", "strict")
self.assertRaisesRegex(
ValueError,
"^'decimal' codec can't encode character",
unicode_encodedecimal, "123\u20ac", "replace")
@support.cpython_only
@support.requires_legacy_unicode_capi
def test_transform_decimal(self):
from _testcapi import unicode_transformdecimaltoascii as transform_decimal
self.assertEqual(transform_decimal('123'),
'123')
self.assertEqual(transform_decimal('\u0663.\u0661\u0664'),
'3.14')
self.assertEqual(transform_decimal("\N{EM SPACE}3.14\N{EN SPACE}"),
"\N{EM SPACE}3.14\N{EN SPACE}")
self.assertEqual(transform_decimal('123\u20ac'),
'123\u20ac')
with warnings_helper.check_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.assertEqual(transform_decimal('123'),
'123')
self.assertEqual(transform_decimal('\u0663.\u0661\u0664'),
'3.14')
self.assertEqual(transform_decimal("\N{EM SPACE}3.14\N{EN SPACE}"),
"\N{EM SPACE}3.14\N{EN SPACE}")
self.assertEqual(transform_decimal('123\u20ac'),
'123\u20ac')
@support.cpython_only
def test_pep393_utf8_caching_bug(self):
+6 -14
View File
@@ -5,9 +5,9 @@ import sys
import unittest
import warnings
from unicodedata import normalize
from test import support
from test.support import os_helper
filenames = [
'1_abc',
'2_ascii',
@@ -151,7 +151,8 @@ class UnicodeFileTests(unittest.TestCase):
sf0 = set(self.files)
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
f1 = os.listdir(os_helper.TESTFN.encode(sys.getfilesystemencoding()))
f1 = os.listdir(os_helper.TESTFN.encode(
sys.getfilesystemencoding()))
f2 = os.listdir(os_helper.TESTFN)
sf2 = set(os.path.join(os_helper.TESTFN, f) for f in f2)
self.assertEqual(sf0, sf2, "%a != %a" % (sf0, sf2))
@@ -163,7 +164,8 @@ class UnicodeFileTests(unittest.TestCase):
os.rename("tmp", name)
def test_directory(self):
dirname = os.path.join(os_helper.TESTFN, 'Gr\xfc\xdf-\u66e8\u66e9\u66eb')
dirname = os.path.join(os_helper.TESTFN,
'Gr\xfc\xdf-\u66e8\u66e9\u66eb')
filename = '\xdf-\u66e8\u66e9\u66eb'
with os_helper.temp_cwd(dirname):
with open(filename, 'wb') as f:
@@ -188,15 +190,5 @@ class UnicodeNFKDFileTests(UnicodeFileTests):
normal_form = 'NFKD'
def test_main():
support.run_unittest(
UnicodeFileTests,
UnicodeNFCFileTests,
UnicodeNFDFileTests,
UnicodeNFKCFileTests,
UnicodeNFKDFileTests,
)
if __name__ == "__main__":
test_main()
unittest.main()
+5 -3
View File
@@ -26,9 +26,11 @@ class PEP3131Test(unittest.TestCase):
def test_invalid(self):
try:
from test import badsyntax_3131
except SyntaxError as s:
self.assertEqual(str(s),
"invalid character in identifier (badsyntax_3131.py, line 2)")
except SyntaxError as err:
self.assertEqual(str(err),
"invalid character '€' (U+20AC) (badsyntax_3131.py, line 2)")
self.assertEqual(err.lineno, 2)
self.assertEqual(err.offset, 1)
else:
self.fail("expected exception didn't occur")
+4 -5
View File
@@ -30,8 +30,8 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol):
self.assertEqual(collections.UserDict(one=1, two=2), d2)
# item sequence constructor
self.assertEqual(collections.UserDict([('one',1), ('two',2)]), d2)
with self.assertWarnsRegex(DeprecationWarning, "'dict'"):
self.assertEqual(collections.UserDict(dict=[('one',1), ('two',2)]), d2)
self.assertEqual(collections.UserDict(dict=[('one',1), ('two',2)]),
{'dict': [('one', 1), ('two', 2)]})
# both together
self.assertEqual(collections.UserDict([('one',1), ('two',2)], two=3, three=5), d3)
@@ -149,9 +149,8 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol):
[('dict', 42)])
self.assertEqual(list(collections.UserDict({}, dict=None).items()),
[('dict', None)])
with self.assertWarnsRegex(DeprecationWarning, "'dict'"):
self.assertEqual(list(collections.UserDict(dict={'a': 42}).items()),
[('a', 42)])
self.assertEqual(list(collections.UserDict(dict={'a': 42}).items()),
[('dict', {'a': 42})])
self.assertRaises(TypeError, collections.UserDict, 42)
self.assertRaises(TypeError, collections.UserDict, (), ())
self.assertRaises(TypeError, collections.UserDict.__init__)
+10
View File
@@ -11,6 +11,16 @@ class UserListTest(list_tests.CommonTest):
def test_init(self):
super().test_init()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_contains_fake(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_contains_fake()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_count(self): # XXX: RUSTPYTHON; the method also need to be removed when done
super().test_count()
# TODO: RUSTPYTHON, parent method is marked but this version passes
import sys
@unittest.skipIf(sys.platform == "win32", "TODO: RUSTPYTHON, unexpectedly panics somewhere")
+79 -22
View File
@@ -18,6 +18,7 @@ from test import support
from test.support import os_helper
from test.support import socket_helper
from test.support import threading_helper
from test.support import ALWAYS_EQ, LARGEST, SMALLEST
try:
import gzip
@@ -559,14 +560,10 @@ class DateTimeTestCase(unittest.TestCase):
# some other types
dbytes = dstr.encode('ascii')
dtuple = now.timetuple()
with self.assertRaises(TypeError):
dtime == 1970
with self.assertRaises(TypeError):
dtime != dbytes
with self.assertRaises(TypeError):
dtime == bytearray(dbytes)
with self.assertRaises(TypeError):
dtime != dtuple
self.assertFalse(dtime == 1970)
self.assertTrue(dtime != dbytes)
self.assertFalse(dtime == bytearray(dbytes))
self.assertTrue(dtime != dtuple)
with self.assertRaises(TypeError):
dtime < float(1970)
with self.assertRaises(TypeError):
@@ -576,9 +573,21 @@ class DateTimeTestCase(unittest.TestCase):
with self.assertRaises(TypeError):
dtime >= dtuple
self.assertTrue(dtime == ALWAYS_EQ)
self.assertFalse(dtime != ALWAYS_EQ)
self.assertTrue(dtime < LARGEST)
self.assertFalse(dtime > LARGEST)
self.assertTrue(dtime <= LARGEST)
self.assertFalse(dtime >= LARGEST)
self.assertFalse(dtime < SMALLEST)
self.assertTrue(dtime > SMALLEST)
self.assertFalse(dtime <= SMALLEST)
self.assertTrue(dtime >= SMALLEST)
class BinaryTestCase(unittest.TestCase):
# XXX What should str(Binary(b"\xff")) return? I'm chosing "\xff"
# XXX What should str(Binary(b"\xff")) return? I'm choosing "\xff"
# for now (i.e. interpreting the binary data as Latin-1-encoded
# text). But this feels very unsatisfactory. Perhaps we should
# only define repr(), and return r"Binary(b'\xff')" instead?
@@ -665,7 +674,7 @@ def http_server(evt, numrequests, requestHandler=None, encoding=None):
serv.handle_request()
numrequests -= 1
except socket.timeout:
except TimeoutError:
pass
finally:
serv.socket.close()
@@ -715,11 +724,16 @@ def http_multi_server(evt, numrequests, requestHandler=None):
#on AF_INET only.
URL = "http://%s:%d"%(ADDR, PORT)
serv.server_activate()
paths = ["/foo", "/foo/bar"]
paths = [
"/foo", "/foo/bar",
"/foo?k=v", "/foo#frag", "/foo?k=v#frag",
"", "/", "/RPC2", "?k=v", "#frag",
]
for path in paths:
d = serv.add_dispatcher(path, xmlrpc.server.SimpleXMLRPCDispatcher())
d.register_introspection_functions()
d.register_multicall_functions()
d.register_function(lambda p=path: p, 'test')
serv.get_dispatcher(paths[0]).register_function(pow)
serv.get_dispatcher(paths[1]).register_function(lambda x,y: x+y, 'add')
serv.add_dispatcher("/is/broken", BrokenDispatcher())
@@ -730,7 +744,7 @@ def http_multi_server(evt, numrequests, requestHandler=None):
serv.handle_request()
numrequests -= 1
except socket.timeout:
except TimeoutError:
pass
finally:
serv.socket.close()
@@ -1073,6 +1087,55 @@ class MultiPathServerTestCase(BaseServerTestCase):
p = xmlrpclib.ServerProxy(URL+"/is/broken")
self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_invalid_path(self):
p = xmlrpclib.ServerProxy(URL+"/invalid")
self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_path_query_fragment(self):
p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag")
self.assertEqual(p.test(), "/foo?k=v#frag")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_path_fragment(self):
p = xmlrpclib.ServerProxy(URL+"/foo#frag")
self.assertEqual(p.test(), "/foo#frag")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_path_query(self):
p = xmlrpclib.ServerProxy(URL+"/foo?k=v")
self.assertEqual(p.test(), "/foo?k=v")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_empty_path(self):
p = xmlrpclib.ServerProxy(URL)
self.assertEqual(p.test(), "/RPC2")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_root_path(self):
p = xmlrpclib.ServerProxy(URL + "/")
self.assertEqual(p.test(), "/")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_empty_path_query(self):
p = xmlrpclib.ServerProxy(URL + "?k=v")
self.assertEqual(p.test(), "?k=v")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_empty_path_fragment(self):
p = xmlrpclib.ServerProxy(URL + "#frag")
self.assertEqual(p.test(), "#frag")
#A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism
#does indeed serve subsequent requests on the same connection
class BaseKeepaliveServerTestCase(BaseServerTestCase):
@@ -1544,16 +1607,10 @@ class UseBuiltinTypesTestCase(unittest.TestCase):
self.assertTrue(server.use_builtin_types)
@threading_helper.reap_threads
def test_main():
support.run_unittest(XMLRPCTestCase, HelperTestCase, DateTimeTestCase,
BinaryTestCase, FaultTestCase, UseBuiltinTypesTestCase,
SimpleServerTestCase, SimpleServerEncodingTestCase,
KeepaliveServerTestCase1, KeepaliveServerTestCase2,
GzipServerTestCase, GzipUtilTestCase, HeadersServerTestCase,
MultiPathServerTestCase, ServerProxyTestCase, FailingServerTestCase,
CGIHandlerTestCase, SimpleXMLRPCDispatcherTestCase)
def setUpModule():
thread_info = threading_helper.threading_setup()
unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info)
if __name__ == "__main__":
test_main()
unittest.main()
+26 -12
View File
@@ -265,16 +265,22 @@ boolean = Boolean = bool
# Issue #13305: different format codes across platforms
_day0 = datetime(1, 1, 1)
if _day0.strftime('%Y') == '0001': # Mac OS X
def _try(fmt):
try:
return _day0.strftime(fmt) == '0001'
except ValueError:
return False
if _try('%Y'): # Mac OS X
def _iso8601_format(value):
return value.strftime("%Y%m%dT%H:%M:%S")
elif _day0.strftime('%4Y') == '0001': # Linux
elif _try('%4Y'): # Linux
def _iso8601_format(value):
return value.strftime("%4Y%m%dT%H:%M:%S")
else:
def _iso8601_format(value):
return value.strftime("%Y%m%dT%H:%M:%S").zfill(17)
del _day0
del _try
def _strftime(value):
@@ -314,31 +320,38 @@ class DateTime:
s = self.timetuple()
o = other.timetuple()
else:
otype = (hasattr(other, "__class__")
and other.__class__.__name__
or type(other))
raise TypeError("Can't compare %s and %s" %
(self.__class__.__name__, otype))
s = self
o = NotImplemented
return s, o
def __lt__(self, other):
s, o = self.make_comparable(other)
if o is NotImplemented:
return NotImplemented
return s < o
def __le__(self, other):
s, o = self.make_comparable(other)
if o is NotImplemented:
return NotImplemented
return s <= o
def __gt__(self, other):
s, o = self.make_comparable(other)
if o is NotImplemented:
return NotImplemented
return s > o
def __ge__(self, other):
s, o = self.make_comparable(other)
if o is NotImplemented:
return NotImplemented
return s >= o
def __eq__(self, other):
s, o = self.make_comparable(other)
if o is NotImplemented:
return NotImplemented
return s == o
def timetuple(self):
@@ -436,7 +449,7 @@ class ExpatParser:
target.xml(encoding, None)
def feed(self, data):
self._parser.Parse(data, 0)
self._parser.Parse(data, False)
def close(self):
try:
@@ -1415,15 +1428,16 @@ class ServerProxy:
# establish a "logical" server connection
# get the url
type, uri = urllib.parse._splittype(uri)
if type not in ("http", "https"):
p = urllib.parse.urlsplit(uri)
if p.scheme not in ("http", "https"):
raise OSError("unsupported XML-RPC protocol")
self.__host, self.__handler = urllib.parse._splithost(uri)
self.__host = p.netloc
self.__handler = urllib.parse.urlunsplit(["", "", *p[2:]])
if not self.__handler:
self.__handler = "/RPC2"
if transport is None:
if type == "https":
if p.scheme == "https":
handler = SafeTransport
extra_kwargs = {"context": context}
else:
+2 -2
View File
@@ -732,7 +732,7 @@ class ServerHTMLDoc(pydoc.HTMLDoc):
# hyperlinking of arbitrary strings being used as method
# names. Only methods with names consisting of word characters
# and '.'s are hyperlinked.
pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
pattern = re.compile(r'\b((http|https|ftp)://\S+[\w/]|'
r'RFC[- ]?(\d+)|'
r'PEP[- ]?(\d+)|'
r'(self\.)?((?:\w|\.)+))\b')
@@ -750,7 +750,7 @@ class ServerHTMLDoc(pydoc.HTMLDoc):
url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
results.append('<a href="%s">%s</a>' % (url, escape(all)))
elif pep:
url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep)
url = 'https://www.python.org/dev/peps/pep-%04d/' % int(pep)
results.append('<a href="%s">%s</a>' % (url, escape(all)))
elif text[end:end+1] == '(':
results.append(self.namelink(name, methods, funcs, classes))