Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
a921480a
Commit
a921480a
authored
May 25, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #544 from undingen/misc_stuff
Misc stuff
parents
2f75201c
13d73fc6
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
557 additions
and
7 deletions
+557
-7
from_cpython/Objects/stringobject.c
from_cpython/Objects/stringobject.c
+28
-0
src/capi/abstract.cpp
src/capi/abstract.cpp
+3
-0
src/capi/modsupport.cpp
src/capi/modsupport.cpp
+7
-0
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+240
-0
src/capi/typeobject.h
src/capi/typeobject.h
+1
-0
src/runtime/capi.cpp
src/runtime/capi.cpp
+8
-2
src/runtime/int.cpp
src/runtime/int.cpp
+2
-2
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+1
-1
src/runtime/str.cpp
src/runtime/str.cpp
+2
-0
src/runtime/types.cpp
src/runtime/types.cpp
+80
-2
test/tests/dict_setting.py
test/tests/dict_setting.py
+9
-0
test/tests/intmethods.py
test/tests/intmethods.py
+1
-0
test/tests/mutable_bases.py
test/tests/mutable_bases.py
+170
-0
test/tests/str_functions.py
test/tests/str_functions.py
+5
-0
No files found.
from_cpython/Objects/stringobject.c
View file @
a921480a
...
...
@@ -364,3 +364,31 @@ PyObject *string_join(PyStringObject *self, PyObject *orig)
Py_DECREF
(
seq
);
return
res
;
}
PyObject
*
string__format__
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
format_spec
;
PyObject
*
result
=
NULL
;
PyObject
*
tmp
=
NULL
;
/* If 2.x, convert format_spec to the same type as value */
/* This is to allow things like u''.format('') */
if
(
!
PyArg_ParseTuple
(
args
,
"O:__format__"
,
&
format_spec
))
goto
done
;
if
(
!
(
PyString_Check
(
format_spec
)
||
PyUnicode_Check
(
format_spec
)))
{
PyErr_Format
(
PyExc_TypeError
,
"__format__ arg must be str "
"or unicode, not %s"
,
Py_TYPE
(
format_spec
)
->
tp_name
);
goto
done
;
}
tmp
=
PyObject_Str
(
format_spec
);
if
(
tmp
==
NULL
)
goto
done
;
format_spec
=
tmp
;
result
=
_PyBytes_FormatAdvanced
(
self
,
PyString_AS_STRING
(
format_spec
),
PyString_GET_SIZE
(
format_spec
));
done:
Py_XDECREF
(
tmp
);
return
result
;
}
src/capi/abstract.cpp
View file @
a921480a
...
...
@@ -1879,6 +1879,9 @@ extern "C" PyObject* PyNumber_Long(PyObject* o) noexcept {
if
(
o
->
cls
==
float_cls
)
return
PyLong_FromDouble
(
PyFloat_AsDouble
(
o
));
if
(
o
->
cls
==
int_cls
)
return
PyLong_FromLong
(((
BoxedInt
*
)
o
)
->
n
);
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
return
nullptr
;
}
...
...
src/capi/modsupport.cpp
View file @
a921480a
...
...
@@ -184,6 +184,13 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
}
return
v
;
}
#ifdef HAVE_LONG_LONG
case
'L'
:
return
PyLong_FromLongLong
((
PY_LONG_LONG
)
va_arg
(
*
p_va
,
PY_LONG_LONG
));
case
'K'
:
return
PyLong_FromUnsignedLongLong
((
PY_LONG_LONG
)
va_arg
(
*
p_va
,
unsigned
PY_LONG_LONG
));
#endif
#ifdef Py_USING_UNICODE
case
'u'
:
{
PyObject
*
v
;
...
...
src/capi/typeobject.cpp
View file @
a921480a
...
...
@@ -2647,6 +2647,246 @@ static void remove_subclass(PyTypeObject* base, PyTypeObject* type) noexcept {
}
}
static
int
equiv_structs
(
PyTypeObject
*
a
,
PyTypeObject
*
b
)
noexcept
{
// Pyston change: added attrs_offset equality check
// return a == b || (a != NULL && b != NULL && a->tp_basicsize == b->tp_basicsize
// && a->tp_itemsize == b->tp_itemsize
// && a->tp_dictoffset == b->tp_dictoffset && a->tp_weaklistoffset == b->tp_weaklistoffset
// && ((a->tp_flags & Py_TPFLAGS_HAVE_GC) == (b->tp_flags & Py_TPFLAGS_HAVE_GC)));
return
a
==
b
||
(
a
!=
NULL
&&
b
!=
NULL
&&
a
->
tp_basicsize
==
b
->
tp_basicsize
&&
a
->
tp_itemsize
==
b
->
tp_itemsize
&&
a
->
tp_dictoffset
==
b
->
tp_dictoffset
&&
a
->
tp_weaklistoffset
==
b
->
tp_weaklistoffset
&&
a
->
attrs_offset
==
b
->
attrs_offset
&&
((
a
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
)
==
(
b
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
)));
}
static
void
update_all_slots
(
PyTypeObject
*
type
)
noexcept
{
slotdef
*
p
;
init_slotdefs
();
for
(
p
=
slotdefs
;
p
->
name
;
p
++
)
{
/* update_slot returns int but can't actually fail */
update_slot
(
type
,
p
->
name
);
}
}
static
int
same_slots_added
(
PyTypeObject
*
a
,
PyTypeObject
*
b
)
noexcept
{
PyTypeObject
*
base
=
a
->
tp_base
;
Py_ssize_t
size
;
PyObject
*
slots_a
,
*
slots_b
;
assert
(
base
==
b
->
tp_base
);
size
=
base
->
tp_basicsize
;
if
(
a
->
tp_dictoffset
==
size
&&
b
->
tp_dictoffset
==
size
)
size
+=
sizeof
(
PyObject
*
);
// Pyston change: have to check attrs_offset
if
(
a
->
attrs_offset
==
size
&&
b
->
attrs_offset
==
size
)
size
+=
sizeof
(
HCAttrs
);
if
(
a
->
tp_weaklistoffset
==
size
&&
b
->
tp_weaklistoffset
==
size
)
size
+=
sizeof
(
PyObject
*
);
/* Check slots compliance */
slots_a
=
((
PyHeapTypeObject
*
)
a
)
->
ht_slots
;
slots_b
=
((
PyHeapTypeObject
*
)
b
)
->
ht_slots
;
if
(
slots_a
&&
slots_b
)
{
if
(
PyObject_Compare
(
slots_a
,
slots_b
)
!=
0
)
return
0
;
size
+=
sizeof
(
PyObject
*
)
*
PyTuple_GET_SIZE
(
slots_a
);
}
return
size
==
a
->
tp_basicsize
&&
size
==
b
->
tp_basicsize
;
}
static
int
compatible_for_assignment
(
PyTypeObject
*
oldto
,
PyTypeObject
*
newto
,
const
char
*
attr
)
noexcept
{
PyTypeObject
*
newbase
,
*
oldbase
;
if
(
newto
->
tp_dealloc
!=
oldto
->
tp_dealloc
||
newto
->
tp_free
!=
oldto
->
tp_free
)
{
PyErr_Format
(
PyExc_TypeError
,
"%s assignment: "
"'%s' deallocator differs from '%s'"
,
attr
,
newto
->
tp_name
,
oldto
->
tp_name
);
return
0
;
}
newbase
=
newto
;
oldbase
=
oldto
;
while
(
equiv_structs
(
newbase
,
newbase
->
tp_base
))
newbase
=
newbase
->
tp_base
;
while
(
equiv_structs
(
oldbase
,
oldbase
->
tp_base
))
oldbase
=
oldbase
->
tp_base
;
if
(
newbase
!=
oldbase
&&
(
newbase
->
tp_base
!=
oldbase
->
tp_base
||
!
same_slots_added
(
newbase
,
oldbase
)))
{
PyErr_Format
(
PyExc_TypeError
,
"%s assignment: "
"'%s' object layout differs from '%s'"
,
attr
,
newto
->
tp_name
,
oldto
->
tp_name
);
return
0
;
}
return
1
;
}
static
int
mro_subclasses
(
PyTypeObject
*
type
,
PyObject
*
temp
)
noexcept
{
PyTypeObject
*
subclass
;
PyObject
*
ref
,
*
subclasses
,
*
old_mro
;
Py_ssize_t
i
,
n
;
subclasses
=
type
->
tp_subclasses
;
if
(
subclasses
==
NULL
)
return
0
;
assert
(
PyList_Check
(
subclasses
));
n
=
PyList_GET_SIZE
(
subclasses
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
ref
=
PyList_GET_ITEM
(
subclasses
,
i
);
assert
(
PyWeakref_CheckRef
(
ref
));
subclass
=
(
PyTypeObject
*
)
PyWeakref_GET_OBJECT
(
ref
);
assert
(
subclass
!=
NULL
);
if
((
PyObject
*
)
subclass
==
Py_None
)
continue
;
assert
(
PyType_Check
(
subclass
));
old_mro
=
subclass
->
tp_mro
;
if
(
mro_internal
(
subclass
)
<
0
)
{
subclass
->
tp_mro
=
old_mro
;
return
-
1
;
}
else
{
PyObject
*
tuple
;
tuple
=
PyTuple_Pack
(
2
,
subclass
,
old_mro
);
Py_DECREF
(
old_mro
);
if
(
!
tuple
)
return
-
1
;
if
(
PyList_Append
(
temp
,
tuple
)
<
0
)
return
-
1
;
Py_DECREF
(
tuple
);
}
if
(
mro_subclasses
(
subclass
,
temp
)
<
0
)
return
-
1
;
}
return
0
;
}
int
type_set_bases
(
PyTypeObject
*
type
,
PyObject
*
value
,
void
*
context
)
noexcept
{
Py_ssize_t
i
;
int
r
=
0
;
PyObject
*
ob
,
*
temp
;
PyTypeObject
*
new_base
,
*
old_base
;
PyObject
*
old_bases
,
*
old_mro
;
if
(
!
(
type
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
))
{
PyErr_Format
(
PyExc_TypeError
,
"can't set %s.__bases__"
,
type
->
tp_name
);
return
-
1
;
}
if
(
!
value
)
{
PyErr_Format
(
PyExc_TypeError
,
"can't delete %s.__bases__"
,
type
->
tp_name
);
return
-
1
;
}
if
(
!
PyTuple_Check
(
value
))
{
PyErr_Format
(
PyExc_TypeError
,
"can only assign tuple to %s.__bases__, not %s"
,
type
->
tp_name
,
Py_TYPE
(
value
)
->
tp_name
);
return
-
1
;
}
if
(
PyTuple_GET_SIZE
(
value
)
==
0
)
{
PyErr_Format
(
PyExc_TypeError
,
"can only assign non-empty tuple to %s.__bases__, not ()"
,
type
->
tp_name
);
return
-
1
;
}
for
(
i
=
0
;
i
<
PyTuple_GET_SIZE
(
value
);
i
++
)
{
ob
=
PyTuple_GET_ITEM
(
value
,
i
);
if
(
!
PyClass_Check
(
ob
)
&&
!
PyType_Check
(
ob
))
{
PyErr_Format
(
PyExc_TypeError
,
"%s.__bases__ must be tuple of old- or new-style classes, not '%s'"
,
type
->
tp_name
,
Py_TYPE
(
ob
)
->
tp_name
);
return
-
1
;
}
if
(
PyType_Check
(
ob
))
{
if
(
PyType_IsSubtype
((
PyTypeObject
*
)
ob
,
type
))
{
PyErr_SetString
(
PyExc_TypeError
,
"a __bases__ item causes an inheritance cycle"
);
return
-
1
;
}
}
}
new_base
=
best_base
(
value
);
if
(
!
new_base
)
{
return
-
1
;
}
if
(
!
compatible_for_assignment
(
type
->
tp_base
,
new_base
,
"__bases__"
))
return
-
1
;
Py_INCREF
(
new_base
);
Py_INCREF
(
value
);
old_bases
=
type
->
tp_bases
;
old_base
=
type
->
tp_base
;
old_mro
=
type
->
tp_mro
;
type
->
tp_bases
=
value
;
type
->
tp_base
=
new_base
;
if
(
mro_internal
(
type
)
<
0
)
{
goto
bail
;
}
temp
=
PyList_New
(
0
);
if
(
!
temp
)
goto
bail
;
r
=
mro_subclasses
(
type
,
temp
);
if
(
r
<
0
)
{
for
(
i
=
0
;
i
<
PyList_Size
(
temp
);
i
++
)
{
PyTypeObject
*
cls
;
PyObject
*
mro
;
PyArg_UnpackTuple
(
PyList_GET_ITEM
(
temp
,
i
),
""
,
2
,
2
,
&
cls
,
&
mro
);
Py_INCREF
(
mro
);
ob
=
cls
->
tp_mro
;
cls
->
tp_mro
=
mro
;
Py_DECREF
(
ob
);
}
Py_DECREF
(
temp
);
goto
bail
;
}
Py_DECREF
(
temp
);
/* any base that was in __bases__ but now isn't, we
need to remove |type| from its tp_subclasses.
conversely, any class now in __bases__ that wasn't
needs to have |type| added to its subclasses. */
/* for now, sod that: just remove from all old_bases,
add to all new_bases */
for
(
i
=
PyTuple_GET_SIZE
(
old_bases
)
-
1
;
i
>=
0
;
i
--
)
{
ob
=
PyTuple_GET_ITEM
(
old_bases
,
i
);
if
(
PyType_Check
(
ob
))
{
remove_subclass
((
PyTypeObject
*
)
ob
,
type
);
}
}
for
(
i
=
PyTuple_GET_SIZE
(
value
)
-
1
;
i
>=
0
;
i
--
)
{
ob
=
PyTuple_GET_ITEM
(
value
,
i
);
if
(
PyType_Check
(
ob
))
{
if
(
add_subclass
((
PyTypeObject
*
)
ob
,
type
)
<
0
)
r
=
-
1
;
}
}
update_all_slots
(
type
);
Py_DECREF
(
old_bases
);
Py_DECREF
(
old_base
);
Py_DECREF
(
old_mro
);
return
r
;
bail:
Py_DECREF
(
type
->
tp_bases
);
Py_DECREF
(
type
->
tp_base
);
if
(
type
->
tp_mro
!=
old_mro
)
{
Py_DECREF
(
type
->
tp_mro
);
}
type
->
tp_bases
=
old_bases
;
type
->
tp_base
=
old_base
;
type
->
tp_mro
=
old_mro
;
return
-
1
;
}
// commonClassSetup is for the common code between PyType_Ready (which is just for extension classes)
// and our internal type-creation endpoints (BoxedClass::BoxedClass()).
// TODO: Move more of the duplicated logic into here.
...
...
src/capi/typeobject.h
View file @
a921480a
...
...
@@ -32,6 +32,7 @@ void commonClassSetup(BoxedClass* cls);
// We could probably unify things more but that's for later.
PyTypeObject
*
best_base
(
PyObject
*
bases
)
noexcept
;
PyObject
*
mro_external
(
PyObject
*
self
)
noexcept
;
int
type_set_bases
(
PyTypeObject
*
type
,
PyObject
*
value
,
void
*
context
)
noexcept
;
}
#endif
src/runtime/capi.cpp
View file @
a921480a
...
...
@@ -461,8 +461,14 @@ extern "C" int PySequence_SetItem(PyObject* o, Py_ssize_t i, PyObject* v) noexce
}
extern
"C"
int
PySequence_DelItem
(
PyObject
*
o
,
Py_ssize_t
i
)
noexcept
{
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
return
-
1
;
try
{
// Not sure if this is really the same:
delitem
(
o
,
boxInt
(
i
));
return
0
;
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
-
1
;
}
}
extern
"C"
int
PySequence_SetSlice
(
PyObject
*
o
,
Py_ssize_t
i1
,
Py_ssize_t
i2
,
PyObject
*
v
)
noexcept
{
...
...
src/runtime/int.cpp
View file @
a921480a
...
...
@@ -196,11 +196,11 @@ extern "C" PyObject* PyInt_FromString(const char* s, char** pend, int base) noex
s
++
;
errno
=
0
;
if
(
base
==
0
&&
s
[
0
]
==
'0'
)
{
x
=
(
long
)
strtoul
(
s
,
&
end
,
base
);
x
=
(
long
)
PyOS_strtoul
(
const_cast
<
char
*>
(
s
)
,
&
end
,
base
);
if
(
x
<
0
)
return
PyLong_FromString
(
s
,
pend
,
base
);
}
else
x
=
strtol
(
s
,
&
end
,
base
);
x
=
PyOS_strtol
(
const_cast
<
char
*>
(
s
)
,
&
end
,
base
);
if
(
end
==
s
||
!
isalnum
(
Py_CHARMASK
(
end
[
-
1
])))
goto
bad
;
while
(
*
end
&&
isspace
(
Py_CHARMASK
(
*
end
)))
...
...
src/runtime/objmodel.cpp
View file @
a921480a
...
...
@@ -4165,7 +4165,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
return
rtn
;
}
RELEASE_ASSERT
(
arg3
->
cls
==
dict_cls
,
"%s"
,
getTypeName
(
arg3
));
RELEASE_ASSERT
(
PyDict_Check
(
arg3
)
,
"%s"
,
getTypeName
(
arg3
));
BoxedDict
*
attr_dict
=
static_cast
<
BoxedDict
*>
(
arg3
);
RELEASE_ASSERT
(
arg2
->
cls
==
tuple_cls
,
""
);
...
...
src/runtime/str.cpp
View file @
a921480a
...
...
@@ -44,6 +44,7 @@ extern "C" PyObject* string_index(PyStringObject* self, PyObject* args) noexcept
extern
"C"
PyObject
*
string_rindex
(
PyStringObject
*
self
,
PyObject
*
args
)
noexcept
;
extern
"C"
PyObject
*
string_rfind
(
PyStringObject
*
self
,
PyObject
*
args
)
noexcept
;
extern
"C"
PyObject
*
string_splitlines
(
PyStringObject
*
self
,
PyObject
*
args
)
noexcept
;
extern
"C"
PyObject
*
string__format__
(
PyObject
*
self
,
PyObject
*
args
)
noexcept
;
// from cpython's stringobject.c:
#define LEFTSTRIP 0
...
...
@@ -2652,6 +2653,7 @@ static PyMethodDef string_methods[] = {
{
"expandtabs"
,
(
PyCFunction
)
string_expandtabs
,
METH_VARARGS
,
NULL
},
{
"splitlines"
,
(
PyCFunction
)
string_splitlines
,
METH_VARARGS
,
NULL
},
{
"zfill"
,
(
PyCFunction
)
string_zfill
,
METH_VARARGS
,
NULL
},
{
"__format__"
,
(
PyCFunction
)
string__format__
,
METH_VARARGS
,
NULL
},
};
void
setupStr
()
{
...
...
src/runtime/types.cpp
View file @
a921480a
...
...
@@ -1546,6 +1546,22 @@ public:
return
rtn
;
}
static
Box
*
clear
(
Box
*
_self
)
{
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
||
attrs
->
hcls
->
type
==
HiddenClass
::
SINGLETON
,
""
);
while
(
true
)
{
const
auto
&
attrMap
=
attrs
->
hcls
->
getStrAttrOffsets
();
if
(
attrMap
.
size
()
==
0
)
break
;
self
->
b
->
delattr
(
attrMap
.
begin
()
->
first
(),
NULL
);
}
return
None
;
}
static
Box
*
len
(
Box
*
_self
)
{
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
...
@@ -1985,6 +2001,63 @@ static PyObject* object_reduce_ex(PyObject* self, PyObject* args) noexcept {
return
_common_reduce
(
self
,
proto
);
}
/*
from PEP 3101, this code implements:
class object:
def __format__(self, format_spec):
if isinstance(format_spec, str):
return format(str(self), format_spec)
elif isinstance(format_spec, unicode):
return format(unicode(self), format_spec)
*/
static
PyObject
*
object_format
(
PyObject
*
self
,
PyObject
*
args
)
noexcept
{
PyObject
*
format_spec
;
PyObject
*
self_as_str
=
NULL
;
PyObject
*
result
=
NULL
;
Py_ssize_t
format_len
;
if
(
!
PyArg_ParseTuple
(
args
,
"O:__format__"
,
&
format_spec
))
return
NULL
;
#ifdef Py_USING_UNICODE
if
(
PyUnicode_Check
(
format_spec
))
{
format_len
=
PyUnicode_GET_SIZE
(
format_spec
);
self_as_str
=
PyObject_Unicode
(
self
);
}
else
if
(
PyString_Check
(
format_spec
))
{
#else
if
(
PyString_Check
(
format_spec
))
{
#endif
format_len
=
PyString_GET_SIZE
(
format_spec
);
self_as_str
=
PyObject_Str
(
self
);
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
"argument to __format__ must be unicode or str"
);
return
NULL
;
}
if
(
self_as_str
!=
NULL
)
{
/* Issue 7994: If we're converting to a string, we
should reject format specifications */
if
(
format_len
>
0
)
{
if
(
PyErr_WarnEx
(
PyExc_PendingDeprecationWarning
,
"object.__format__ with a non-empty format "
"string is deprecated"
,
1
)
<
0
)
{
goto
done
;
}
/* Eventually this will become an error:
PyErr_Format(PyExc_TypeError,
"non-empty format string passed to object.__format__");
goto done;
*/
}
result
=
PyObject_Format
(
self_as_str
,
format_spec
);
}
done:
Py_XDECREF
(
self_as_str
);
return
result
;
}
static
Box
*
objectClass
(
Box
*
obj
,
void
*
context
)
{
assert
(
obj
->
cls
!=
instance_cls
);
// should override __class__ in classobj
return
obj
->
cls
;
...
...
@@ -2029,6 +2102,7 @@ static void objectSetClass(Box* obj, Box* val, void* context) {
static
PyMethodDef
object_methods
[]
=
{
{
"__reduce_ex__"
,
object_reduce_ex
,
METH_VARARGS
,
NULL
},
//
{
"__reduce__"
,
object_reduce
,
METH_VARARGS
,
NULL
},
//
{
"__format__"
,
object_format
,
METH_VARARGS
,
PyDoc_STR
(
"default object formatter"
)
},
};
static
Box
*
typeName
(
Box
*
b
,
void
*
)
{
...
...
@@ -2086,8 +2160,11 @@ static Box* typeBases(Box* b, void*) {
return
type
->
tp_bases
;
}
static
void
typeSetBases
(
Box
*
b
,
Box
*
v
,
void
*
)
{
Py_FatalError
(
"unimplemented"
);
static
void
typeSetBases
(
Box
*
b
,
Box
*
v
,
void
*
c
)
{
RELEASE_ASSERT
(
isSubclass
(
b
->
cls
,
type_cls
),
""
);
BoxedClass
*
type
=
static_cast
<
BoxedClass
*>
(
b
);
if
(
type_set_bases
(
type
,
v
,
c
)
==
-
1
)
throwCAPIException
();
}
// cls should be obj->cls.
...
...
@@ -2540,6 +2617,7 @@ void setupRuntime() {
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
itervalues
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"iteritems"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
iteritems
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"copy"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
copy
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"clear"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
clear
,
NONE
,
1
)));
attrwrapper_cls
->
giveAttr
(
"__len__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
len
,
BOXED_INT
,
1
)));
attrwrapper_cls
->
giveAttr
(
"__iter__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
iter
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"update"
,
...
...
test/tests/dict_setting.py
View file @
a921480a
...
...
@@ -38,3 +38,12 @@ p()
c1
.
__dict__
=
d
=
{}
d
[
'i'
]
=
5
p
()
class
C
(
object
):
def
foo
(
self
):
return
0
c
=
C
()
c
.
attr
=
"test"
c
.
__dict__
.
clear
()
print
hasattr
(
c
,
"attr"
)
print
hasattr
(
c
,
"foo"
)
test/tests/intmethods.py
View file @
a921480a
...
...
@@ -67,6 +67,7 @@ print type(int(L()))
print
int
(
u'123'
)
print
int
(
"9223372036854775808"
,
0
)
print
int
(
"0b101"
,
2
),
int
(
"0b101"
,
0
)
print
1
<<
63
,
1
<<
64
,
-
1
<<
63
,
-
1
<<
64
,
2
<<
63
print
type
(
1
<<
63
),
type
(
1
<<
64
),
type
(
-
1
<<
63
),
type
(
-
1
<<
64
),
type
(
2
<<
63
)
...
...
test/tests/mutable_bases.py
0 → 100644
View file @
a921480a
class
A
(
object
):
def
foo
(
self
):
print
"foo"
class
B
(
object
):
def
bar
(
self
):
print
"bar"
class
C
(
object
):
def
baz
(
self
):
print
"baz"
class
D
(
C
):
pass
print
D
.
__bases__
==
(
C
,)
print
hasattr
(
D
,
"bar"
)
try
:
D
.
__bases__
+=
(
A
,
B
,
C
)
except
Exception
as
e
:
print
e
# duplicate base class C
D
.
__bases__
+=
(
A
,
B
)
print
D
.
__bases__
==
(
C
,
A
,
B
,
C
)
print
D
.
__base__
==
(
C
)
D
().
foo
(),
D
().
bar
(),
D
().
baz
()
D
.
__bases__
=
(
C
,)
print
D
.
__bases__
==
(
C
,)
print
hasattr
(
D
,
"foo"
),
hasattr
(
D
,
"bar"
),
hasattr
(
D
,
"baz"
)
D
().
baz
()
# inheritance circle:
try
:
C
.
__bases__
=
(
D
,)
except
TypeError
as
e
:
print
e
class
Slots
(
object
):
__slots__
=
[
"a"
,
"b"
,
"c"
]
def
__init__
(
self
):
self
.
a
=
1
self
.
b
=
2
self
.
c
=
3
try
:
Slots
.
__bases__
=
(
A
,)
except
TypeError
:
print
"cought TypeError exception"
# pyston and cpython throw a different exception
# This tests are copied from CPython an can be removed when we support running test/cpython/test_descr.py
class
CPythonTests
(
object
):
def
assertEqual
(
self
,
x
,
y
):
assert
x
==
y
def
fail
(
self
,
msg
):
print
"Error"
,
msg
def
test_mutable_bases
(
self
):
# Testing mutable bases...
# stuff that should work:
class
C
(
object
):
pass
class
C2
(
object
):
def
__getattribute__
(
self
,
attr
):
if
attr
==
'a'
:
return
2
else
:
return
super
(
C2
,
self
).
__getattribute__
(
attr
)
def
meth
(
self
):
return
1
class
D
(
C
):
pass
class
E
(
D
):
pass
d
=
D
()
e
=
E
()
D
.
__bases__
=
(
C
,)
D
.
__bases__
=
(
C2
,)
self
.
assertEqual
(
d
.
meth
(),
1
)
self
.
assertEqual
(
e
.
meth
(),
1
)
self
.
assertEqual
(
d
.
a
,
2
)
self
.
assertEqual
(
e
.
a
,
2
)
self
.
assertEqual
(
C2
.
__subclasses__
(),
[
D
])
try
:
del
D
.
__bases__
except
(
TypeError
,
AttributeError
):
pass
else
:
self
.
fail
(
"shouldn't be able to delete .__bases__"
)
try
:
D
.
__bases__
=
()
except
TypeError
,
msg
:
if
str
(
msg
)
==
"a new-style class can't have only classic bases"
:
self
.
fail
(
"wrong error message for .__bases__ = ()"
)
else
:
self
.
fail
(
"shouldn't be able to set .__bases__ to ()"
)
try
:
D
.
__bases__
=
(
D
,)
except
TypeError
:
pass
else
:
# actually, we'll have crashed by here...
self
.
fail
(
"shouldn't be able to create inheritance cycles"
)
try
:
D
.
__bases__
=
(
C
,
C
)
except
TypeError
:
pass
else
:
self
.
fail
(
"didn't detect repeated base classes"
)
try
:
D
.
__bases__
=
(
E
,)
except
TypeError
:
pass
else
:
self
.
fail
(
"shouldn't be able to create inheritance cycles"
)
# let's throw a classic class into the mix:
class
Classic
:
def
meth2
(
self
):
return
3
D
.
__bases__
=
(
C
,
Classic
)
self
.
assertEqual
(
d
.
meth2
(),
3
)
self
.
assertEqual
(
e
.
meth2
(),
3
)
try
:
d
.
a
except
AttributeError
:
pass
else
:
self
.
fail
(
"attribute should have vanished"
)
try
:
D
.
__bases__
=
(
Classic
,)
except
TypeError
:
pass
else
:
self
.
fail
(
"new-style class must have a new-style base"
)
def
test_mutable_bases_catch_mro_conflict
(
self
):
# Testing mutable bases catch mro conflict...
class
A
(
object
):
pass
class
B
(
object
):
pass
class
C
(
A
,
B
):
pass
class
D
(
A
,
B
):
pass
class
E
(
C
,
D
):
pass
try
:
C
.
__bases__
=
(
B
,
A
)
except
TypeError
:
pass
else
:
self
.
fail
(
"didn't catch MRO conflict"
)
tests
=
CPythonTests
()
tests
.
test_mutable_bases
()
tests
.
test_mutable_bases_catch_mro_conflict
()
print
print
"Finished"
test/tests/str_functions.py
View file @
a921480a
...
...
@@ -168,3 +168,8 @@ it = iter("hello world")
print
list
(
it
)
print
"'{0}' '{1}'"
.
format
(
"Hello "
*
3
,
"Hello "
*
-
3
)
class
C
(
object
):
def
__str__
(
self
):
return
"my class"
print
"{0}"
.
format
(
C
())
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment