[pypy-commit] pypy py3.5: hg merge default

rlamy pypy.commits at gmail.com
Wed Jan 11 13:49:46 EST 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5
Changeset: r89501:f4f9c3b10d64
Date: 2017-01-11 18:49 +0000
http://bitbucket.org/pypy/pypy/changeset/f4f9c3b10d64/

Log:	hg merge default

diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -8,6 +8,7 @@
 
 from rpython.rlib.jit import promote
 from rpython.rlib.objectmodel import compute_identity_hash, specialize
+from rpython.rlib.objectmodel import instantiate
 from rpython.tool.sourcetools import compile2, func_with_new_name
 
 
@@ -221,10 +222,6 @@
     exec source.compile() in miniglobals
     return miniglobals['descr_typecheck_%s' % func.__name__]
 
-def unknown_objclass_getter(space):
-    # NB. this is an AttributeError to make inspect.py happy
-    raise oefmt(space.w_AttributeError, "generic property has no __objclass__")
-
 @specialize.arg(0)
 def make_objclass_getter(tag, func, cls):
     if func and hasattr(func, 'im_func'):
@@ -235,7 +232,7 @@
 @specialize.memo()
 def _make_objclass_getter(cls):
     if not cls:
-        return unknown_objclass_getter, cls
+        return None, cls
     miniglobals = {}
     if isinstance(cls, str):
         assert cls.startswith('<'), "pythontype typecheck should begin with <"
@@ -254,6 +251,8 @@
 
 class GetSetProperty(W_Root):
     _immutable_fields_ = ["fget", "fset", "fdel"]
+    name = '<generic property>'
+    w_objclass = None
 
     @specialize.arg(7)
     def __init__(self, fget, fset=None, fdel=None, doc=None,
@@ -265,16 +264,26 @@
                                             cls=cls, use_closure=use_closure)
         fdel = make_descr_typecheck_wrapper((tag, 2), fdel,
                                             cls=cls, use_closure=use_closure)
+        self._init(fget, fset, fdel, doc, cls, objclass_getter, use_closure)
+
+    def _init(self, fget, fset, fdel, doc, cls, objclass_getter, use_closure):
         self.fget = fget
         self.fset = fset
         self.fdel = fdel
         self.doc = doc
         self.reqcls = cls
-        self.name = '<generic property>'
         self.qualname = None
         self.objclass_getter = objclass_getter
         self.use_closure = use_closure
 
+    def copy_for_type(self, w_objclass):
+        new = instantiate(GetSetProperty)
+        new._init(self.fget, self.fset, self.fdel, self.doc, self.reqcls,
+                  None, self.use_closure)
+        new.name = self.name
+        new.w_objclass = w_objclass
+        return new
+
     @unwrap_spec(w_cls = WrappedDefault(None))
     def descr_property_get(self, space, w_obj, w_cls=None):
         """property.__get__(obj[, type]) -> value
@@ -338,7 +347,14 @@
         return space.wrap(qualname)
 
     def descr_get_objclass(space, property):
-        return property.objclass_getter(space)
+        if property.w_objclass is not None:
+            return property.w_objclass
+        if property.objclass_getter is not None:
+            return property.objclass_getter(space)
+        # NB. this is an AttributeError to make inspect.py happy
+        raise oefmt(space.w_AttributeError,
+                    "generic property has no __objclass__")
+
 
 def interp_attrproperty(name, cls, doc=None):
     "NOT_RPYTHON: initialization-time only"
@@ -497,7 +513,7 @@
     return lifeline.get_any_weakref(space)
 
 dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
-                            doc="dictionary for instance variables (if defined)")
+                            doc="dictionary for instance variables")
 dict_descr.name = '__dict__'
 
 
@@ -532,7 +548,7 @@
     return space.newtuple([w_docstring])
 
 weakref_descr = GetSetProperty(descr_get_weakref,
-                    doc="list of weak references to the object (if defined)")
+                               doc="list of weak references to the object")
 weakref_descr.name = '__weakref__'
 
 def make_weakref_descr(cls):
diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py
--- a/pypy/module/cpyext/cdatetime.py
+++ b/pypy/module/cpyext/cdatetime.py
@@ -118,12 +118,16 @@
                     """ % (type_name,)))
         except OperationError:
             return 0
+    return check, check_exact
 
-make_check_function("PyDateTime_Check", "datetime")
-make_check_function("PyDate_Check", "date")
-make_check_function("PyTime_Check", "time")
-make_check_function("PyDelta_Check", "timedelta")
-make_check_function("PyTZInfo_Check", "tzinfo")
+PyDateTime_Check, PyDateTime_CheckExact = make_check_function(
+    "PyDateTime_Check", "datetime")
+PyDate_Check, PyDate_CheckExact = make_check_function("PyDate_Check", "date")
+PyTime_Check, PyTime_CheckExact = make_check_function("PyTime_Check", "time")
+PyDelta_Check, PyDelta_CheckExact = make_check_function(
+    "PyDelta_Check", "timedelta")
+PyTZInfo_Check, PyTZInfo_CheckExact = make_check_function(
+    "PyTZInfo_Check", "tzinfo")
 
 # Constructors. They are better used as macros.
 
diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py
--- a/pypy/module/cpyext/test/test_api.py
+++ b/pypy/module/cpyext/test/test_api.py
@@ -1,4 +1,5 @@
 import py, pytest
+import contextlib
 from rpython.rtyper.lltypesystem import lltype
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.module.cpyext.state import State
@@ -10,6 +11,13 @@
 from rpython.rlib import rawrefcount
 import os
 
+ at contextlib.contextmanager
+def raises_w(space, expected_exc):
+    with pytest.raises(OperationError) as excinfo:
+        yield
+    operror = excinfo.value
+    assert operror.w_type is getattr(space, 'w_' + expected_exc.__name__)
+
 class BaseApiTest(LeakCheckingTest):
     def setup_class(cls):
         space = cls.space
diff --git a/pypy/module/cpyext/test/test_boolobject.py b/pypy/module/cpyext/test/test_boolobject.py
--- a/pypy/module/cpyext/test/test_boolobject.py
+++ b/pypy/module/cpyext/test/test_boolobject.py
@@ -1,20 +1,22 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.boolobject import PyBool_Check, PyBool_FromLong
+from pypy.module.cpyext.floatobject import PyFloat_FromDouble
 
 class TestBoolObject(BaseApiTest):
-    def test_fromlong(self, space, api):
+    def test_fromlong(self, space):
         for i in range(-3, 3):
-            obj = api.PyBool_FromLong(i)
+            obj = PyBool_FromLong(space, i)
             if i:
                 assert obj is space.w_True
             else:
                 assert obj is space.w_False
 
-    def test_check(self, space, api):
-        assert api.PyBool_Check(space.w_True)
-        assert api.PyBool_Check(space.w_False)
-        assert not api.PyBool_Check(space.w_None)
-        assert not api.PyBool_Check(api.PyFloat_FromDouble(1.0))
+    def test_check(self, space):
+        assert PyBool_Check(space, space.w_True)
+        assert PyBool_Check(space, space.w_False)
+        assert not PyBool_Check(space, space.w_None)
+        assert not PyBool_Check(space, PyFloat_FromDouble(space, 1.0))
 
 class AppTestBoolMacros(AppTestCpythonExtensionBase):
     def test_macros(self):
diff --git a/pypy/module/cpyext/test/test_bytesobject.py b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -1,14 +1,14 @@
 # encoding: utf-8
+import pytest
 from rpython.rtyper.lltypesystem import rffi, lltype
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.interpreter.error import OperationError
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.bytesobject import new_empty_str, PyBytesObject
 from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP, generic_cpy_call, Py_buffer
 from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref, as_pyobj
 from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
 
-import py
-import sys
 
 
 class AppTestBytesObject(AppTestCpythonExtensionBase):
diff --git a/pypy/module/cpyext/test/test_codecs.py b/pypy/module/cpyext/test/test_codecs.py
--- a/pypy/module/cpyext/test/test_codecs.py
+++ b/pypy/module/cpyext/test/test_codecs.py
@@ -1,14 +1,15 @@
 # encoding: iso-8859-15
 from pypy.module.cpyext.test.test_api import BaseApiTest
-from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.lltypesystem import rffi
+from pypy.module.cpyext.codecs import (
+    PyCodec_IncrementalEncoder, PyCodec_IncrementalDecoder)
 
 class TestCodecs(BaseApiTest):
-    def test_incremental(self, space, api):
+    def test_incremental(self, space):
         utf8 = rffi.str2charp('utf-8')
-        w_encoder = api.PyCodec_IncrementalEncoder(utf8, None)
+        w_encoder = PyCodec_IncrementalEncoder(space, utf8, None)
         w_encoded = space.call_method(w_encoder, 'encode', space.wrap(u'späm'))
-        w_decoder = api.PyCodec_IncrementalDecoder(utf8, None)
+        w_decoder = PyCodec_IncrementalDecoder(space, utf8, None)
         w_decoded = space.call_method(w_decoder, 'decode', w_encoded)
         assert space.unwrap(w_decoded) == u'späm'
         rffi.free_charp(utf8)
-
diff --git a/pypy/module/cpyext/test/test_complexobject.py b/pypy/module/cpyext/test/test_complexobject.py
--- a/pypy/module/cpyext/test/test_complexobject.py
+++ b/pypy/module/cpyext/test/test_complexobject.py
@@ -1,23 +1,23 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
+from pypy.module.cpyext.complexobject import (
+    PyComplex_FromDoubles, PyComplex_RealAsDouble, PyComplex_ImagAsDouble)
 
 class TestComplexObject(BaseApiTest):
-    def test_complexobject(self, space, api):
-        w_value = api.PyComplex_FromDoubles(1.2, 3.4)
+    def test_complexobject(self, space):
+        w_value = PyComplex_FromDoubles(space, 1.2, 3.4)
         assert space.unwrap(w_value) == 1.2+3.4j
-        assert api.PyComplex_RealAsDouble(w_value) == 1.2
-        assert api.PyComplex_ImagAsDouble(w_value) == 3.4
+        assert PyComplex_RealAsDouble(space, w_value) == 1.2
+        assert PyComplex_ImagAsDouble(space, w_value) == 3.4
 
-        assert api.PyComplex_RealAsDouble(space.wrap(42)) == 42
-        assert api.PyComplex_RealAsDouble(space.wrap(1.5)) == 1.5
-        assert api.PyComplex_ImagAsDouble(space.wrap(1.5)) == 0.0
+        assert PyComplex_RealAsDouble(space, space.wrap(42)) == 42
+        assert PyComplex_RealAsDouble(space, space.wrap(1.5)) == 1.5
+        assert PyComplex_ImagAsDouble(space, space.wrap(1.5)) == 0.0
 
         # cpython accepts anything for PyComplex_ImagAsDouble
-        assert api.PyComplex_ImagAsDouble(space.w_None) == 0.0
-        assert not api.PyErr_Occurred()
-        assert api.PyComplex_RealAsDouble(space.w_None) == -1.0
-        assert api.PyErr_Occurred()
-        api.PyErr_Clear()
+        assert PyComplex_ImagAsDouble(space, space.w_None) == 0.0
+        with raises_w(space, TypeError):
+            PyComplex_RealAsDouble(space, space.w_None)
 
 class AppTestCComplex(AppTestCpythonExtensionBase):
     def test_AsCComplex(self):
diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py
--- a/pypy/module/cpyext/test/test_datetime.py
+++ b/pypy/module/cpyext/test/test_datetime.py
@@ -1,92 +1,96 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.cdatetime import *
+from pypy.module.cpyext.cdatetime import (
+    _PyDateTime_Import, _PyDateTime_FromDateAndTime, _PyDate_FromDate,
+    _PyTime_FromTime, _PyDelta_FromDelta)
 import datetime
 
 class TestDatetime(BaseApiTest):
-    def test_date(self, space, api):
-        date_api = api._PyDateTime_Import()
-        w_date = api._PyDate_FromDate(2010, 06, 03, date_api.c_DateType)
+    def test_date(self, space):
+        date_api = _PyDateTime_Import(space)
+        w_date = _PyDate_FromDate(space, 2010, 06, 03, date_api.c_DateType)
         assert space.unwrap(space.str(w_date)) == '2010-06-03'
 
-        assert api.PyDate_Check(w_date)
-        assert api.PyDate_CheckExact(w_date)
+        assert PyDate_Check(space, w_date)
+        assert PyDate_CheckExact(space, w_date)
 
-        assert api.PyDateTime_GET_YEAR(w_date) == 2010
-        assert api.PyDateTime_GET_MONTH(w_date) == 6
-        assert api.PyDateTime_GET_DAY(w_date) == 3
+        assert PyDateTime_GET_YEAR(space, w_date) == 2010
+        assert PyDateTime_GET_MONTH(space, w_date) == 6
+        assert PyDateTime_GET_DAY(space, w_date) == 3
 
-    def test_time(self, space, api):
-        date_api = api._PyDateTime_Import()
-        w_time = api._PyTime_FromTime(23, 15, 40, 123456,
-                                      space.w_None, date_api.c_TimeType)
+    def test_time(self, space):
+        date_api = _PyDateTime_Import(space)
+        w_time = _PyTime_FromTime(
+            space, 23, 15, 40, 123456, space.w_None, date_api.c_TimeType)
         assert space.unwrap(space.str(w_time)) == '23:15:40.123456'
 
-        assert api.PyTime_Check(w_time)
-        assert api.PyTime_CheckExact(w_time)
+        assert PyTime_Check(space, w_time)
+        assert PyTime_CheckExact(space, w_time)
 
-        assert api.PyDateTime_TIME_GET_HOUR(w_time) == 23
-        assert api.PyDateTime_TIME_GET_MINUTE(w_time) == 15
-        assert api.PyDateTime_TIME_GET_SECOND(w_time) == 40
-        assert api.PyDateTime_TIME_GET_MICROSECOND(w_time) == 123456
+        assert PyDateTime_TIME_GET_HOUR(space, w_time) == 23
+        assert PyDateTime_TIME_GET_MINUTE(space, w_time) == 15
+        assert PyDateTime_TIME_GET_SECOND(space, w_time) == 40
+        assert PyDateTime_TIME_GET_MICROSECOND(space, w_time) == 123456
 
-    def test_datetime(self, space, api):
-        date_api = api._PyDateTime_Import()
-        w_date = api._PyDateTime_FromDateAndTime(
-            2010, 06, 03, 23, 15, 40, 123456,
-            space.w_None, date_api.c_DateTimeType)
+    def test_datetime(self, space):
+        date_api = _PyDateTime_Import(space)
+        w_date = _PyDateTime_FromDateAndTime(
+            space, 2010, 06, 03, 23, 15, 40, 123456, space.w_None,
+            date_api.c_DateTimeType)
         assert space.unwrap(space.str(w_date)) == '2010-06-03 23:15:40.123456'
 
-        assert api.PyDateTime_Check(w_date)
-        assert api.PyDateTime_CheckExact(w_date)
-        assert api.PyDate_Check(w_date)
-        assert not api.PyDate_CheckExact(w_date)
+        assert PyDateTime_Check(space, w_date)
+        assert PyDateTime_CheckExact(space, w_date)
+        assert PyDate_Check(space, w_date)
+        assert not PyDate_CheckExact(space, w_date)
 
-        assert api.PyDateTime_GET_YEAR(w_date) == 2010
-        assert api.PyDateTime_GET_MONTH(w_date) == 6
-        assert api.PyDateTime_GET_DAY(w_date) == 3
-        assert api.PyDateTime_DATE_GET_HOUR(w_date) == 23
-        assert api.PyDateTime_DATE_GET_MINUTE(w_date) == 15
-        assert api.PyDateTime_DATE_GET_SECOND(w_date) == 40
-        assert api.PyDateTime_DATE_GET_MICROSECOND(w_date) == 123456
+        assert PyDateTime_GET_YEAR(space, w_date) == 2010
+        assert PyDateTime_GET_MONTH(space, w_date) == 6
+        assert PyDateTime_GET_DAY(space, w_date) == 3
+        assert PyDateTime_DATE_GET_HOUR(space, w_date) == 23
+        assert PyDateTime_DATE_GET_MINUTE(space, w_date) == 15
+        assert PyDateTime_DATE_GET_SECOND(space, w_date) == 40
+        assert PyDateTime_DATE_GET_MICROSECOND(space, w_date) == 123456
 
-    def test_delta(self, space, api):
-        date_api = api._PyDateTime_Import()
+    def test_delta(self, space):
+        date_api = _PyDateTime_Import(space)
         w_delta = space.appexec(
             [space.wrap(3), space.wrap(15)], """(days, seconds):
             from datetime import timedelta
             return timedelta(days, seconds)
         """)
-        assert api.PyDelta_Check(w_delta)
-        assert api.PyDelta_CheckExact(w_delta)
+        assert PyDelta_Check(space, w_delta)
+        assert PyDelta_CheckExact(space, w_delta)
 
-        w_delta = api._PyDelta_FromDelta(10, 20, 30, True, date_api.c_DeltaType)
-        assert api.PyDelta_Check(w_delta)
-        assert api.PyDelta_CheckExact(w_delta)
+        w_delta = _PyDelta_FromDelta(space, 10, 20, 30, True, date_api.c_DeltaType)
+        assert PyDelta_Check(space, w_delta)
+        assert PyDelta_CheckExact(space, w_delta)
 
-        assert api.PyDateTime_DELTA_GET_DAYS(w_delta) == 10
-        assert api.PyDateTime_DELTA_GET_SECONDS(w_delta) == 20
-        assert api.PyDateTime_DELTA_GET_MICROSECONDS(w_delta) == 30
+        assert PyDateTime_DELTA_GET_DAYS(space, w_delta) == 10
+        assert PyDateTime_DELTA_GET_SECONDS(space, w_delta) == 20
+        assert PyDateTime_DELTA_GET_MICROSECONDS(space, w_delta) == 30
 
-    def test_fromtimestamp(self, space, api):
+    def test_fromtimestamp(self, space):
         w_args = space.wrap((0,))
-        w_date = api.PyDate_FromTimestamp(w_args)
+        w_date = PyDate_FromTimestamp(space, w_args)
         date = datetime.date.fromtimestamp(0)
         assert space.unwrap(space.str(w_date)) == str(date)
 
         w_args = space.wrap((0,))
-        w_date = api.PyDateTime_FromTimestamp(w_args)
+        w_date = PyDateTime_FromTimestamp(space, w_args)
         date = datetime.datetime.fromtimestamp(0)
         assert space.unwrap(space.str(w_date)) == str(date)
 
-    def test_tzinfo(self, space, api):
+    def test_tzinfo(self, space):
         w_tzinfo = space.appexec(
             [], """():
             from datetime import tzinfo
             return tzinfo()
         """)
-        assert api.PyTZInfo_Check(w_tzinfo)
-        assert api.PyTZInfo_CheckExact(w_tzinfo)
-        assert not api.PyTZInfo_Check(space.w_None)
+        assert PyTZInfo_Check(space, w_tzinfo)
+        assert PyTZInfo_CheckExact(space, w_tzinfo)
+        assert not PyTZInfo_Check(space, space.w_None)
 
 class AppTestDatetime(AppTestCpythonExtensionBase):
     def test_CAPI(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
@@ -1456,3 +1456,9 @@
     def test_duplicate_slot_name(self):
         class X:   # does not raise
             __slots__ = 'a', 'a'
+
+    def test_descriptor_objclass(self):
+        class X(object):
+            pass
+        assert X.__dict__['__dict__'].__objclass__ is X
+        assert X.__dict__['__weakref__'].__objclass__ is X
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
@@ -1160,14 +1160,16 @@
 
 def create_dict_slot(w_self):
     if not w_self.hasdict:
+        descr = dict_descr.copy_for_type(w_self)
         w_self.dict_w.setdefault('__dict__',
-                                 w_self.space.wrap(dict_descr))
+                                 w_self.space.wrap(descr))
         w_self.hasdict = True
 
 def create_weakref_slot(w_self):
     if not w_self.weakrefable:
+        descr = weakref_descr.copy_for_type(w_self)
         w_self.dict_w.setdefault('__weakref__',
-                                 w_self.space.wrap(weakref_descr))
+                                 w_self.space.wrap(descr))
         w_self.weakrefable = True
 
 def setup_user_defined_type(w_self, force_new_layout):


More information about the pypy-commit mailing list