[pypy-commit] pypy stdlib-2.7.12: tighten type's arg checking
pjenvey
pypy.commits at gmail.com
Sat Oct 8 18:40:13 EDT 2016
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: stdlib-2.7.12
Changeset: r87637:9dacf5a3b331
Date: 2016-10-08 15:36 -0700
http://bitbucket.org/pypy/pypy/changeset/9dacf5a3b331/
Log: tighten type's arg checking
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
@@ -886,10 +886,11 @@
Abc.__name__ = 'Def'
assert Abc.__name__ == 'Def'
raises(TypeError, "Abc.__name__ = 42")
+ raises(TypeError, "Abc.__name__ = u'A'")
try:
Abc.__name__ = 'G\x00hi'
except ValueError as e:
- assert str(e) == "__name__ must not contain null bytes"
+ assert str(e) == "type name must not contain null characters"
else:
assert False
@@ -1112,6 +1113,14 @@
__bases__ = (int,)
assert int.__subclasscheck__(AbstractClass()) is True
+ def test_bad_args(self):
+ import UserDict
+ raises(TypeError, type, 'A', (), dict={})
+ raises(TypeError, type, 'A', [], {})
+ raises(TypeError, type, 'A', (), UserDict.UserDict())
+ raises(ValueError, type, 'A\x00B', (), {})
+ raises(TypeError, type, u'A', (), {})
+
class AppTestWithMethodCacheCounter:
spaceconfig = {"objspace.std.withmethodcachecounter": True}
@@ -1200,7 +1209,7 @@
assert w_B.w_new_function is not None
w_b = space.call_function(w_B)
- w_m = space.call_function(w_M, space.wrap('C'), space.newlist([]),
+ w_m = space.call_function(w_M, space.wrap('C'), space.newtuple([]),
space.newdict())
assert w_M.w_new_function is not None
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
@@ -672,25 +672,34 @@
def descr__new__(space, w_typetype, w_name, w_bases=None, w_dict=None):
- "This is used to create user-defined classes only."
- # XXX check types
-
+ """This is used to create user-defined classes only."""
w_typetype = _precheck_for_new(space, w_typetype)
# special case for type(x)
- if (space.is_w(space.type(w_typetype), space.w_type) and w_bases is None and
- w_dict is None):
+ if (space.is_w(space.type(w_typetype), space.w_type) and
+ w_bases is None and w_dict is None):
return space.type(w_name)
- else:
- return _create_new_type(space, w_typetype, w_name, w_bases, w_dict)
+ return _create_new_type(space, w_typetype, w_name, w_bases, w_dict)
+
+
+def _check_new_args(space, w_name, w_bases, w_dict):
+ if w_bases is None or w_dict is None:
+ raise oefmt(space.w_TypeError, "type() takes 1 or 3 arguments")
+ if not space.isinstance_w(w_name, space.w_str):
+ raise oefmt(space.w_TypeError,
+ "type() argument 1 must be string, not %T", w_name)
+ if not space.isinstance_w(w_bases, space.w_tuple):
+ raise oefmt(space.w_TypeError,
+ "type() argument 2 must be tuple, not %T", w_bases)
+ if not space.isinstance_w(w_dict, space.w_dict):
+ raise oefmt(space.w_TypeError,
+ "type() argument 3 must be dict, not %T", w_dict)
def _create_new_type(space, w_typetype, w_name, w_bases, w_dict):
# this is in its own function because we want the special case 'type(x)'
# above to be seen by the jit.
- if w_bases is None or w_dict is None:
- raise oefmt(space.w_TypeError, "type() takes 1 or 3 arguments")
-
+ _check_new_args(space, w_name, w_bases, w_dict)
bases_w = space.fixedview(w_bases)
w_winner = w_typetype
@@ -716,6 +725,8 @@
name = space.str_w(w_name)
assert isinstance(name, str)
+ if '\x00' in name:
+ raise oefmt(space.w_ValueError, "type name must not contain null characters")
dict_w = {}
dictkeys_w = space.listview(w_dict)
for w_key in dictkeys_w:
@@ -732,6 +743,16 @@
raise oefmt(space.w_TypeError, "X is not a type object (%T)", w_type)
return w_type
+
+def descr__init__(space, w_type, __args__):
+ if __args__.keywords:
+ raise oefmt(space.w_TypeError,
+ "type.__init__() takes no keyword arguments")
+ if len(__args__.arguments_w) not in (1, 3):
+ raise oefmt(space.w_TypeError,
+ "type.__init__() takes 1 or 3 arguments")
+
+
# ____________________________________________________________
def _check(space, w_type, msg="descriptor is for 'type'"):
@@ -748,9 +769,13 @@
w_type = _check(space, w_type)
if not w_type.is_heaptype():
raise oefmt(space.w_TypeError, "can't set %N.__name__", w_type)
+ if not space.isinstance_w(w_value, space.w_str):
+ raise oefmt(space.w_TypeError,
+ "can only assign string to %N.__name__, not '%T'",
+ w_type, w_value)
name = space.str_w(w_value)
if '\x00' in name:
- raise oefmt(space.w_ValueError, "__name__ must not contain null bytes")
+ raise oefmt(space.w_ValueError, "type name must not contain null characters")
w_type.name = name
def descr_get__mro__(space, w_type):
@@ -920,6 +945,7 @@
W_TypeObject.typedef = TypeDef("type",
__new__ = gateway.interp2app(descr__new__),
+ __init__ = gateway.interp2app(descr__init__),
__name__ = GetSetProperty(descr_get__name__, descr_set__name__),
__bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__),
__base__ = GetSetProperty(descr__base),
More information about the pypy-commit
mailing list