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
25922a87
Commit
25922a87
authored
Mar 11, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'django_dependencies'
parents
d544b623
bc62488a
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
541 additions
and
101 deletions
+541
-101
from_cpython/Include/object.h
from_cpython/Include/object.h
+2
-0
from_cpython/Lib/warnings.py
from_cpython/Lib/warnings.py
+6
-0
src/capi/abstract.cpp
src/capi/abstract.cpp
+33
-1
src/capi/modsupport.cpp
src/capi/modsupport.cpp
+51
-0
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+2
-0
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+2
-2
src/runtime/capi.cpp
src/runtime/capi.cpp
+0
-24
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+6
-63
src/runtime/set.cpp
src/runtime/set.cpp
+10
-0
src/runtime/types.cpp
src/runtime/types.cpp
+358
-8
src/runtime/types.h
src/runtime/types.h
+5
-0
test/tests/collections_test.py
test/tests/collections_test.py
+1
-0
test/tests/dict_setting.py
test/tests/dict_setting.py
+25
-0
test/tests/dir.py
test/tests/dir.py
+9
-3
test/tests/object_reduce.py
test/tests/object_reduce.py
+14
-0
test/tests/set.py
test/tests/set.py
+5
-0
test/tests/special_getattrs.py
test/tests/special_getattrs.py
+12
-0
No files found.
from_cpython/Include/object.h
View file @
25922a87
...
@@ -498,6 +498,8 @@ PyAPI_DATA(PyTypeObject*) type_cls;
...
@@ -498,6 +498,8 @@ PyAPI_DATA(PyTypeObject*) type_cls;
// Pyston change: this is no longer a static object
// Pyston change: this is no longer a static object
//PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */
//PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */
//PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */
//PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */
PyAPI_DATA
(
PyTypeObject
*
)
object_cls
;
#define PyBaseObject_Type (*object_cls)
// Pyston changes: these aren't direct macros any more [they potentially could be though]
// Pyston changes: these aren't direct macros any more [they potentially could be though]
PyAPI_FUNC
(
bool
)
_PyType_Check
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
bool
)
_PyType_Check
(
PyObject
*
)
PYSTON_NOEXCEPT
;
...
...
from_cpython/Lib/warnings.py
View file @
25922a87
...
@@ -183,6 +183,12 @@ def warn(message, category=None, stacklevel=1):
...
@@ -183,6 +183,12 @@ def warn(message, category=None, stacklevel=1):
assert
issubclass
(
category
,
Warning
)
assert
issubclass
(
category
,
Warning
)
# Get context information
# Get context information
try
:
try
:
# Pyston change: manually skip the call to _getframe.
# A ValueError() is supposed to specify that the "depth" argument is greater
# than the stack level, so it doesn't seem appropriate for us to throw as
# a signal that it's unimplemented.
raise
ValueError
()
caller
=
sys
.
_getframe
(
stacklevel
)
caller
=
sys
.
_getframe
(
stacklevel
)
except
ValueError
:
except
ValueError
:
globals
=
sys
.
__dict__
globals
=
sys
.
__dict__
...
...
src/capi/abstract.cpp
View file @
25922a87
...
@@ -521,7 +521,39 @@ static PyObject* call_function_tail(PyObject* callable, PyObject* args) {
...
@@ -521,7 +521,39 @@ static PyObject* call_function_tail(PyObject* callable, PyObject* args) {
}
}
extern
"C"
PyObject
*
PyObject_CallMethod
(
PyObject
*
o
,
const
char
*
name
,
const
char
*
format
,
...)
noexcept
{
extern
"C"
PyObject
*
PyObject_CallMethod
(
PyObject
*
o
,
const
char
*
name
,
const
char
*
format
,
...)
noexcept
{
Py_FatalError
(
"unimplemented"
);
va_list
va
;
PyObject
*
args
;
PyObject
*
func
=
NULL
;
PyObject
*
retval
=
NULL
;
if
(
o
==
NULL
||
name
==
NULL
)
return
null_error
();
func
=
PyObject_GetAttrString
(
o
,
name
);
if
(
func
==
NULL
)
{
PyErr_SetString
(
PyExc_AttributeError
,
name
);
return
0
;
}
if
(
!
PyCallable_Check
(
func
))
{
type_error
(
"attribute of type '%.200s' is not callable"
,
func
);
goto
exit
;
}
if
(
format
&&
*
format
)
{
va_start
(
va
,
format
);
args
=
Py_VaBuildValue
(
format
,
va
);
va_end
(
va
);
}
else
args
=
PyTuple_New
(
0
);
retval
=
call_function_tail
(
func
,
args
);
exit:
/* args gets consumed in call_function_tail */
Py_XDECREF
(
func
);
return
retval
;
}
}
extern
"C"
PyObject
*
PyObject_CallMethodObjArgs
(
PyObject
*
callable
,
PyObject
*
name
,
...)
noexcept
{
extern
"C"
PyObject
*
PyObject_CallMethodObjArgs
(
PyObject
*
callable
,
PyObject
*
name
,
...)
noexcept
{
...
...
src/capi/modsupport.cpp
View file @
25922a87
...
@@ -432,6 +432,57 @@ extern "C" int PyModule_AddIntConstant(PyObject* _m, const char* name, long valu
...
@@ -432,6 +432,57 @@ extern "C" int PyModule_AddIntConstant(PyObject* _m, const char* name, long valu
return
PyModule_AddObject
(
_m
,
name
,
boxInt
(
value
));
return
PyModule_AddObject
(
_m
,
name
,
boxInt
(
value
));
}
}
extern
"C"
PyObject
*
PyEval_CallMethod
(
PyObject
*
obj
,
const
char
*
methodname
,
const
char
*
format
,
...)
noexcept
{
va_list
vargs
;
PyObject
*
meth
;
PyObject
*
args
;
PyObject
*
res
;
meth
=
PyObject_GetAttrString
(
obj
,
methodname
);
if
(
meth
==
NULL
)
return
NULL
;
va_start
(
vargs
,
format
);
args
=
Py_VaBuildValue
(
format
,
vargs
);
va_end
(
vargs
);
if
(
args
==
NULL
)
{
Py_DECREF
(
meth
);
return
NULL
;
}
res
=
PyEval_CallObject
(
meth
,
args
);
Py_DECREF
(
meth
);
Py_DECREF
(
args
);
return
res
;
}
extern
"C"
PyObject
*
PyEval_CallObjectWithKeywords
(
PyObject
*
func
,
PyObject
*
arg
,
PyObject
*
kw
)
noexcept
{
PyObject
*
result
;
if
(
arg
==
NULL
)
{
arg
=
PyTuple_New
(
0
);
if
(
arg
==
NULL
)
return
NULL
;
}
else
if
(
!
PyTuple_Check
(
arg
))
{
PyErr_SetString
(
PyExc_TypeError
,
"argument list must be a tuple"
);
return
NULL
;
}
else
Py_INCREF
(
arg
);
if
(
kw
!=
NULL
&&
!
PyDict_Check
(
kw
))
{
PyErr_SetString
(
PyExc_TypeError
,
"keyword list must be a dictionary"
);
Py_DECREF
(
arg
);
return
NULL
;
}
result
=
PyObject_Call
(
func
,
arg
,
kw
);
Py_DECREF
(
arg
);
return
result
;
}
}
// namespace pyston
}
// namespace pyston
src/capi/typeobject.cpp
View file @
25922a87
...
@@ -2297,6 +2297,8 @@ void commonClassSetup(BoxedClass* cls) {
...
@@ -2297,6 +2297,8 @@ void commonClassSetup(BoxedClass* cls) {
if
(
PyType_Check
(
b
))
if
(
PyType_Check
(
b
))
inherit_slots
(
cls
,
static_cast
<
BoxedClass
*>
(
b
));
inherit_slots
(
cls
,
static_cast
<
BoxedClass
*>
(
b
));
}
}
assert
(
cls
->
tp_dict
&&
cls
->
tp_dict
->
cls
==
attrwrapper_cls
);
}
}
extern
"C"
void
PyType_Modified
(
PyTypeObject
*
type
)
noexcept
{
extern
"C"
void
PyType_Modified
(
PyTypeObject
*
type
)
noexcept
{
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
25922a87
...
@@ -483,8 +483,8 @@ Box* issubclass_func(Box* child, Box* parent) {
...
@@ -483,8 +483,8 @@ Box* issubclass_func(Box* child, Box* parent) {
return
boxBool
(
classobjIssubclass
(
static_cast
<
BoxedClassobj
*>
(
child
),
static_cast
<
BoxedClassobj
*>
(
parent
)));
return
boxBool
(
classobjIssubclass
(
static_cast
<
BoxedClassobj
*>
(
child
),
static_cast
<
BoxedClassobj
*>
(
parent
)));
}
}
assert
(
isSubclass
(
child
->
cls
,
type_cls
)
);
RELEASE_ASSERT
(
isSubclass
(
child
->
cls
,
type_cls
),
""
);
if
(
parent
->
cls
!=
type_cls
)
if
(
!
isSubclass
(
parent
->
cls
,
type_cls
)
)
return
False
;
return
False
;
return
boxBool
(
isSubclass
(
static_cast
<
BoxedClass
*>
(
child
),
static_cast
<
BoxedClass
*>
(
parent
)));
return
boxBool
(
isSubclass
(
static_cast
<
BoxedClass
*>
(
child
),
static_cast
<
BoxedClass
*>
(
parent
)));
...
...
src/runtime/capi.cpp
View file @
25922a87
...
@@ -373,30 +373,6 @@ extern "C" int PyObject_Not(PyObject* o) noexcept {
...
@@ -373,30 +373,6 @@ extern "C" int PyObject_Not(PyObject* o) noexcept {
Py_FatalError
(
"unimplemented"
);
Py_FatalError
(
"unimplemented"
);
}
}
extern
"C"
PyObject
*
PyEval_CallObjectWithKeywords
(
PyObject
*
func
,
PyObject
*
arg
,
PyObject
*
kw
)
noexcept
{
PyObject
*
result
;
if
(
arg
==
NULL
)
{
arg
=
PyTuple_New
(
0
);
if
(
arg
==
NULL
)
return
NULL
;
}
else
if
(
!
PyTuple_Check
(
arg
))
{
PyErr_SetString
(
PyExc_TypeError
,
"argument list must be a tuple"
);
return
NULL
;
}
else
Py_INCREF
(
arg
);
if
(
kw
!=
NULL
&&
!
PyDict_Check
(
kw
))
{
PyErr_SetString
(
PyExc_TypeError
,
"keyword list must be a dictionary"
);
Py_DECREF
(
arg
);
return
NULL
;
}
result
=
PyObject_Call
(
func
,
arg
,
kw
);
Py_DECREF
(
arg
);
return
result
;
}
extern
"C"
PyObject
*
PyObject_Call
(
PyObject
*
callable_object
,
PyObject
*
args
,
PyObject
*
kw
)
noexcept
{
extern
"C"
PyObject
*
PyObject_Call
(
PyObject
*
callable_object
,
PyObject
*
args
,
PyObject
*
kw
)
noexcept
{
try
{
try
{
if
(
kw
)
if
(
kw
)
...
...
src/runtime/objmodel.cpp
View file @
25922a87
...
@@ -383,6 +383,9 @@ void BoxedClass::finishInitialization() {
...
@@ -383,6 +383,9 @@ void BoxedClass::finishInitialization() {
tp_clear
=
tp_base
->
tp_clear
;
tp_clear
=
tp_base
->
tp_clear
;
}
}
assert
(
!
this
->
tp_dict
);
this
->
tp_dict
=
makeAttrWrapper
(
this
);
commonClassSetup
(
this
);
commonClassSetup
(
this
);
}
}
...
@@ -1523,16 +1526,6 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
...
@@ -1523,16 +1526,6 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
static
StatCounter
slowpath_getattr
(
"slowpath_getattr"
);
static
StatCounter
slowpath_getattr
(
"slowpath_getattr"
);
slowpath_getattr
.
log
();
slowpath_getattr
.
log
();
bool
is_dunder
=
(
attr
[
0
]
==
'_'
&&
attr
[
1
]
==
'_'
);
if
(
is_dunder
)
{
if
(
strcmp
(
attr
,
"__dict__"
)
==
0
)
{
// TODO this is wrong, should be added at the class level as a getset
if
(
obj
->
cls
->
instancesHaveHCAttrs
())
return
makeAttrWrapper
(
obj
);
}
}
if
(
VERBOSITY
()
>=
2
)
{
if
(
VERBOSITY
()
>=
2
)
{
#if !DISABLE_STATS
#if !DISABLE_STATS
std
::
string
per_name_stat_name
=
"getattr__"
+
std
::
string
(
attr
);
std
::
string
per_name_stat_name
=
"getattr__"
+
std
::
string
(
attr
);
...
@@ -1578,21 +1571,6 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
...
@@ -1578,21 +1571,6 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
return
val
;
return
val
;
}
}
if
(
is_dunder
)
{
// There's more to it than this:
if
(
strcmp
(
attr
,
"__class__"
)
==
0
)
{
assert
(
obj
->
cls
!=
instance_cls
);
// I think in this case __class__ is supposed to be the classobj?
return
obj
->
cls
;
}
// This doesn't belong here either:
if
(
strcmp
(
attr
,
"__bases__"
)
==
0
&&
isSubclass
(
obj
->
cls
,
type_cls
))
{
BoxedClass
*
cls
=
static_cast
<
BoxedClass
*>
(
obj
);
assert
(
cls
->
tp_bases
);
return
cls
->
tp_bases
;
}
}
raiseAttributeError
(
obj
,
attr
);
raiseAttributeError
(
obj
,
attr
);
}
}
...
@@ -1658,44 +1636,6 @@ void setattrInternal(Box* obj, const std::string& attr, Box* val, SetattrRewrite
...
@@ -1658,44 +1636,6 @@ void setattrInternal(Box* obj, const std::string& attr, Box* val, SetattrRewrite
}
}
}
}
if
(
attr
==
"__class__"
)
{
if
(
!
isSubclass
(
val
->
cls
,
type_cls
))
raiseExcHelper
(
TypeError
,
"__class__ must be set to new-style class, not '%s' object"
,
val
->
cls
->
tp_name
);
auto
new_cls
=
static_cast
<
BoxedClass
*>
(
val
);
// Conservative Pyston checks: make sure that both classes are derived only from Pyston types,
// and that they don't define any extra C-level fields
RELEASE_ASSERT
(
val
->
cls
==
type_cls
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
cls
==
type_cls
,
""
);
for
(
auto
_base
:
static_cast
<
BoxedTuple
*>
(
obj
->
cls
->
tp_mro
)
->
elts
)
{
BoxedClass
*
base
=
static_cast
<
BoxedClass
*>
(
_base
);
RELEASE_ASSERT
(
base
->
is_pyston_class
,
""
);
}
for
(
auto
_base
:
static_cast
<
BoxedTuple
*>
(
new_cls
->
tp_mro
)
->
elts
)
{
BoxedClass
*
base
=
static_cast
<
BoxedClass
*>
(
_base
);
RELEASE_ASSERT
(
base
->
is_pyston_class
,
""
);
}
RELEASE_ASSERT
(
obj
->
cls
->
tp_basicsize
==
object_cls
->
tp_basicsize
+
sizeof
(
HCAttrs
)
+
sizeof
(
Box
**
),
""
);
RELEASE_ASSERT
(
new_cls
->
tp_basicsize
==
object_cls
->
tp_basicsize
+
sizeof
(
HCAttrs
)
+
sizeof
(
Box
**
),
""
);
RELEASE_ASSERT
(
obj
->
cls
->
attrs_offset
!=
0
,
""
);
RELEASE_ASSERT
(
new_cls
->
attrs_offset
!=
0
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
tp_weaklistoffset
!=
0
,
""
);
RELEASE_ASSERT
(
new_cls
->
tp_weaklistoffset
!=
0
,
""
);
// Normal Python checks.
// TODO there are more checks to add here, and they should throw errors not asserts
RELEASE_ASSERT
(
obj
->
cls
->
tp_basicsize
==
new_cls
->
tp_basicsize
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
tp_dictoffset
==
new_cls
->
tp_dictoffset
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
tp_weaklistoffset
==
new_cls
->
tp_weaklistoffset
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
attrs_offset
==
new_cls
->
attrs_offset
,
""
);
obj
->
cls
=
new_cls
;
return
;
}
// Lookup a descriptor
// Lookup a descriptor
Box
*
descr
=
NULL
;
Box
*
descr
=
NULL
;
RewriterVar
*
r_descr
=
NULL
;
RewriterVar
*
r_descr
=
NULL
;
...
@@ -3769,6 +3709,9 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
...
@@ -3769,6 +3709,9 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
// TODO: how much of these should be in BoxedClass::finishInitialization()?
// TODO: how much of these should be in BoxedClass::finishInitialization()?
made
->
tp_dictoffset
=
base
->
tp_dictoffset
;
made
->
tp_dictoffset
=
base
->
tp_dictoffset
;
if
(
!
made
->
getattr
(
"__dict__"
)
&&
(
made
->
instancesHaveHCAttrs
()
||
made
->
instancesHaveDictAttrs
()))
made
->
giveAttr
(
"__dict__"
,
dict_descr
);
for
(
const
auto
&
p
:
attr_dict
->
d
)
{
for
(
const
auto
&
p
:
attr_dict
->
d
)
{
auto
k
=
coerceUnicodeToStr
(
p
.
first
);
auto
k
=
coerceUnicodeToStr
(
p
.
first
);
...
...
src/runtime/set.cpp
View file @
25922a87
...
@@ -231,6 +231,14 @@ Box* setUpdate(BoxedSet* self, BoxedTuple* args) {
...
@@ -231,6 +231,14 @@ Box* setUpdate(BoxedSet* self, BoxedTuple* args) {
return
None
;
return
None
;
}
}
Box
*
setCopy
(
BoxedSet
*
self
)
{
assert
(
self
->
cls
==
set_cls
);
BoxedSet
*
rtn
=
new
BoxedSet
();
rtn
->
s
.
insert
(
self
->
s
.
begin
(),
self
->
s
.
end
());
return
rtn
;
}
Box
*
setContains
(
BoxedSet
*
self
,
Box
*
v
)
{
Box
*
setContains
(
BoxedSet
*
self
,
Box
*
v
)
{
assert
(
self
->
cls
==
set_cls
||
self
->
cls
==
frozenset_cls
);
assert
(
self
->
cls
==
set_cls
||
self
->
cls
==
frozenset_cls
);
return
boxBool
(
self
->
s
.
count
(
v
)
!=
0
);
return
boxBool
(
self
->
s
.
count
(
v
)
!=
0
);
...
@@ -313,6 +321,8 @@ void setupSet() {
...
@@ -313,6 +321,8 @@ void setupSet() {
set_cls
->
giveAttr
(
"clear"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setClear
,
NONE
,
1
)));
set_cls
->
giveAttr
(
"clear"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setClear
,
NONE
,
1
)));
set_cls
->
giveAttr
(
"update"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setUpdate
,
NONE
,
1
,
0
,
true
,
false
)));
set_cls
->
giveAttr
(
"update"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setUpdate
,
NONE
,
1
,
0
,
true
,
false
)));
set_cls
->
giveAttr
(
"copy"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setCopy
,
UNKNOWN
,
1
)));
set_cls
->
freeze
();
set_cls
->
freeze
();
frozenset_cls
->
freeze
();
frozenset_cls
->
freeze
();
}
}
...
...
src/runtime/types.cpp
View file @
25922a87
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <stdint.h>
#include <stdint.h>
#include "capi/typeobject.h"
#include "capi/typeobject.h"
#include "capi/types.h"
#include "core/options.h"
#include "core/options.h"
#include "core/stats.h"
#include "core/stats.h"
#include "core/types.h"
#include "core/types.h"
...
@@ -102,7 +103,7 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
...
@@ -102,7 +103,7 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
}
}
#endif
#endif
if
(
!
cls
->
tp_mro
)
{
if
(
!
cls
->
tp_mro
)
{
assert
(
!
list_cls
);
assert
(
!
attrwrapper_cls
);
// the last class to be set up during bootstrapping
}
else
{
}
else
{
assert
(
cls
->
tp_mro
&&
"maybe we should just skip these checks if !mro"
);
assert
(
cls
->
tp_mro
&&
"maybe we should just skip these checks if !mro"
);
assert
(
cls
->
tp_mro
->
cls
==
tuple_cls
);
assert
(
cls
->
tp_mro
->
cls
==
tuple_cls
);
...
@@ -428,6 +429,20 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) {
...
@@ -428,6 +429,20 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) {
}
}
}
}
static
Box
*
typeDict
(
Box
*
obj
,
void
*
context
)
{
if
(
obj
->
cls
->
instancesHaveHCAttrs
())
return
makeAttrWrapper
(
obj
);
if
(
obj
->
cls
->
instancesHaveDictAttrs
())
return
obj
->
getDict
();
abort
();
}
static
void
typeSetDict
(
Box
*
obj
,
Box
*
val
,
void
*
context
)
{
Py_FatalError
(
"unimplemented"
);
}
Box
*
dict_descr
=
NULL
;
extern
"C"
void
instancemethodGCHandler
(
GCVisitor
*
v
,
Box
*
b
)
{
extern
"C"
void
instancemethodGCHandler
(
GCVisitor
*
v
,
Box
*
b
)
{
BoxedInstanceMethod
*
im
=
(
BoxedInstanceMethod
*
)
b
;
BoxedInstanceMethod
*
im
=
(
BoxedInstanceMethod
*
)
b
;
...
@@ -613,7 +628,7 @@ extern "C" Box* createUserClass(const std::string* name, Box* _bases, Box* _attr
...
@@ -613,7 +628,7 @@ extern "C" Box* createUserClass(const std::string* name, Box* _bases, Box* _attr
}
}
// Go through these routines since they do some normalization:
// Go through these routines since they do some normalization:
PyErr_Restore
(
e
.
type
,
e
.
value
,
NULL
);
PyErr_Restore
(
e
.
type
,
e
.
value
,
e
.
traceback
);
throwCAPIException
();
throwCAPIException
();
}
}
}
}
...
@@ -1011,6 +1026,21 @@ public:
...
@@ -1011,6 +1026,21 @@ public:
return
None
;
return
None
;
}
}
static
Box
*
setdefault
(
Box
*
_self
,
Box
*
_key
,
Box
*
value
)
{
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
_key
=
coerceUnicodeToStr
(
_key
);
RELEASE_ASSERT
(
_key
->
cls
==
str_cls
,
""
);
BoxedString
*
key
=
static_cast
<
BoxedString
*>
(
_key
);
Box
*
cur
=
self
->
b
->
getattr
(
key
->
s
);
if
(
cur
)
return
cur
;
self
->
b
->
setattr
(
key
->
s
,
value
,
NULL
);
return
value
;
}
static
Box
*
get
(
Box
*
_self
,
Box
*
_key
,
Box
*
def
)
{
static
Box
*
get
(
Box
*
_self
,
Box
*
_key
,
Box
*
def
)
{
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
...
@@ -1144,8 +1174,14 @@ public:
...
@@ -1144,8 +1174,14 @@ public:
for
(
const
auto
&
p
:
attrs
->
hcls
->
attr_offsets
)
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
attr_offsets
)
{
self
->
b
->
setattr
(
p
.
first
,
attrs
->
attr_list
->
attrs
[
p
.
second
],
NULL
);
self
->
b
->
setattr
(
p
.
first
,
attrs
->
attr_list
->
attrs
[
p
.
second
],
NULL
);
}
}
}
else
if
(
_container
->
cls
==
dict_cls
)
{
BoxedDict
*
container
=
static_cast
<
BoxedDict
*>
(
_container
);
for
(
const
auto
&
p
:
container
->
d
)
{
AttrWrapper
::
setitem
(
self
,
p
.
first
,
p
.
second
);
}
}
else
{
}
else
{
RELEASE_ASSERT
(
0
,
"not implemented
"
);
RELEASE_ASSERT
(
0
,
"not implemented
: %s"
,
_container
->
cls
->
tp_name
);
}
}
return
None
;
return
None
;
}
}
...
@@ -1231,6 +1267,289 @@ Box* objectStr(Box* obj) {
...
@@ -1231,6 +1267,289 @@ Box* objectStr(Box* obj) {
return
obj
->
reprIC
();
return
obj
->
reprIC
();
}
}
static
PyObject
*
import_copyreg
(
void
)
noexcept
{
static
PyObject
*
copyreg_str
;
if
(
!
copyreg_str
)
{
copyreg_str
=
PyGC_AddRoot
(
PyString_InternFromString
(
"copy_reg"
));
if
(
copyreg_str
==
NULL
)
return
NULL
;
}
return
PyImport_Import
(
copyreg_str
);
}
static
PyObject
*
slotnames
(
PyObject
*
cls
)
noexcept
{
PyObject
*
clsdict
;
PyObject
*
copyreg
;
PyObject
*
slotnames
;
if
(
!
PyType_Check
(
cls
))
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
clsdict
=
((
PyTypeObject
*
)
cls
)
->
tp_dict
;
slotnames
=
PyDict_GetItemString
(
clsdict
,
"__slotnames__"
);
if
(
slotnames
!=
NULL
&&
PyList_Check
(
slotnames
))
{
Py_INCREF
(
slotnames
);
return
slotnames
;
}
copyreg
=
import_copyreg
();
if
(
copyreg
==
NULL
)
return
NULL
;
slotnames
=
PyObject_CallMethod
(
copyreg
,
"_slotnames"
,
"O"
,
cls
);
Py_DECREF
(
copyreg
);
if
(
slotnames
!=
NULL
&&
slotnames
!=
Py_None
&&
!
PyList_Check
(
slotnames
))
{
PyErr_SetString
(
PyExc_TypeError
,
"copy_reg._slotnames didn't return a list or None"
);
Py_DECREF
(
slotnames
);
slotnames
=
NULL
;
}
return
slotnames
;
}
static
PyObject
*
reduce_2
(
PyObject
*
obj
)
noexcept
{
PyObject
*
cls
,
*
getnewargs
;
PyObject
*
args
=
NULL
,
*
args2
=
NULL
;
PyObject
*
getstate
=
NULL
,
*
state
=
NULL
,
*
names
=
NULL
;
PyObject
*
slots
=
NULL
,
*
listitems
=
NULL
,
*
dictitems
=
NULL
;
PyObject
*
copyreg
=
NULL
,
*
newobj
=
NULL
,
*
res
=
NULL
;
Py_ssize_t
i
,
n
;
cls
=
PyObject_GetAttrString
(
obj
,
"__class__"
);
if
(
cls
==
NULL
)
return
NULL
;
getnewargs
=
PyObject_GetAttrString
(
obj
,
"__getnewargs__"
);
if
(
getnewargs
!=
NULL
)
{
args
=
PyObject_CallObject
(
getnewargs
,
NULL
);
Py_DECREF
(
getnewargs
);
if
(
args
!=
NULL
&&
!
PyTuple_Check
(
args
))
{
PyErr_Format
(
PyExc_TypeError
,
"__getnewargs__ should return a tuple, "
"not '%.200s'"
,
Py_TYPE
(
args
)
->
tp_name
);
goto
end
;
}
}
else
{
PyErr_Clear
();
args
=
PyTuple_New
(
0
);
}
if
(
args
==
NULL
)
goto
end
;
getstate
=
PyObject_GetAttrString
(
obj
,
"__getstate__"
);
if
(
getstate
!=
NULL
)
{
state
=
PyObject_CallObject
(
getstate
,
NULL
);
Py_DECREF
(
getstate
);
if
(
state
==
NULL
)
goto
end
;
}
else
{
PyErr_Clear
();
state
=
PyObject_GetAttrString
(
obj
,
"__dict__"
);
if
(
state
==
NULL
)
{
PyErr_Clear
();
state
=
Py_None
;
Py_INCREF
(
state
);
}
names
=
slotnames
(
cls
);
if
(
names
==
NULL
)
goto
end
;
if
(
names
!=
Py_None
)
{
assert
(
PyList_Check
(
names
));
slots
=
PyDict_New
();
if
(
slots
==
NULL
)
goto
end
;
n
=
0
;
/* Can't pre-compute the list size; the list
is stored on the class so accessible to other
threads, which may be run by DECREF */
for
(
i
=
0
;
i
<
PyList_GET_SIZE
(
names
);
i
++
)
{
PyObject
*
name
,
*
value
;
name
=
PyList_GET_ITEM
(
names
,
i
);
value
=
PyObject_GetAttr
(
obj
,
name
);
if
(
value
==
NULL
)
PyErr_Clear
();
else
{
int
err
=
PyDict_SetItem
(
slots
,
name
,
value
);
Py_DECREF
(
value
);
if
(
err
)
goto
end
;
n
++
;
}
}
if
(
n
)
{
state
=
Py_BuildValue
(
"(NO)"
,
state
,
slots
);
if
(
state
==
NULL
)
goto
end
;
}
}
}
if
(
!
PyList_Check
(
obj
))
{
listitems
=
Py_None
;
Py_INCREF
(
listitems
);
}
else
{
listitems
=
PyObject_GetIter
(
obj
);
if
(
listitems
==
NULL
)
goto
end
;
}
if
(
!
PyDict_Check
(
obj
))
{
dictitems
=
Py_None
;
Py_INCREF
(
dictitems
);
}
else
{
dictitems
=
PyObject_CallMethod
(
obj
,
"iteritems"
,
""
);
if
(
dictitems
==
NULL
)
goto
end
;
}
copyreg
=
import_copyreg
();
if
(
copyreg
==
NULL
)
goto
end
;
newobj
=
PyObject_GetAttrString
(
copyreg
,
"__newobj__"
);
if
(
newobj
==
NULL
)
goto
end
;
n
=
PyTuple_GET_SIZE
(
args
);
args2
=
PyTuple_New
(
n
+
1
);
if
(
args2
==
NULL
)
goto
end
;
PyTuple_SET_ITEM
(
args2
,
0
,
cls
);
cls
=
NULL
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
PyObject
*
v
=
PyTuple_GET_ITEM
(
args
,
i
);
Py_INCREF
(
v
);
PyTuple_SET_ITEM
(
args2
,
i
+
1
,
v
);
}
res
=
PyTuple_Pack
(
5
,
newobj
,
args2
,
state
,
listitems
,
dictitems
);
end:
Py_XDECREF
(
cls
);
Py_XDECREF
(
args
);
Py_XDECREF
(
args2
);
Py_XDECREF
(
slots
);
Py_XDECREF
(
state
);
Py_XDECREF
(
names
);
Py_XDECREF
(
listitems
);
Py_XDECREF
(
dictitems
);
Py_XDECREF
(
copyreg
);
Py_XDECREF
(
newobj
);
return
res
;
}
static
PyObject
*
_common_reduce
(
PyObject
*
self
,
int
proto
)
noexcept
{
PyObject
*
copyreg
,
*
res
;
if
(
proto
>=
2
)
return
reduce_2
(
self
);
copyreg
=
import_copyreg
();
if
(
!
copyreg
)
return
NULL
;
res
=
PyEval_CallMethod
(
copyreg
,
"_reduce_ex"
,
"(Oi)"
,
self
,
proto
);
Py_DECREF
(
copyreg
);
return
res
;
}
static
PyObject
*
object_reduce
(
PyObject
*
self
,
PyObject
*
args
)
noexcept
{
int
proto
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:__reduce__"
,
&
proto
))
return
NULL
;
return
_common_reduce
(
self
,
proto
);
}
static
PyObject
*
object_reduce_ex
(
PyObject
*
self
,
PyObject
*
args
)
noexcept
{
PyObject
*
reduce
,
*
res
;
int
proto
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:__reduce_ex__"
,
&
proto
))
return
NULL
;
reduce
=
PyObject_GetAttrString
(
self
,
"__reduce__"
);
if
(
reduce
==
NULL
)
PyErr_Clear
();
else
{
PyObject
*
cls
,
*
clsreduce
,
*
objreduce
;
int
override
;
cls
=
PyObject_GetAttrString
(
self
,
"__class__"
);
if
(
cls
==
NULL
)
{
Py_DECREF
(
reduce
);
return
NULL
;
}
clsreduce
=
PyObject_GetAttrString
(
cls
,
"__reduce__"
);
Py_DECREF
(
cls
);
if
(
clsreduce
==
NULL
)
{
Py_DECREF
(
reduce
);
return
NULL
;
}
objreduce
=
PyDict_GetItemString
(
PyBaseObject_Type
.
tp_dict
,
"__reduce__"
);
override
=
(
clsreduce
!=
objreduce
);
Py_DECREF
(
clsreduce
);
if
(
override
)
{
res
=
PyObject_CallObject
(
reduce
,
NULL
);
Py_DECREF
(
reduce
);
return
res
;
}
else
Py_DECREF
(
reduce
);
}
return
_common_reduce
(
self
,
proto
);
}
static
Box
*
objectClass
(
Box
*
obj
,
void
*
context
)
{
assert
(
obj
->
cls
!=
instance_cls
);
// should override __class__ in classobj
return
obj
->
cls
;
}
static
void
objectSetClass
(
Box
*
obj
,
Box
*
val
,
void
*
context
)
{
if
(
!
isSubclass
(
val
->
cls
,
type_cls
))
raiseExcHelper
(
TypeError
,
"__class__ must be set to new-style class, not '%s' object"
,
val
->
cls
->
tp_name
);
auto
new_cls
=
static_cast
<
BoxedClass
*>
(
val
);
// Conservative Pyston checks: make sure that both classes are derived only from Pyston types,
// and that they don't define any extra C-level fields
RELEASE_ASSERT
(
val
->
cls
==
type_cls
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
cls
==
type_cls
,
""
);
for
(
auto
_base
:
static_cast
<
BoxedTuple
*>
(
obj
->
cls
->
tp_mro
)
->
elts
)
{
BoxedClass
*
base
=
static_cast
<
BoxedClass
*>
(
_base
);
RELEASE_ASSERT
(
base
->
is_pyston_class
,
""
);
}
for
(
auto
_base
:
static_cast
<
BoxedTuple
*>
(
new_cls
->
tp_mro
)
->
elts
)
{
BoxedClass
*
base
=
static_cast
<
BoxedClass
*>
(
_base
);
RELEASE_ASSERT
(
base
->
is_pyston_class
,
""
);
}
RELEASE_ASSERT
(
obj
->
cls
->
tp_basicsize
==
object_cls
->
tp_basicsize
+
sizeof
(
HCAttrs
)
+
sizeof
(
Box
**
),
""
);
RELEASE_ASSERT
(
new_cls
->
tp_basicsize
==
object_cls
->
tp_basicsize
+
sizeof
(
HCAttrs
)
+
sizeof
(
Box
**
),
""
);
RELEASE_ASSERT
(
obj
->
cls
->
attrs_offset
!=
0
,
""
);
RELEASE_ASSERT
(
new_cls
->
attrs_offset
!=
0
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
tp_weaklistoffset
!=
0
,
""
);
RELEASE_ASSERT
(
new_cls
->
tp_weaklistoffset
!=
0
,
""
);
// Normal Python checks.
// TODO there are more checks to add here, and they should throw errors not asserts
RELEASE_ASSERT
(
obj
->
cls
->
tp_basicsize
==
new_cls
->
tp_basicsize
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
tp_dictoffset
==
new_cls
->
tp_dictoffset
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
tp_weaklistoffset
==
new_cls
->
tp_weaklistoffset
,
""
);
RELEASE_ASSERT
(
obj
->
cls
->
attrs_offset
==
new_cls
->
attrs_offset
,
""
);
obj
->
cls
=
new_cls
;
}
static
PyMethodDef
object_methods
[]
=
{
{
"__reduce_ex__"
,
object_reduce_ex
,
METH_VARARGS
,
NULL
},
//
{
"__reduce__"
,
object_reduce
,
METH_VARARGS
,
NULL
},
//
};
static
Box
*
typeName
(
Box
*
b
,
void
*
)
{
static
Box
*
typeName
(
Box
*
b
,
void
*
)
{
RELEASE_ASSERT
(
isSubclass
(
b
->
cls
,
type_cls
),
""
);
RELEASE_ASSERT
(
isSubclass
(
b
->
cls
,
type_cls
),
""
);
BoxedClass
*
type
=
static_cast
<
BoxedClass
*>
(
b
);
BoxedClass
*
type
=
static_cast
<
BoxedClass
*>
(
b
);
...
@@ -1278,6 +1597,18 @@ static void typeSetName(Box* b, Box* v, void*) {
...
@@ -1278,6 +1597,18 @@ static void typeSetName(Box* b, Box* v, void*) {
ht
->
tp_name
=
s
->
s
.
c_str
();
ht
->
tp_name
=
s
->
s
.
c_str
();
}
}
static
Box
*
typeBases
(
Box
*
b
,
void
*
)
{
RELEASE_ASSERT
(
isSubclass
(
b
->
cls
,
type_cls
),
""
);
BoxedClass
*
type
=
static_cast
<
BoxedClass
*>
(
b
);
assert
(
type
->
tp_bases
);
return
type
->
tp_bases
;
}
static
void
typeSetBases
(
Box
*
b
,
Box
*
v
,
void
*
)
{
Py_FatalError
(
"unimplemented"
);
}
// cls should be obj->cls.
// cls should be obj->cls.
// Added as parameter because it should typically be available
// Added as parameter because it should typically be available
inline
void
initUserAttrs
(
Box
*
obj
,
BoxedClass
*
cls
)
{
inline
void
initUserAttrs
(
Box
*
obj
,
BoxedClass
*
cls
)
{
...
@@ -1377,13 +1708,21 @@ void setupRuntime() {
...
@@ -1377,13 +1708,21 @@ void setupRuntime() {
EmptyTuple
=
new
BoxedTuple
({});
EmptyTuple
=
new
BoxedTuple
({});
gc
::
registerPermanentRoot
(
EmptyTuple
);
gc
::
registerPermanentRoot
(
EmptyTuple
);
list_cls
=
new
BoxedHeapClass
(
object_cls
,
&
listGCHandler
,
0
,
0
,
sizeof
(
BoxedList
),
false
,
boxStrConstant
(
"list"
));
list_cls
=
new
BoxedHeapClass
(
object_cls
,
&
listGCHandler
,
0
,
0
,
sizeof
(
BoxedList
),
false
,
boxStrConstant
(
"list"
));
pyston_getset_cls
=
new
BoxedHeapClass
(
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedGetsetDescriptor
),
false
,
boxStrConstant
(
"getset"
));
attrwrapper_cls
=
new
BoxedHeapClass
(
object_cls
,
&
AttrWrapper
::
gcHandler
,
0
,
0
,
sizeof
(
AttrWrapper
),
false
,
new
BoxedString
(
"attrwrapper"
));
// Kind of hacky, but it's easier to manually construct the mro for a couple key classes
// Kind of hacky, but it's easier to manually construct the mro for a couple key classes
// than try to make the MRO construction code be safe against say, tuple_cls not having
// than try to make the MRO construction code be safe against say, tuple_cls not having
// an mro (since the mro is stored as a tuple).
// an mro (since the mro is stored as a tuple).
object_cls
->
tp_mro
=
new
BoxedTuple
({
object_cls
});
tuple_cls
->
tp_mro
=
new
BoxedTuple
({
tuple_cls
,
object_cls
});
tuple_cls
->
tp_mro
=
new
BoxedTuple
({
tuple_cls
,
object_cls
});
list_cls
->
tp_mro
=
new
BoxedTuple
({
list_cls
,
object_cls
});
list_cls
->
tp_mro
=
new
BoxedTuple
({
list_cls
,
object_cls
});
type_cls
->
tp_mro
=
new
BoxedTuple
({
type_cls
,
object_cls
});
type_cls
->
tp_mro
=
new
BoxedTuple
({
type_cls
,
object_cls
});
pyston_getset_cls
->
tp_mro
=
new
BoxedTuple
({
pyston_getset_cls
,
object_cls
});
attrwrapper_cls
->
tp_mro
=
new
BoxedTuple
({
attrwrapper_cls
,
object_cls
});
object_cls
->
finishInitialization
();
object_cls
->
finishInitialization
();
type_cls
->
finishInitialization
();
type_cls
->
finishInitialization
();
...
@@ -1392,9 +1731,14 @@ void setupRuntime() {
...
@@ -1392,9 +1731,14 @@ void setupRuntime() {
none_cls
->
finishInitialization
();
none_cls
->
finishInitialization
();
tuple_cls
->
finishInitialization
();
tuple_cls
->
finishInitialization
();
list_cls
->
finishInitialization
();
list_cls
->
finishInitialization
();
pyston_getset_cls
->
finishInitialization
();
attrwrapper_cls
->
finishInitialization
();
str_cls
->
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
str_cls
->
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
dict_descr
=
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeDict
,
typeSetDict
,
NULL
);
gc
::
registerPermanentRoot
(
dict_descr
);
type_cls
->
giveAttr
(
"__dict__"
,
dict_descr
);
module_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
offsetof
(
BoxedModule
,
attrs
),
0
,
module_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
offsetof
(
BoxedModule
,
attrs
),
0
,
...
@@ -1434,8 +1778,6 @@ void setupRuntime() {
...
@@ -1434,8 +1778,6 @@ void setupRuntime() {
sizeof
(
BoxedSet
),
false
,
"frozenset"
);
sizeof
(
BoxedSet
),
false
,
"frozenset"
);
member_cls
member_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedMemberDescriptor
),
false
,
"member"
);
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedMemberDescriptor
),
false
,
"member"
);
pyston_getset_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedGetsetDescriptor
),
false
,
"getset"
);
capi_getset_cls
capi_getset_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedGetsetDescriptor
),
false
,
"getset"
);
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedGetsetDescriptor
),
false
,
"getset"
);
closure_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
closureGCHandler
,
offsetof
(
BoxedClosure
,
attrs
),
0
,
closure_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
closureGCHandler
,
offsetof
(
BoxedClosure
,
attrs
),
0
,
...
@@ -1446,8 +1788,6 @@ void setupRuntime() {
...
@@ -1446,8 +1788,6 @@ void setupRuntime() {
sizeof
(
BoxedStaticmethod
),
false
,
"staticmethod"
);
sizeof
(
BoxedStaticmethod
),
false
,
"staticmethod"
);
classmethod_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
classmethodGCHandler
,
0
,
0
,
classmethod_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
classmethodGCHandler
,
0
,
0
,
sizeof
(
BoxedClassmethod
),
false
,
"classmethod"
);
sizeof
(
BoxedClassmethod
),
false
,
"classmethod"
);
attrwrapper_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
AttrWrapper
::
gcHandler
,
0
,
0
,
sizeof
(
AttrWrapper
),
false
,
"attrwrapper"
);
attrwrapperiter_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
AttrWrapperIter
::
gcHandler
,
0
,
0
,
attrwrapperiter_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
AttrWrapperIter
::
gcHandler
,
0
,
0
,
sizeof
(
AttrWrapperIter
),
false
,
"attrwrapperiter"
);
sizeof
(
AttrWrapperIter
),
false
,
"attrwrapperiter"
);
...
@@ -1474,12 +1814,12 @@ void setupRuntime() {
...
@@ -1474,12 +1814,12 @@ void setupRuntime() {
object_cls
->
giveAttr
(
"__init__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectInit
,
UNKNOWN
,
1
,
0
,
true
,
false
)));
object_cls
->
giveAttr
(
"__init__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectInit
,
UNKNOWN
,
1
,
0
,
true
,
false
)));
object_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectRepr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectRepr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectStr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectStr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
freeze
();
auto
typeCallObj
=
boxRTFunction
((
void
*
)
typeCall
,
UNKNOWN
,
1
,
0
,
true
,
true
);
auto
typeCallObj
=
boxRTFunction
((
void
*
)
typeCall
,
UNKNOWN
,
1
,
0
,
true
,
true
);
typeCallObj
->
internal_callable
=
&
typeCallInternal
;
typeCallObj
->
internal_callable
=
&
typeCallInternal
;
type_cls
->
giveAttr
(
"__name__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeName
,
typeSetName
,
NULL
));
type_cls
->
giveAttr
(
"__name__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeName
,
typeSetName
,
NULL
));
type_cls
->
giveAttr
(
"__bases__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeBases
,
typeSetBases
,
NULL
));
type_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
typeCallObj
));
type_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
typeCallObj
));
type_cls
->
giveAttr
(
"__new__"
,
type_cls
->
giveAttr
(
"__new__"
,
...
@@ -1506,6 +1846,13 @@ void setupRuntime() {
...
@@ -1506,6 +1846,13 @@ void setupRuntime() {
setupCAPI
();
setupCAPI
();
// Can't set up object methods until we set up CAPI support:
for
(
auto
&
md
:
object_methods
)
{
object_cls
->
giveAttr
(
md
.
ml_name
,
new
BoxedMethodDescriptor
(
&
md
,
object_cls
));
}
object_cls
->
giveAttr
(
"__class__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
objectClass
,
objectSetClass
,
NULL
));
object_cls
->
freeze
();
setupBool
();
setupBool
();
setupInt
();
setupInt
();
setupLong
();
setupLong
();
...
@@ -1525,6 +1872,7 @@ void setupRuntime() {
...
@@ -1525,6 +1872,7 @@ void setupRuntime() {
setupDescr
();
setupDescr
();
setupTraceback
();
setupTraceback
();
function_cls
->
giveAttr
(
"__dict__"
,
dict_descr
);
function_cls
->
giveAttr
(
"__name__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
funcName
,
funcSetName
,
NULL
));
function_cls
->
giveAttr
(
"__name__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
funcName
,
funcSetName
,
NULL
));
function_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
functionRepr
,
STR
,
1
)));
function_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
functionRepr
,
STR
,
1
)));
function_cls
->
giveAttr
(
"__module__"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
function_cls
->
giveAttr
(
"__module__"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
...
@@ -1568,6 +1916,8 @@ void setupRuntime() {
...
@@ -1568,6 +1916,8 @@ void setupRuntime() {
attrwrapper_cls
->
giveAttr
(
"__setitem__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
setitem
,
UNKNOWN
,
3
)));
attrwrapper_cls
->
giveAttr
(
"__setitem__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
setitem
,
UNKNOWN
,
3
)));
attrwrapper_cls
->
giveAttr
(
"__getitem__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
getitem
,
UNKNOWN
,
2
)));
attrwrapper_cls
->
giveAttr
(
"__getitem__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
getitem
,
UNKNOWN
,
2
)));
attrwrapper_cls
->
giveAttr
(
"setdefault"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
setdefault
,
UNKNOWN
,
3
)));
attrwrapper_cls
->
giveAttr
(
attrwrapper_cls
->
giveAttr
(
"get"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
get
,
UNKNOWN
,
3
,
1
,
false
,
false
),
{
None
}));
"get"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
get
,
UNKNOWN
,
3
,
1
,
false
,
false
),
{
None
}));
attrwrapper_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
str
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
str
,
UNKNOWN
,
1
)));
...
...
src/runtime/types.h
View file @
25922a87
...
@@ -630,5 +630,10 @@ Box* makeAttrWrapper(Box* b);
...
@@ -630,5 +630,10 @@ Box* makeAttrWrapper(Box* b);
// Our default for tp_alloc:
// Our default for tp_alloc:
extern
"C"
PyObject
*
PystonType_GenericAlloc
(
BoxedClass
*
cls
,
Py_ssize_t
nitems
)
noexcept
;
extern
"C"
PyObject
*
PystonType_GenericAlloc
(
BoxedClass
*
cls
,
Py_ssize_t
nitems
)
noexcept
;
// A descriptor that you can add to your class to provide instances with a __dict__ accessor.
// Classes created in Python get this automatically, but builtin types (including extension types)
// are supposed to add one themselves. type_cls and function_cls do this, for example.
extern
Box
*
dict_descr
;
}
}
#endif
#endif
test/tests/collections_test.py
View file @
25922a87
...
@@ -5,6 +5,7 @@ print o.items()
...
@@ -5,6 +5,7 @@ print o.items()
for
i
in
xrange
(
30
):
for
i
in
xrange
(
30
):
o
[(
i
**
2
)
^
0xace
]
=
i
o
[(
i
**
2
)
^
0xace
]
=
i
print
o
print
o
print
o
.
copy
()
print
collections
.
deque
().
maxlen
print
collections
.
deque
().
maxlen
...
...
test/tests/dict_setting.py
0 → 100644
View file @
25922a87
# expected: fail
# - we don't support setting __dict__ yet
class
C
(
object
):
pass
c1
=
C
()
c2
=
C
()
c1
.
a
=
2
c1
.
b
=
3
c2
.
a
=
4
c2
.
b
=
5
def
p
():
print
sorted
(
c1
.
__dict__
.
items
()),
sorted
(
c2
.
__dict__
.
items
())
p
()
c1
.
__dict__
=
c2
.
__dict__
p
()
c1
.
a
=
6
c2
.
b
=
7
p
()
test/tests/dir.py
View file @
25922a87
...
@@ -13,7 +13,8 @@ def fake():
...
@@ -13,7 +13,8 @@ def fake():
class
TestClass
(
object
):
class
TestClass
(
object
):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
__dict__
=
{
n
:
n
for
n
in
fake
()}
for
n
in
fake
():
setattr
(
self
,
n
,
n
)
def
__dir__
(
self
):
def
__dir__
(
self
):
return
fake
()
return
fake
()
...
@@ -21,7 +22,8 @@ class TestClass(object):
...
@@ -21,7 +22,8 @@ class TestClass(object):
class
TestClass2
(
object
):
class
TestClass2
(
object
):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
__dict__
=
{
'dictAttr'
:
False
,
'attribute1'
:
None
}
self
.
dictAttr
=
False
self
.
attribute1
=
None
self
.
other_attribute
=
False
self
.
other_attribute
=
False
def
method1
(
self
):
def
method1
(
self
):
...
@@ -63,7 +65,7 @@ test_in_dir(['__str__', '__new__', '__repr__', '__dir__', '__init__',
...
@@ -63,7 +65,7 @@ test_in_dir(['__str__', '__new__', '__repr__', '__dir__', '__init__',
test_in_dir
([
'__str__'
,
'__new__'
,
'__repr__'
,
'__dir__'
,
'__init__'
,
test_in_dir
([
'__str__'
,
'__new__'
,
'__repr__'
,
'__dir__'
,
'__init__'
,
'__module__'
,
'method1'
,
'dictAttr'
,
'attribute1'
],
TestClass2
)
'__module__'
,
'method1'
,
'dictAttr'
,
'attribute1'
],
TestClass2
)
test_in_dir
([
'attribute1'
,
'dictAttr'
,
'__init__'
,
'__module__'
,
'method1'
,
test_in_dir
([
'attribute1'
,
'dictAttr'
,
'__init__'
,
'__module__'
,
'method1'
,
'other_attribute'
,
'__dict__'
],
TestClass2
())
'other_attribute'
],
TestClass2
())
test_in_dir
(
fake
(),
TestClass
())
test_in_dir
(
fake
(),
TestClass
())
print
len
(
fake
())
==
len
(
dir
(
TestClass
()))
print
len
(
fake
())
==
len
(
dir
(
TestClass
()))
...
@@ -91,3 +93,7 @@ for x in d1:
...
@@ -91,3 +93,7 @@ for x in d1:
l
.
append
(
x
)
l
.
append
(
x
)
l
.
sort
()
l
.
sort
()
print
l
print
l
c
=
C1
()
c
.
__dict__
.
update
(
dict
(
a
=
1
,
b
=
5
))
print
sorted
(
c
.
__dict__
.
items
())
test/tests/object_reduce.py
0 → 100644
View file @
25922a87
o
=
object
()
r
=
o
.
__reduce__
()
print
type
(
r
),
len
(
r
)
class
C
(
object
):
def
__repr__
(
self
):
return
"<C>"
c
=
C
()
r
=
c
.
__reduce__
()
print
type
(
r
),
len
(
r
)
assert
len
(
r
)
==
2
c2
=
r
[
0
](
*
r
[
1
])
print
c
,
c2
test/tests/set.py
View file @
25922a87
...
@@ -74,3 +74,8 @@ except KeyError, e:
...
@@ -74,3 +74,8 @@ except KeyError, e:
def
f2
():
def
f2
():
print
{
5
}
print
{
5
}
f2
()
f2
()
s
=
set
([])
s2
=
s
.
copy
()
s
.
add
(
1
)
print
s
,
s2
test/tests/special_getattrs.py
0 → 100644
View file @
25922a87
def
show
(
obj
):
print
obj
.
__class__
for
b
in
obj
.
__class__
.
__mro__
:
print
b
,
print
if
isinstance
(
obj
,
type
):
print
obj
.
__bases__
,
obj
.
__mro__
if
hasattr
(
obj
,
"__dict__"
):
print
sorted
(
obj
.
__dict__
.
items
())
show
(
object
())
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