Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit