mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Merge pull request #3910 from youknowone/update-container-tests
Update multiple unittests from CPython 3.10.5
This commit is contained in:
39 files changed
+8517
-7224
No files matched your search
Vendored
+102
-30
@@ -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'):
|
||||
|
||||
Vendored
+87
-101
@@ -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))
|
||||
Vendored
+1
@@ -1,2 +1,3 @@
|
||||
from _collections_abc import *
|
||||
from _collections_abc import __all__
|
||||
from _collections_abc import _CallableGenericAlias
|
||||
Vendored
+1
-1
@@ -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)
|
||||
|
||||
Vendored
+150
-142
@@ -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
|
||||
Vendored
+20
-16
@@ -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])
|
||||
|
||||
Vendored
+21
-9
@@ -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):
|
||||
|
||||
Vendored
+327
-331
@@ -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()
|
||||
Vendored
+102
-121
@@ -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')
|
||||
|
||||
|
||||
Vendored
+20
-16
@@ -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()
|
||||
Vendored
+311
-84
@@ -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__":
|
||||
|
||||
Vendored
+26
-2
@@ -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():
|
||||
|
||||
Vendored
+1
-1
@@ -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")
|
||||
|
||||
Vendored
+82
-44
@@ -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)
|
||||
Vendored
+2
-7
@@ -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)
|
||||
|
||||
Vendored
+5783
-5720
File diff suppressed because it is too large.
Load diff
Vendored
+40
-33
@@ -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()
|
||||
Vendored
+34
-39
@@ -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 = """
|
||||
|
||||
Vendored
+234
-3
@@ -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):
|
||||
|
||||
|
||||
Vendored
+18
-1
@@ -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()
|
||||
Vendored
+335
-290
@@ -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()
|
||||
Vendored
+44
-6
@@ -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))
|
||||
|
||||
Vendored
+103
-4
@@ -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__":
|
||||
|
||||
Vendored
+74
@@ -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()
|
||||
Vendored
+5
-2
@@ -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
|
||||
|
||||
|
||||
Vendored
+13
-12
@@ -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())
|
||||
|
||||
|
||||
|
||||
Vendored
+65
-28
@@ -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
|
||||
|
||||
Vendored
-3
@@ -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
|
||||
|
||||
Vendored
+200
-62
@@ -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):
|
||||
|
||||
Vendored
+1
-1
@@ -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
|
||||
|
||||
Vendored
-6
@@ -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()
|
||||
|
||||
Vendored
+183
-51
@@ -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
@@ -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()
|
||||
Vendored
+5
-3
@@ -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")
|
||||
|
||||
|
||||
Vendored
+4
-5
@@ -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__)
|
||||
|
||||
Vendored
+10
@@ -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")
|
||||
|
||||
Vendored
+79
-22
@@ -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()
|
||||
Vendored
+26
-12
@@ -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:
|
||||
|
||||
Vendored
+2
-2
@@ -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))
|
||||
|
||||
Reference in new issue
Block a user