Author: Ronan Lamy <ronan.l...@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 +@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): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit