[pypy-commit] pypy pypy3-release-2.3.x: merge py3k
pjenvey
noreply at buildbot.pypy.org
Thu Jun 19 18:17:26 CEST 2014
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: pypy3-release-2.3.x
Changeset: r72102:986752d005bb
Date: 2014-06-19 09:16 -0700
http://bitbucket.org/pypy/pypy/changeset/986752d005bb/
Log: merge py3k
diff --git a/lib_pypy/gdbm.py b/lib_pypy/_gdbm.py
rename from lib_pypy/gdbm.py
rename to lib_pypy/_gdbm.py
--- a/lib_pypy/gdbm.py
+++ b/lib_pypy/_gdbm.py
@@ -1,4 +1,5 @@
import cffi, os
+import sys
ffi = cffi.FFI()
ffi.cdef('''
@@ -46,12 +47,15 @@
# failure must be due to missing gdbm dev libs
raise ImportError('%s: %s' %(e.__class__.__name__, e))
-class error(Exception):
+class error(IOError):
pass
def _fromstr(key):
- if not isinstance(key, str):
- raise TypeError("gdbm mappings have string indices only")
+ if isinstance(key, str):
+ key = key.encode(sys.getdefaultencoding())
+ elif not isinstance(key, bytes):
+ msg = "gdbm mappings have bytes or string indices only, not {!r}"
+ raise TypeError(msg.format(type(key).__name__))
return {'dptr': ffi.new("char[]", key), 'dsize': len(key)}
class gdbm(object):
@@ -98,21 +102,27 @@
return lib.gdbm_exists(self.ll_dbm, _fromstr(key))
has_key = __contains__
- def __getitem__(self, key):
+ def get(self, key, default=None):
self._check_closed()
drec = lib.gdbm_fetch(self.ll_dbm, _fromstr(key))
if not drec.dptr:
- raise KeyError(key)
- res = str(ffi.buffer(drec.dptr, drec.dsize))
+ return default
+ res = bytes(ffi.buffer(drec.dptr, drec.dsize))
lib.free(drec.dptr)
return res
+ def __getitem__(self, key):
+ value = self.get(key)
+ if value is None:
+ raise KeyError(key)
+ return value
+
def keys(self):
self._check_closed()
l = []
key = lib.gdbm_firstkey(self.ll_dbm)
while key.dptr:
- l.append(str(ffi.buffer(key.dptr, key.dsize)))
+ l.append(bytes(ffi.buffer(key.dptr, key.dsize)))
nextkey = lib.gdbm_nextkey(self.ll_dbm, key)
lib.free(key.dptr)
key = nextkey
@@ -122,7 +132,7 @@
self._check_closed()
key = lib.gdbm_firstkey(self.ll_dbm)
if key.dptr:
- res = str(ffi.buffer(key.dptr, key.dsize))
+ res = bytes(ffi.buffer(key.dptr, key.dsize))
lib.free(key.dptr)
return res
@@ -130,7 +140,7 @@
self._check_closed()
key = lib.gdbm_nextkey(self.ll_dbm, _fromstr(key))
if key.dptr:
- res = str(ffi.buffer(key.dptr, key.dsize))
+ res = bytes(ffi.buffer(key.dptr, key.dsize))
lib.free(key.dptr)
return res
@@ -149,7 +159,18 @@
self._check_closed()
lib.gdbm_sync(self.ll_dbm)
+ def setdefault(self, key, default=None):
+ value = self.get(key)
+ if value is not None:
+ return value
+ self[key] = default
+ return default
+
def open(filename, flags='r', mode=0o666):
+ if not isinstance(filename, str):
+ raise TypeError("must be str, not %s" % type(filename).__name__)
+ filename = filename.encode(sys.getdefaultencoding())
+
if flags[0] == 'r':
iflags = lib.GDBM_READER
elif flags[0] == 'w':
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -283,8 +283,7 @@
missing += 1
continue
name = signature.kwonlyargnames[i - co_argcount]
- w_name = self.space.wrap(name)
- w_def = self.space.finditem(w_kw_defs, w_name)
+ w_def = self.space.finditem_str(w_kw_defs, name)
if w_def is not None:
scope_w[i] = w_def
else:
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -36,44 +36,11 @@
def setup(self, w_type, w_value=None):
assert w_type is not None
- from pypy.objspace.std.typeobject import W_TypeObject
self.w_type = w_type
self._w_value = w_value
- # HACK: isinstance(w_type, W_TypeObject) won't translate under
- # the fake objspace, but w_type.__class__ is W_TypeObject does
- # and short circuits to a False constant there, causing the
- # isinstance to be ignored =[
- if (w_type is not None and w_type.__class__ is W_TypeObject and
- isinstance(w_type, W_TypeObject)):
- self.setup_context(w_type.space)
if not we_are_translated():
self.debug_excs = []
- def setup_context(self, space):
- # Implicit exception chaining
- last_operror = space.getexecutioncontext().sys_exc_info()
- if (last_operror is None or
- last_operror is get_cleared_operation_error(space)):
- return
-
- # We must normalize the value right now to check for cycles
- self.normalize_exception(space)
- w_value = self.get_w_value(space)
- w_last_value = last_operror.get_w_value(space)
- if not space.is_w(w_value, w_last_value):
- # Avoid reference cycles through the context chain. This is
- # O(chain length) but context chains are usually very short.
- w_obj = w_last_value
- while True:
- w_context = space.getattr(w_obj, space.wrap('__context__'))
- if space.is_w(w_context, space.w_None):
- break
- if space.is_w(w_context, w_value):
- space.setattr(w_obj, space.wrap('__context__'), space.w_None)
- break
- w_obj = w_context
- space.setattr(w_value, space.wrap('__context__'), w_last_value)
-
def clear(self, space):
# XXX remove this method. The point is that we cannot always
# hack at 'self' to clear w_type and _w_value, because in some
@@ -350,6 +317,53 @@
"""
self._application_traceback = traceback
+ def record_context(self, space, frame):
+ """Record a __context__ for this exception from the current
+ frame if one exists.
+
+ __context__ is otherwise lazily determined from the
+ traceback. However the current frame.last_exception must be
+ checked for a __context__ before this OperationError overwrites
+ it (making the previous last_exception unavailable later on).
+ """
+ last_exception = frame.last_exception
+ if (last_exception is not None and not frame.hide() or
+ last_exception is get_cleared_operation_error(space)):
+ # normalize w_value so setup_context can check for cycles
+ self.normalize_exception(space)
+ w_value = self.get_w_value(space)
+ w_last = last_exception.get_w_value(space)
+ w_context = setup_context(space, w_value, w_last, lazy=True)
+ space.setattr(w_value, space.wrap('__context__'), w_context)
+
+
+def setup_context(space, w_exc, w_last, lazy=False):
+ """Determine the __context__ for w_exc from w_last and break
+ reference cycles in the __context__ chain.
+ """
+ from pypy.module.exceptions.interp_exceptions import W_BaseException
+ if space.is_w(w_exc, w_last):
+ w_last = space.w_None
+ # w_last may also be space.w_None if from ClearedOpErr
+ if not space.is_w(w_last, space.w_None):
+ # Avoid reference cycles through the context chain. This is
+ # O(chain length) but context chains are usually very short.
+ w_obj = w_last
+ while True:
+ assert isinstance(w_obj, W_BaseException)
+ if lazy:
+ w_context = w_obj.w_context
+ else:
+ # triggers W_BaseException._setup_context
+ w_context = space.getattr(w_obj, space.wrap('__context__'))
+ if space.is_none(w_context):
+ break
+ if space.is_w(w_context, w_exc):
+ w_obj.w_context = space.w_None
+ break
+ w_obj = w_context
+ return w_last
+
class ClearedOpErr:
def __init__(self, space):
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -202,18 +202,21 @@
self._trace(frame, 'exception', None, operationerr)
#operationerr.print_detailed_traceback(self.space)
+ @staticmethod
+ def last_operr(space, frame):
+ while frame:
+ last = frame.last_exception
+ if (last is not None and
+ (not frame.hide() or
+ last is get_cleared_operation_error(space))):
+ return last
+ frame = frame.f_backref()
+ return None
+
def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!!
"""Implements sys.exc_info().
Return an OperationError instance or None."""
- frame = self.gettopframe()
- while frame:
- if frame.last_exception is not None:
- if (not frame.hide() or
- frame.last_exception is
- get_cleared_operation_error(self.space)):
- return frame.last_exception
- frame = frame.f_backref()
- return None
+ return self.last_operr(self.space, self.gettopframe())
def set_sys_exc_info(self, operror):
frame = self.gettopframe_nohidden()
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -32,7 +32,8 @@
'w_func_globals?',
'closure?[*]',
'defs_w?[*]',
- 'name?']
+ 'name?',
+ 'w_kw_defs?']
def __init__(self, space, code, w_globals=None, defs_w=[], w_kw_defs=None,
closure=None, w_ann=None, forcename=None):
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -164,12 +164,9 @@
for i in range(nfreevars):
self.cells[i + ncellvars] = outer_func.closure[i]
- def is_generator(self):
- return self.getcode().co_flags & pycode.CO_GENERATOR
-
def run(self):
"""Start this frame's execution."""
- if self.is_generator():
+ if self.getcode().co_flags & pycode.CO_GENERATOR:
if self.getcode().co_flags & pycode.CO_YIELD_INSIDE_TRY:
from pypy.interpreter.generator import GeneratorIteratorWithDel
return self.space.wrap(GeneratorIteratorWithDel(self))
@@ -514,10 +511,10 @@
for i in range(min(len(varnames), self.getcode().co_nlocals)):
name = varnames[i]
w_value = self.locals_stack_w[i]
- w_name = self.space.wrap(name.decode('utf-8'))
if w_value is not None:
- self.space.setitem(self.w_locals, w_name, w_value)
+ self.space.setitem_str(self.w_locals, name, w_value)
else:
+ w_name = self.space.wrap(name.decode('utf-8'))
try:
self.space.delitem(self.w_locals, w_name)
except OperationError as e:
@@ -537,8 +534,7 @@
except ValueError:
pass
else:
- w_name = self.space.wrap(name)
- self.space.setitem(self.w_locals, w_name, w_value)
+ self.space.setitem_str(self.w_locals, name, w_value)
@jit.unroll_safe
@@ -551,13 +547,9 @@
new_fastlocals_w = [None] * numlocals
for i in range(min(len(varnames), numlocals)):
- w_name = self.space.wrap(varnames[i].decode('utf-8'))
- try:
- w_value = self.space.getitem(self.w_locals, w_name)
- except OperationError, e:
- if not e.match(self.space, self.space.w_KeyError):
- raise
- else:
+ name = varnames[i]
+ w_value = self.space.finditem_str(self.w_locals, name)
+ if w_value is not None:
new_fastlocals_w[i] = w_value
self.setfastscope(new_fastlocals_w)
@@ -566,13 +558,8 @@
for i in range(len(freevarnames)):
name = freevarnames[i]
cell = self.cells[i]
- w_name = self.space.wrap(name)
- try:
- w_value = self.space.getitem(self.w_locals, w_name)
- except OperationError, e:
- if not e.match(self.space, self.space.w_KeyError):
- raise
- else:
+ w_value = self.space.finditem_str(self.w_locals, name)
+ if w_value is not None:
cell.set(w_value)
@jit.unroll_safe
diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py
--- a/pypy/interpreter/pytraceback.py
+++ b/pypy/interpreter/pytraceback.py
@@ -57,6 +57,7 @@
tb = operror.get_traceback()
tb = PyTraceback(space, frame, last_instruction, tb)
operror.set_traceback(tb)
+ operror.record_context(space, frame)
def check_traceback(space, w_tb, msg):
diff --git a/pypy/interpreter/test/test_raise.py b/pypy/interpreter/test/test_raise.py
--- a/pypy/interpreter/test/test_raise.py
+++ b/pypy/interpreter/test/test_raise.py
@@ -369,6 +369,44 @@
else:
fail("No exception raised")
+ def test_context_once_removed(self):
+ context = IndexError()
+ def func1():
+ func2()
+ def func2():
+ try:
+ 1/0
+ except ZeroDivisionError as e:
+ assert e.__context__ is context
+ else:
+ fail('No exception raised')
+ try:
+ raise context
+ except:
+ func1()
+
+ @py.test.mark.xfail(reason="A somewhat contrived case that may burden the "
+ "JIT to fully support")
+ def test_frame_spanning_cycle_broken(self):
+ context = IndexError()
+ def func():
+ try:
+ 1/0
+ except Exception as e1:
+ try:
+ raise context
+ except Exception as e2:
+ assert e2.__context__ is e1
+ # XXX:
+ assert e1.__context__ is None
+ else:
+ fail('No exception raised')
+ try:
+ raise context
+ except:
+ func()
+
+
class AppTestTraceback:
def test_raise_with___traceback__(self):
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -6,7 +6,8 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
+from pypy.interpreter.gateway import (
+ interp2app, interpindirect2app, unwrap_spec)
from pypy.interpreter.typedef import TypeDef
from rpython.rlib import jit
from rpython.rlib.objectmodel import specialize
@@ -307,15 +308,19 @@
class W_Range(W_Root):
- def __init__(self, w_start, w_stop, w_step, w_length):
+ def __init__(self, w_start, w_stop, w_step, w_length, promote_step=False):
self.w_start = w_start
self.w_stop = w_stop
self.w_step = w_step
self.w_length = w_length
+ self.promote_step = promote_step
- @unwrap_spec(w_step = WrappedDefault(1))
def descr_new(space, w_subtype, w_start, w_stop=None, w_step=None):
w_start = space.index(w_start)
+ promote_step = False
+ if space.is_none(w_step): # no step argument provided
+ w_step = space.wrap(1)
+ promote_step = True
if space.is_none(w_stop): # only 1 argument provided
w_start, w_stop = space.newint(0), w_start
else:
@@ -331,7 +336,7 @@
"step argument must not be zero"))
w_length = compute_range_length(space, w_start, w_stop, w_step)
obj = space.allocate_instance(W_Range, w_subtype)
- W_Range.__init__(obj, w_start, w_stop, w_step, w_length)
+ W_Range.__init__(obj, w_start, w_stop, w_step, w_length, promote_step)
return space.wrap(obj)
def descr_repr(self, space):
@@ -386,8 +391,19 @@
return self._compute_item(space, w_index)
def descr_iter(self, space):
- return space.wrap(W_RangeIterator(
- space, self.w_start, self.w_step, self.w_length))
+ try:
+ start = space.int_w(self.w_start)
+ stop = space.int_w(self.w_stop)
+ step = space.int_w(self.w_step)
+ length = space.int_w(self.w_length)
+ except OperationError as e:
+ pass
+ else:
+ if self.promote_step:
+ return W_IntRangeStepOneIterator(space, start, stop)
+ return W_IntRangeIterator(space, start, length, step)
+ return W_LongRangeIterator(space, self.w_start, self.w_step,
+ self.w_length)
def descr_reversed(self, space):
# lastitem = self.start + (self.length-1) * self.step
@@ -395,7 +411,7 @@
self.w_start,
space.mul(space.sub(self.w_length, space.newint(1)),
self.w_step))
- return space.wrap(W_RangeIterator(
+ return space.wrap(W_LongRangeIterator(
space, w_lastitem, space.neg(self.w_step), self.w_length))
def descr_reduce(self, space):
@@ -463,7 +479,22 @@
W_Range.typedef.acceptable_as_base_class = False
-class W_RangeIterator(W_Root):
+class W_AbstractRangeIterator(W_Root):
+
+ def descr_iter(self, space):
+ return space.wrap(self)
+
+ def descr_len(self, space):
+ raise NotImplementedError
+
+ def descr_next(self, space):
+ raise NotImplementedError
+
+ def descr_reduce(self, space):
+ raise NotImplementedError
+
+
+class W_LongRangeIterator(W_AbstractRangeIterator):
def __init__(self, space, w_start, w_step, w_len, w_index=None):
self.w_start = w_start
self.w_step = w_step
@@ -472,9 +503,6 @@
w_index = space.newint(0)
self.w_index = w_index
- def descr_iter(self, space):
- return space.wrap(self)
-
def descr_next(self, space):
if space.is_true(space.lt(self.w_index, self.w_len)):
w_index = space.add(self.w_index, space.newint(1))
@@ -489,23 +517,75 @@
def descr_reduce(self, space):
from pypy.interpreter.mixedmodule import MixedModule
+ w_mod = space.getbuiltinmodule('_pickle_support')
+ mod = space.interp_w(MixedModule, w_mod)
+ w_args = space.newtuple([self.w_start, self.w_step, self.w_len,
+ self.w_index])
+ return space.newtuple([mod.get('longrangeiter_new'), w_args])
+
+
+class W_IntRangeIterator(W_AbstractRangeIterator):
+
+ def __init__(self, space, current, remaining, step):
+ self.current = current
+ self.remaining = remaining
+ self.step = step
+
+ def descr_next(self, space):
+ return self.next(space)
+
+ def next(self, space):
+ if self.remaining > 0:
+ item = self.current
+ self.current = item + self.step
+ self.remaining -= 1
+ return space.wrap(item)
+ raise OperationError(space.w_StopIteration, space.w_None)
+
+ def descr_len(self, space):
+ return self.get_remaining(space)
+
+ def descr_reduce(self, space):
+ from pypy.interpreter.mixedmodule import MixedModule
w_mod = space.getbuiltinmodule('_pickle_support')
mod = space.interp_w(MixedModule, w_mod)
+ new_inst = mod.get('intrangeiter_new')
+ w = space.wrap
+ nt = space.newtuple
- return space.newtuple(
- [mod.get('rangeiter_new'),
- space.newtuple([self.w_start, self.w_step,
- self.w_len, self.w_index]),
- ])
+ tup = [w(self.current), self.get_remaining(space), w(self.step)]
+ return nt([new_inst, nt(tup)])
+ def get_remaining(self, space):
+ return space.wrap(self.remaining)
-W_RangeIterator.typedef = TypeDef("rangeiterator",
- __iter__ = interp2app(W_RangeIterator.descr_iter),
- __length_hint__ = interp2app(W_RangeIterator.descr_len),
- __next__ = interp2app(W_RangeIterator.descr_next),
- __reduce__ = interp2app(W_RangeIterator.descr_reduce),
+
+class W_IntRangeStepOneIterator(W_IntRangeIterator):
+ _immutable_fields_ = ['stop']
+
+ def __init__(self, space, start, stop):
+ self.current = start
+ self.stop = stop
+ self.step = 1
+
+ def next(self, space):
+ if self.current < self.stop:
+ item = self.current
+ self.current = item + 1
+ return space.wrap(item)
+ raise OperationError(space.w_StopIteration, space.w_None)
+
+ def get_remaining(self, space):
+ return space.wrap(self.stop - self.current)
+
+
+W_AbstractRangeIterator.typedef = TypeDef("rangeiterator",
+ __iter__ = interp2app(W_AbstractRangeIterator.descr_iter),
+ __length_hint__ = interpindirect2app(W_AbstractRangeIterator.descr_len),
+ __next__ = interpindirect2app(W_AbstractRangeIterator.descr_next),
+ __reduce__ = interpindirect2app(W_AbstractRangeIterator.descr_reduce),
)
-W_RangeIterator.typedef.acceptable_as_base_class = False
+W_AbstractRangeIterator.typedef.acceptable_as_base_class = False
class W_Map(W_Root):
diff --git a/pypy/module/_pickle_support/__init__.py b/pypy/module/_pickle_support/__init__.py
--- a/pypy/module/_pickle_support/__init__.py
+++ b/pypy/module/_pickle_support/__init__.py
@@ -19,7 +19,8 @@
'frame_new' : 'maker.frame_new',
'traceback_new' : 'maker.traceback_new',
'generator_new' : 'maker.generator_new',
- 'rangeiter_new': 'maker.rangeiter_new',
+ 'longrangeiter_new': 'maker.longrangeiter_new',
+ 'intrangeiter_new': 'maker.intrangeiter_new',
'builtin_code': 'maker.builtin_code',
'builtin_function' : 'maker.builtin_function',
'enumerate_new': 'maker.enumerate_new',
diff --git a/pypy/module/_pickle_support/maker.py b/pypy/module/_pickle_support/maker.py
--- a/pypy/module/_pickle_support/maker.py
+++ b/pypy/module/_pickle_support/maker.py
@@ -62,9 +62,15 @@
new_generator = instantiate(GeneratorIteratorWithDel)
return space.wrap(new_generator)
-def rangeiter_new(space, w_start, w_step, w_len, w_index):
- from pypy.module.__builtin__.functional import W_RangeIterator
- new_iter = W_RangeIterator(space, w_start, w_step, w_len, w_index)
+def longrangeiter_new(space, w_start, w_step, w_len, w_index):
+ from pypy.module.__builtin__.functional import W_LongRangeIterator
+ new_iter = W_LongRangeIterator(space, w_start, w_step, w_len, w_index)
+ return space.wrap(new_iter)
+
+ at unwrap_spec(current=int, remaining=int, step=int)
+def intrangeiter_new(space, current, remaining, step):
+ from pypy.module.__builtin__.functional import W_IntRangeIterator
+ new_iter = W_IntRangeIterator(space, current, remaining, step)
return space.wrap(new_iter)
def operationerror_new(space):
diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py
--- a/pypy/module/exceptions/interp_exceptions.py
+++ b/pypy/module/exceptions/interp_exceptions.py
@@ -76,8 +76,8 @@
from pypy.interpreter.typedef import (TypeDef, GetSetProperty, descr_get_dict,
descr_set_dict, descr_del_dict)
from pypy.interpreter.gateway import interp2app
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.pytraceback import check_traceback
+from pypy.interpreter.error import OperationError, setup_context
+from pypy.interpreter.pytraceback import PyTraceback, check_traceback
from rpython.rlib import rwin32
@@ -156,7 +156,27 @@
self.w_cause = w_newcause
def descr_getcontext(self, space):
- return self.w_context
+ w_context = self.w_context
+ if w_context is None:
+ self.w_context = w_context = self._setup_context(space)
+ return w_context
+
+ def _setup_context(self, space):
+ """Lazily determine __context__ from w_traceback"""
+ # XXX: w_traceback can be overwritten: it's not necessarily the
+ # authoratative traceback!
+ last_operr = None
+ w_traceback = self.w_traceback
+ if w_traceback is not None and isinstance(w_traceback, PyTraceback):
+ ec = space.getexecutioncontext()
+ # search for __context__ beginning in the previous frame. A
+ # __context__ from the top most frame would have already
+ # been handled by OperationError.record_context
+ last_operr = ec.last_operr(space, w_traceback.frame.f_backref())
+ if last_operr is None:
+ # no __context__
+ return space.w_None
+ return setup_context(space, self, last_operr.get_w_value(space))
def descr_setcontext(self, space, w_newcontext):
if not (space.is_w(w_newcontext, space.w_None) or
@@ -167,7 +187,6 @@
self.w_context = w_newcontext
def descr_gettraceback(self, space):
- from pypy.interpreter.pytraceback import PyTraceback
tb = self.w_traceback
if tb is not None and isinstance(tb, PyTraceback):
# tb escapes to app level (see OperationError.get_traceback)
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
@@ -24,7 +24,7 @@
class W_UnicodeObject(W_Root):
import_from_mixin(StringMethods)
- _immutable_fields_ = ['_value']
+ _immutable_fields_ = ['_value', '_utf8?']
def __init__(w_self, unistr):
assert isinstance(unistr, unicode)
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -133,7 +133,7 @@
modules = ['_sqlite3']
subprocess.check_call([str(pypy_c), '-c', 'import _sqlite3'])
if not sys.platform == 'win32':
- modules += ['_curses', 'syslog', 'gdbm', '_sqlite3']
+ modules += ['_curses', 'syslog', '_gdbm', '_sqlite3']
if not options.no_tk:
modules.append(('_tkinter'))
for module in modules:
@@ -402,10 +402,10 @@
'''
-gdbm_bit = '''gdbm
+gdbm_bit = '''_gdbm
----
-The gdbm module includes code from gdbm.h, which is distributed under the terms
+The _gdbm module includes code from gdbm.h, which is distributed under the terms
of the GPL license version 2 or any later version.
'''
More information about the pypy-commit
mailing list