Author: Armin Rigo <[email protected]>
Branch: py3.6
Changeset: r97268:08f03166561f
Date: 2019-08-26 17:06 +0200
http://bitbucket.org/pypy/pypy/changeset/08f03166561f/
Log: merge heads
diff --git a/lib-python/3/test/list_tests.py b/lib-python/3/test/list_tests.py
--- a/lib-python/3/test/list_tests.py
+++ b/lib-python/3/test/list_tests.py
@@ -546,7 +546,7 @@
u += "eggs"
self.assertEqual(u, self.type2test("spameggs"))
- self.assertRaises(TypeError, u.__iadd__, None)
+ self.assertRaises(TypeError, "u += None") # PyPy change
def test_imul(self):
u = self.type2test([0, 1])
diff --git a/lib-python/3/test/test_asyncio/test_futures.py
b/lib-python/3/test/test_asyncio/test_futures.py
--- a/lib-python/3/test/test_asyncio/test_futures.py
+++ b/lib-python/3/test/test_asyncio/test_futures.py
@@ -534,7 +534,7 @@
@unittest.skipUnless(hasattr(futures, '_CFuture'),
'requires the C _asyncio module')
class CFutureTests(BaseFutureTests, test_utils.TestCase):
- cls = getattr(futures, '_CFuture')
+ cls = getattr(futures, '_CFuture', None)
class PyFutureTests(BaseFutureTests, test_utils.TestCase):
diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -108,27 +108,29 @@
# array accepts very strange parameters as part of structure
# or function argument...
from ctypes import c_char, c_wchar
- if issubclass(self._type_, c_char):
- if isinstance(value, bytes):
- if len(value) > self._length_:
- raise ValueError("Invalid length")
- value = self(*value)
- elif not isinstance(value, self):
- raise TypeError("expected bytes, %s found"
- % (value.__class__.__name__,))
- elif issubclass(self._type_, c_wchar):
- if isinstance(value, str):
- if len(value) > self._length_:
- raise ValueError("Invalid length")
- value = self(*value)
- elif not isinstance(value, self):
- raise TypeError("expected unicode string, %s found"
- % (value.__class__.__name__,))
- else:
- if isinstance(value, tuple):
- if len(value) > self._length_:
- raise RuntimeError("Invalid length")
- value = self(*value)
+ if isinstance(value, self):
+ return value
+ if hasattr(self, '_type_'):
+ if issubclass(self._type_, c_char):
+ if isinstance(value, bytes):
+ if len(value) > self._length_:
+ raise ValueError("Invalid length")
+ value = self(*value)
+ elif not isinstance(value, self):
+ raise TypeError("expected bytes, %s found"
+ % (value.__class__.__name__,))
+ elif issubclass(self._type_, c_wchar):
+ if isinstance(value, str):
+ if len(value) > self._length_:
+ raise ValueError("Invalid length")
+ value = self(*value)
+ elif not isinstance(value, self):
+ raise TypeError("expected unicode string, %s found"
+ % (value.__class__.__name__,))
+ if isinstance(value, tuple):
+ if len(value) > self._length_:
+ raise RuntimeError("Invalid length")
+ value = self(*value)
return _CDataMeta.from_param(self, value)
def _build_ffiargtype(self):
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -45,6 +45,9 @@
self.details = details
class _CDataMeta(type):
+ def _is_abstract(self):
+ return getattr(self, '_type_', 'abstract') == 'abstract'
+
def from_param(self, value):
if isinstance(value, self):
return value
@@ -95,6 +98,8 @@
return self.from_address(dll.__pypy_dll__.getaddressindll(name))
def from_buffer(self, obj, offset=0):
+ if self._is_abstract():
+ raise TypeError('abstract class')
size = self._sizeofinstances()
buf = memoryview(obj)
if buf.nbytes < offset + size:
@@ -111,6 +116,8 @@
return result
def from_buffer_copy(self, obj, offset=0):
+ if self._is_abstract():
+ raise TypeError('abstract class')
size = self._sizeofinstances()
buf = memoryview(obj)
if buf.nbytes < offset + size:
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -40,14 +40,17 @@
def from_param(self, value):
if value is None:
return self(None)
- # If we expect POINTER(<type>), but receive a <type> instance, accept
- # it by calling byref(<type>).
- if isinstance(value, self._type_):
- return byref(value)
- # Array instances are also pointers when the item types are the same.
- if isinstance(value, (_Pointer, Array)):
- if issubclass(type(value)._type_, self._type_):
- return value
+ if isinstance(value, self):
+ return value
+ if hasattr(self, '_type_'):
+ # If we expect POINTER(<type>), but receive a <type> instance,
accept
+ # it by calling byref(<type>).
+ if isinstance(value, self._type_):
+ return byref(value)
+ # Array instances are also pointers when the item types are the
same.
+ if isinstance(value, (_Pointer, Array)):
+ if issubclass(type(value)._type_, self._type_):
+ return value
return _CDataMeta.from_param(self, value)
def _sizeofinstances(self):
@@ -60,6 +63,8 @@
return True
def set_type(self, TP):
+ if self._is_abstract():
+ raise TypeError('abstract class')
ffiarray = _rawffi.Array('P')
def __init__(self, value=None):
if not hasattr(self, '_buffer'):
@@ -179,6 +184,7 @@
klass = type(_Pointer)("LP_%s" % cls,
(_Pointer,),
{})
+ klass._type_ = 'P'
_pointer_type_cache[id(klass)] = klass
return klass
else:
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -158,6 +158,8 @@
break
else:
raise AttributeError("cannot find _type_ attribute")
+ if tp == 'abstract':
+ tp = 'i'
if (not isinstance(tp, str) or
not len(tp) == 1 or
tp not in SIMPLE_TYPE_CHARS):
@@ -341,7 +343,8 @@
def from_param(self, value):
if isinstance(value, self):
return value
-
+ if self._type_ == 'abstract':
+ raise TypeError('abstract class')
from_param_f = FROM_PARAM_BY_TYPE.get(self._type_)
if from_param_f:
res = from_param_f(self, value)
@@ -371,7 +374,7 @@
return self._type_ in "sPzUZXO"
class _SimpleCData(_CData, metaclass=SimpleType):
- _type_ = 'i'
+ _type_ = 'abstract'
def __init__(self, value=DEFAULT_VALUE):
if not hasattr(self, '_buffer'):
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -119,6 +119,8 @@
if self.is_bitfield:
# bitfield member, use direct access
return obj._buffer.__getattr__(self.name)
+ elif not isinstance(obj, _CData):
+ raise(TypeError, 'not a ctype instance')
else:
fieldtype = self.ctype
offset = self.num
@@ -142,6 +144,8 @@
from ctypes import memmove
dest = obj._buffer.fieldaddress(self.name)
memmove(dest, arg, fieldtype._fficompositesize_)
+ elif not isinstance(obj, _CData):
+ raise(TypeError, 'not a ctype instance')
else:
obj._buffer.__setattr__(self.name, arg)
@@ -209,6 +213,9 @@
__setattr__ = struct_setattr
+ def _is_abstract(self):
+ return False
+
def from_address(self, address):
instance = StructOrUnion.__new__(self)
if isinstance(address, _rawffi.StructureInstance):
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -296,15 +296,17 @@
"expected %s, got %T object", expected, self)
def int(self, space):
- from pypy.objspace.std.intobject import _new_int
+ from pypy.objspace.std.intobject import W_AbstractIntObject
w_impl = space.lookup(self, '__int__')
if w_impl is None:
self._typed_unwrap_error(space, "integer")
w_result = space.get_and_call_function(w_impl, self)
if space.is_w(space.type(w_result), space.w_int):
+ assert isinstance(w_result, W_AbstractIntObject)
return w_result
if space.isinstance_w(w_result, space.w_int):
+ assert isinstance(w_result, W_AbstractIntObject)
tp = space.type(w_result).name
space.warn(space.newtext(
"__int__ returned non-int (type %s). "
@@ -816,7 +818,7 @@
return self.w_None
return w_obj
- @signature(types.any(), types.bool(), returns=types.instance(W_Root))
+ @signature(types.any(), types.bool(), returns=types.any())
def newbool(self, b):
if b:
return self.w_True
diff --git a/pypy/module/_codecs/interp_codecs.py
b/pypy/module/_codecs/interp_codecs.py
--- a/pypy/module/_codecs/interp_codecs.py
+++ b/pypy/module/_codecs/interp_codecs.py
@@ -618,10 +618,10 @@
# ____________________________________________________________
# Helpers for unicode.encode() and bytes.decode()
def lookup_text_codec(space, action, encoding):
- codec_info = lookup_codec(space, encoding)
+ w_codec_info = lookup_codec(space, encoding)
try:
is_text_encoding = space.is_true(
- space.getattr(codec_info, space.newtext('_is_text_encoding')))
+ space.getattr(w_codec_info,
space.newtext('_is_text_encoding')))
except OperationError as e:
if e.match(space, space.w_AttributeError):
is_text_encoding = True
@@ -630,8 +630,8 @@
if not is_text_encoding:
raise oefmt(space.w_LookupError,
"'%s' is not a text encoding; "
- "use %s to handle arbitrary codecs", encoding, action)
- return codec_info
+ "use codecs.%s() to handle arbitrary codecs", encoding,
action)
+ return w_codec_info
# ____________________________________________________________
diff --git a/pypy/module/_io/interp_bufferedio.py
b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -319,7 +319,6 @@
with self.lock:
if self.writable:
self._writer_flush_unlocked(space)
- self._writer_reset_buf()
if whence == 1:
pos -= self._raw_offset()
@@ -371,6 +370,7 @@
def _writer_flush_unlocked(self, space):
if self.write_end == -1 or self.write_pos == self.write_end:
+ self._writer_reset_buf()
return
# First, rewind
rewind = self._raw_offset() + (self.pos - self.write_pos)
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -266,24 +266,16 @@
def readlines_w(self, space, w_hint=None):
hint = convert_size(space, w_hint)
-
if hint <= 0:
return space.newlist(space.unpackiterable(self))
+ length = 0
lines_w = []
- length = 0
- while True:
- w_line = space.call_method(self, "readline")
- line_length = space.len_w(w_line)
- if line_length == 0: # done
- break
-
+ for w_line in space.iteriterable(self):
lines_w.append(w_line)
-
- length += line_length
+ length += space.len_w(w_line)
if length > hint:
break
-
return space.newlist(lines_w)
def writelines_w(self, space, w_lines):
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -663,12 +663,15 @@
# To prepare for tell(), we need to snapshot a point in the file
# where the decoder's input buffer is empty.
w_state = space.call_method(self.w_decoder, "getstate")
+ if (not space.isinstance_w(w_state, space.w_tuple)
+ or space.len_w(w_state) != 2):
+ raise oefmt(space.w_TypeError, "illegal decoder state")
# Given this, we know there was a valid snapshot point
# len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
w_dec_buffer, w_dec_flags = space.unpackiterable(w_state, 2)
if not space.isinstance_w(w_dec_buffer, space.w_bytes):
- msg = "decoder getstate() should have returned a bytes " \
- "object not '%T'"
+ msg = ("illegal decoder state: the first value should be a "
+ "bytes object not '%T'")
raise oefmt(space.w_TypeError, msg, w_dec_buffer)
dec_buffer = space.bytes_w(w_dec_buffer)
dec_flags = space.int_w(w_dec_flags)
diff --git a/pypy/module/_io/test/test_bufferedio.py
b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -513,6 +513,17 @@
assert b.truncate() == 8
assert b.tell() == 8
+ def test_truncate_after_write(self):
+ import _io
+ raw = _io.FileIO(self.tmpfile, 'rb+')
+ raw.write(b'\x00' * 50)
+ raw.seek(0)
+ b = _io.BufferedRandom(raw, 10)
+ b.write(b'\x00' * 11)
+ b.read(1)
+ b.truncate()
+ assert b.tell() == 12
+
def test_write_non_blocking(self):
import _io, io
class MockNonBlockWriterIO(io.RawIOBase):
diff --git a/pypy/module/select/interp_epoll.py
b/pypy/module/select/interp_epoll.py
--- a/pypy/module/select/interp_epoll.py
+++ b/pypy/module/select/interp_epoll.py
@@ -87,10 +87,12 @@
self.register_finalizer(space)
@unwrap_spec(sizehint=int, flags=int)
- def descr__new__(space, w_subtype, sizehint=0, flags=0):
- if sizehint < 0: # 'sizehint' is otherwise ignored
+ def descr__new__(space, w_subtype, sizehint=-1, flags=0):
+ if sizehint == -1:
+ sizehint = FD_SETSIZE - 1
+ elif sizehint <= 0: # 'sizehint' is otherwise ignored
raise oefmt(space.w_ValueError,
- "sizehint must be greater than zero, got %d", sizehint)
+ "sizehint must be positive or -1")
epfd = epoll_create1(flags | EPOLL_CLOEXEC)
if epfd < 0:
raise exception_from_saved_errno(space, space.w_IOError)
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -9,7 +9,7 @@
import sys
from rpython.rlib import jit
-from rpython.rlib.objectmodel import instantiate
+from rpython.rlib.objectmodel import instantiate, enforceargs
from rpython.rlib.rarithmetic import (
LONG_BIT, intmask, is_valid_int, ovfcheck, r_longlong, r_uint,
string_to_int)
@@ -851,80 +851,49 @@
sys.maxint == 2147483647)
-def _string_to_int_or_long(space, w_inttype, w_source, string, base=10):
+def _string_to_int_or_long(space, w_source, string, base=10):
try:
- value = string_to_int(string, base, allow_underscores=True,
no_implicit_octal=True)
+ value = string_to_int(
+ string, base, allow_underscores=True, no_implicit_octal=True)
+ return wrapint(space, value)
except ParseStringError as e:
raise wrap_parsestringerror(space, e, w_source)
except ParseStringOverflowError as e:
- return _retry_to_w_long(space, e.parser, w_inttype, w_source)
+ return _retry_to_w_long(space, e.parser, w_source)
- if space.is_w(w_inttype, space.w_int):
- w_result = wrapint(space, value)
- else:
- w_result = space.allocate_instance(W_IntObject, w_inttype)
- W_IntObject.__init__(w_result, value)
- return w_result
-
-def _retry_to_w_long(space, parser, w_inttype, w_source):
+def _retry_to_w_long(space, parser, w_source):
from pypy.objspace.std.longobject import newbigint
parser.rewind()
try:
bigint = rbigint._from_numberstring_parser(parser)
except ParseStringError as e:
raise wrap_parsestringerror(space, e, w_source)
- return newbigint(space, w_inttype, bigint)
+ return newbigint(space, space.w_int, bigint)
def _new_int(space, w_inttype, w_x, w_base=None):
- from pypy.objspace.std.longobject import (
- W_AbstractLongObject, W_LongObject, newlong, newbigint)
- if space.config.objspace.std.withsmalllong:
- from pypy.objspace.std.smalllongobject import W_SmallLongObject
+ w_value = w_x # 'x' is the keyword argument name in CPython
+ if w_inttype is space.w_int:
+ return _new_baseint(space, w_x, w_base)
else:
- W_SmallLongObject = None
+ w_tmp = _new_baseint(space, w_x, w_base)
+ return _as_subint(space, w_inttype, w_tmp)
- w_longval = None
- w_value = w_x # 'x' is the keyword argument name in CPython
- value = 0
+def _new_baseint(space, w_value, w_base=None):
if w_base is None:
- #import pdb; pdb.set_trace()
- # check for easy cases
- if type(w_value) is W_IntObject:
- if space.is_w(w_inttype, space.w_int):
- return w_value
- value = w_value.intval
- w_obj = space.allocate_instance(W_IntObject, w_inttype)
- W_IntObject.__init__(w_obj, value)
- return w_obj
- elif type(w_value) is W_LongObject:
- if space.is_w(w_inttype, space.w_int):
- return w_value
- return newbigint(space, w_inttype, w_value.num)
- elif W_SmallLongObject and type(w_value) is W_SmallLongObject:
- if space.is_w(w_inttype, space.w_int):
- return w_value
- return newbigint(space, w_inttype, space.bigint_w(w_value))
+ if space.is_w(space.type(w_value), space.w_int):
+ assert isinstance(w_value, W_AbstractIntObject)
+ return w_value
elif space.lookup(w_value, '__int__') is not None:
w_intvalue = space.int(w_value)
- if isinstance(w_intvalue, W_IntObject):
- if type(w_intvalue) is not W_IntObject:
- w_intvalue = wrapint(space, w_intvalue.intval)
- return _new_int(space, w_inttype, w_intvalue)
- elif isinstance(w_intvalue, W_AbstractLongObject):
- if type(w_intvalue) is not W_LongObject:
- w_intvalue = newlong(space, w_intvalue.asbigint())
- return _new_int(space, w_inttype, w_intvalue)
- else:
- # shouldn't happen
- raise oefmt(space.w_RuntimeError,
- "internal error in int.__new__()")
+ return _ensure_baseint(space, w_intvalue)
elif space.lookup(w_value, '__trunc__') is not None:
w_obj = space.trunc(w_value)
- if not space.is_w(space.type(w_obj), space.w_int):
+ if not space.isinstance_w(w_obj, space.w_int):
w_obj = space.int(w_obj)
- return _from_intlike(space, w_inttype, w_obj)
+ assert isinstance(w_obj, W_AbstractIntObject)
+ return _ensure_baseint(space, w_obj)
elif space.isinstance_w(w_value, space.w_unicode):
from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
try:
@@ -933,10 +902,10 @@
raise oefmt(space.w_ValueError,
'invalid literal for int() with base 10: %R',
w_value)
- return _string_to_int_or_long(space, w_inttype, w_value, b)
+ return _string_to_int_or_long(space, w_value, b)
elif (space.isinstance_w(w_value, space.w_bytearray) or
space.isinstance_w(w_value, space.w_bytes)):
- return _string_to_int_or_long(space, w_inttype, w_value,
+ return _string_to_int_or_long(space, w_value,
space.charbuf_w(w_value))
else:
# If object supports the buffer interface
@@ -949,7 +918,7 @@
"int() argument must be a string, a bytes-like "
"object or a number, not '%T'", w_value)
else:
- return _string_to_int_or_long(space, w_inttype, w_value, buf)
+ return _string_to_int_or_long(space, w_value, buf)
else:
try:
base = space.getindex_w(w_base, None)
@@ -973,14 +942,40 @@
raise oefmt(space.w_TypeError,
"int() can't convert non-string with explicit base")
- return _string_to_int_or_long(space, w_inttype, w_value, s, base)
+ return _string_to_int_or_long(space, w_value, s, base)
+@enforceargs(None, None, W_AbstractIntObject, typecheck=False)
+def _as_subint(space, w_inttype, w_value):
+ from pypy.objspace.std.longobject import W_LongObject, newbigint
+ if space.config.objspace.std.withsmalllong:
+ from pypy.objspace.std.smalllongobject import W_SmallLongObject
+ else:
+ W_SmallLongObject = None
+ if type(w_value) is W_IntObject:
+ w_obj = space.allocate_instance(W_IntObject, w_inttype)
+ W_IntObject.__init__(w_obj, w_value.intval)
+ return w_obj
+ elif type(w_value) is W_LongObject:
+ return newbigint(space, w_inttype, w_value.num)
+ elif W_SmallLongObject and type(w_value) is W_SmallLongObject:
+ return newbigint(space, w_inttype, space.bigint_w(w_value))
-def _from_intlike(space, w_inttype, w_intlike):
- if space.is_w(w_inttype, space.w_int):
- return w_intlike
- from pypy.objspace.std.longobject import newbigint
- return newbigint(space, w_inttype, space.bigint_w(w_intlike))
+@enforceargs(None, W_AbstractIntObject, typecheck=False)
+def _ensure_baseint(space, w_intvalue):
+ from pypy.objspace.std.longobject import (
+ W_LongObject, W_AbstractLongObject, newlong)
+ if isinstance(w_intvalue, W_IntObject):
+ if type(w_intvalue) is not W_IntObject:
+ w_intvalue = wrapint(space, w_intvalue.intval)
+ return w_intvalue
+ elif isinstance(w_intvalue, W_AbstractLongObject):
+ if type(w_intvalue) is not W_LongObject:
+ w_intvalue = newlong(space, w_intvalue.asbigint())
+ return w_intvalue
+ else:
+ # shouldn't happen
+ raise oefmt(space.w_RuntimeError,
+ "internal error in int.__new__()")
W_AbstractIntObject.typedef = TypeDef("int",
diff --git a/pypy/objspace/std/test/test_intobject.py
b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -533,6 +533,19 @@
assert n == 1
assert type(n) is int
+ def test_trunc_returns_int_subclass_2(self):
+ class BadInt:
+ def __int__(self):
+ return True
+
+ class TruncReturnsBadInt:
+ def __trunc__(self):
+ return BadInt()
+ bad_int = TruncReturnsBadInt()
+ n = int(bad_int)
+ assert n == 1
+ assert type(n) is int
+
def test_int_before_string(self):
class Integral(str):
def __int__(self):
diff --git a/pypy/objspace/std/test/test_typeobject.py
b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -71,6 +71,22 @@
raises(AttributeError, getattr, type, "__abstractmethods__")
raises(TypeError, "int.__abstractmethods__ = ('abc', )")
+ def test_is_abstract_flag(self):
+ # IS_ABSTRACT flag should always be in sync with
+ # cls.__dict__['__abstractmethods__']
+ FLAG_IS_ABSTRACT = 1 << 20
+
+ class Base:
+ pass
+ Base.__abstractmethods__ = {'x'}
+ assert Base.__flags__ & FLAG_IS_ABSTRACT
+
+ class Derived(Base):
+ pass
+ assert not (Derived.__flags__ & FLAG_IS_ABSTRACT)
+ Derived.__abstractmethods__ = {'x'}
+ assert Derived.__flags__ & FLAG_IS_ABSTRACT
+
def test_attribute_error(self):
class X(object):
__module__ = 'test'
diff --git a/pypy/objspace/std/test/test_unicodeobject.py
b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -780,6 +780,11 @@
raises(UnicodeError, b"\xc2".decode, "utf-8")
assert b'\xe1\x80'.decode('utf-8', 'replace') == "\ufffd"
+ def test_invalid_lookup(self):
+
+ raises(LookupError, u"abcd".encode, "hex")
+ raises(LookupError, b"abcd".decode, "hex")
+
def test_repr_printable(self):
# PEP 3138: __repr__ respects printable characters.
x = '\u027d'
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -816,7 +816,7 @@
return space.call_function(newfunc, w_winner, w_name, w_bases,
w_dict)
w_typetype = w_winner
- name = space.text_w(w_name)
+ name = space.text_w(w_name)
if '\x00' in name:
raise oefmt(space.w_ValueError, "type name must not contain null
characters")
pos = surrogate_in_utf8(name)
@@ -1339,7 +1339,6 @@
if not isinstance(w_base, W_TypeObject):
continue
w_self.flag_cpytype |= w_base.flag_cpytype
- w_self.flag_abstract |= w_base.flag_abstract
if w_self.flag_map_or_seq == '?':
w_self.flag_map_or_seq = w_base.flag_map_or_seq
diff --git a/pypy/objspace/std/unicodeobject.py
b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -1241,7 +1241,7 @@
return encoding, errors
def encode_object(space, w_obj, encoding, errors):
- from pypy.module._codecs.interp_codecs import encode
+ from pypy.module._codecs.interp_codecs import _call_codec,
lookup_text_codec
if errors is None or errors == 'strict':
# fast paths
utf8 = space.utf8_w(w_obj)
@@ -1263,7 +1263,11 @@
a.pos, a.pos + 1)
assert False, "always raises"
return space.newbytes(utf8)
- w_retval = encode(space, w_obj, encoding, errors)
+ if encoding is None:
+ encoding = space.sys.defaultencoding
+ w_codec_info = lookup_text_codec(space, 'encode', encoding)
+ w_encfunc = space.getitem(w_codec_info, space.newint(0))
+ w_retval = _call_codec(space, w_encfunc, w_obj, "encoding", encoding,
errors)
if not space.isinstance_w(w_retval, space.w_bytes):
raise oefmt(space.w_TypeError,
"'%s' encoder returned '%T' instead of 'bytes'; "
@@ -1274,6 +1278,7 @@
def decode_object(space, w_obj, encoding, errors=None):
+ from pypy.module._codecs.interp_codecs import _call_codec,
lookup_text_codec
if errors == 'strict' or errors is None:
# fast paths
if encoding == 'ascii':
@@ -1284,8 +1289,11 @@
s = space.charbuf_w(w_obj)
lgt = unicodehelper.check_utf8_or_raise(space, s)
return space.newutf8(s, lgt)
- from pypy.module._codecs.interp_codecs import decode
- w_retval = decode(space, w_obj, encoding, errors)
+ if encoding is None:
+ encoding = space.sys.defaultencoding
+ w_codec_info = lookup_text_codec(space, 'decode', encoding)
+ w_encfunc = space.getitem(w_codec_info, space.newint(1))
+ w_retval = _call_codec(space, w_encfunc, w_obj, "decoding", encoding,
errors)
if not isinstance(w_retval, W_UnicodeObject):
raise oefmt(space.w_TypeError,
"'%s' decoder returned '%T' instead of 'str'; "
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit