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
f677127a
Commit
f677127a
authored
May 26, 2015
by
Marius Wachtler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add dictproxy and use it for type.__dict__
parent
e95f4bef
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
306 additions
and
16 deletions
+306
-16
Makefile
Makefile
+1
-0
from_cpython/CMakeLists.txt
from_cpython/CMakeLists.txt
+1
-0
from_cpython/Include/descrobject.h
from_cpython/Include/descrobject.h
+2
-0
from_cpython/Objects/dictproxy.c
from_cpython/Objects/dictproxy.c
+244
-0
src/runtime/dict.cpp
src/runtime/dict.cpp
+10
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+2
-2
src/runtime/types.cpp
src/runtime/types.cpp
+26
-3
test/tests/data_descriptors.py
test/tests/data_descriptors.py
+9
-10
test/tests/dict_setting.py
test/tests/dict_setting.py
+11
-0
No files found.
Makefile
View file @
f677127a
...
...
@@ -390,6 +390,7 @@ STDOBJECT_SRCS := \
iterobject.c
\
bufferobject.c
\
cobject.c
\
dictproxy.c
\
$(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS
:=
\
...
...
from_cpython/CMakeLists.txt
View file @
f677127a
...
...
@@ -78,6 +78,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
bytes_methods.c
capsule.c
cobject.c
dictproxy.c
exceptions.c
floatobject.c
iterobject.c
...
...
from_cpython/Include/descrobject.h
View file @
f677127a
...
...
@@ -80,6 +80,8 @@ PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type;
PyAPI_DATA(PyTypeObject) PyDictProxy_Type;
PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type;
PyAPI_DATA(PyTypeObject) PyMemberDescr_Type;
#else
PyAPI_DATA
(
PyTypeObject
)
PyDictProxy_Type
;
#endif
// (Pyston TODO: add #defines to our names)
PyAPI_DATA
(
PyTypeObject
*
)
wrapperdescr_cls
;
...
...
from_cpython/Objects/dictproxy.c
0 → 100644
View file @
f677127a
// This file is originally from CPython 2.7, with modifications for Pyston
// The code is normally part of descrobject.c
#include "Python.h"
/* --- Readonly proxy for dictionaries (actually any mapping) --- */
/* This has no reason to be in this file except that adding new files is a
bit of a pain */
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
}
proxyobject
;
static
Py_ssize_t
proxy_len
(
proxyobject
*
pp
)
{
return
PyObject_Size
(
pp
->
dict
);
}
static
PyObject
*
proxy_getitem
(
proxyobject
*
pp
,
PyObject
*
key
)
{
return
PyObject_GetItem
(
pp
->
dict
,
key
);
}
static
PyMappingMethods
proxy_as_mapping
=
{
(
lenfunc
)
proxy_len
,
/* mp_length */
(
binaryfunc
)
proxy_getitem
,
/* mp_subscript */
0
,
/* mp_ass_subscript */
};
static
int
proxy_contains
(
proxyobject
*
pp
,
PyObject
*
key
)
{
return
PyDict_Contains
(
pp
->
dict
,
key
);
}
static
PySequenceMethods
proxy_as_sequence
=
{
0
,
/* sq_length */
0
,
/* sq_concat */
0
,
/* sq_repeat */
0
,
/* sq_item */
0
,
/* sq_slice */
0
,
/* sq_ass_item */
0
,
/* sq_ass_slice */
(
objobjproc
)
proxy_contains
,
/* sq_contains */
0
,
/* sq_inplace_concat */
0
,
/* sq_inplace_repeat */
};
static
PyObject
*
proxy_has_key
(
proxyobject
*
pp
,
PyObject
*
key
)
{
int
res
=
PyDict_Contains
(
pp
->
dict
,
key
);
if
(
res
<
0
)
return
NULL
;
return
PyBool_FromLong
(
res
);
}
static
PyObject
*
proxy_get
(
proxyobject
*
pp
,
PyObject
*
args
)
{
PyObject
*
key
,
*
def
=
Py_None
;
if
(
!
PyArg_UnpackTuple
(
args
,
"get"
,
1
,
2
,
&
key
,
&
def
))
return
NULL
;
return
PyObject_CallMethod
(
pp
->
dict
,
"get"
,
"(OO)"
,
key
,
def
);
}
static
PyObject
*
proxy_keys
(
proxyobject
*
pp
)
{
return
PyMapping_Keys
(
pp
->
dict
);
}
static
PyObject
*
proxy_values
(
proxyobject
*
pp
)
{
return
PyMapping_Values
(
pp
->
dict
);
}
static
PyObject
*
proxy_items
(
proxyobject
*
pp
)
{
return
PyMapping_Items
(
pp
->
dict
);
}
static
PyObject
*
proxy_iterkeys
(
proxyobject
*
pp
)
{
return
PyObject_CallMethod
(
pp
->
dict
,
"iterkeys"
,
NULL
);
}
static
PyObject
*
proxy_itervalues
(
proxyobject
*
pp
)
{
return
PyObject_CallMethod
(
pp
->
dict
,
"itervalues"
,
NULL
);
}
static
PyObject
*
proxy_iteritems
(
proxyobject
*
pp
)
{
return
PyObject_CallMethod
(
pp
->
dict
,
"iteritems"
,
NULL
);
}
static
PyObject
*
proxy_copy
(
proxyobject
*
pp
)
{
return
PyObject_CallMethod
(
pp
->
dict
,
"copy"
,
NULL
);
}
static
PyMethodDef
proxy_methods
[]
=
{
{
"has_key"
,
(
PyCFunction
)
proxy_has_key
,
METH_O
,
PyDoc_STR
(
"D.has_key(k) -> True if D has a key k, else False"
)},
{
"get"
,
(
PyCFunction
)
proxy_get
,
METH_VARARGS
,
PyDoc_STR
(
"D.get(k[,d]) -> D[k] if D.has_key(k), else d."
" d defaults to None."
)},
{
"keys"
,
(
PyCFunction
)
proxy_keys
,
METH_NOARGS
,
PyDoc_STR
(
"D.keys() -> list of D's keys"
)},
{
"values"
,
(
PyCFunction
)
proxy_values
,
METH_NOARGS
,
PyDoc_STR
(
"D.values() -> list of D's values"
)},
{
"items"
,
(
PyCFunction
)
proxy_items
,
METH_NOARGS
,
PyDoc_STR
(
"D.items() -> list of D's (key, value) pairs, as 2-tuples"
)},
{
"iterkeys"
,
(
PyCFunction
)
proxy_iterkeys
,
METH_NOARGS
,
PyDoc_STR
(
"D.iterkeys() -> an iterator over the keys of D"
)},
{
"itervalues"
,(
PyCFunction
)
proxy_itervalues
,
METH_NOARGS
,
PyDoc_STR
(
"D.itervalues() -> an iterator over the values of D"
)},
{
"iteritems"
,
(
PyCFunction
)
proxy_iteritems
,
METH_NOARGS
,
PyDoc_STR
(
"D.iteritems() ->"
" an iterator over the (key, value) items of D"
)},
{
"copy"
,
(
PyCFunction
)
proxy_copy
,
METH_NOARGS
,
PyDoc_STR
(
"D.copy() -> a shallow copy of D"
)},
{
0
}
};
static
void
proxy_dealloc
(
proxyobject
*
pp
)
{
_PyObject_GC_UNTRACK
(
pp
);
Py_DECREF
(
pp
->
dict
);
PyObject_GC_Del
(
pp
);
}
static
PyObject
*
proxy_getiter
(
proxyobject
*
pp
)
{
return
PyObject_GetIter
(
pp
->
dict
);
}
static
PyObject
*
proxy_str
(
proxyobject
*
pp
)
{
return
PyObject_Str
(
pp
->
dict
);
}
static
PyObject
*
proxy_repr
(
proxyobject
*
pp
)
{
PyObject
*
dictrepr
;
PyObject
*
result
;
dictrepr
=
PyObject_Repr
(
pp
->
dict
);
if
(
dictrepr
==
NULL
)
return
NULL
;
result
=
PyString_FromFormat
(
"dict_proxy(%s)"
,
PyString_AS_STRING
(
dictrepr
));
Py_DECREF
(
dictrepr
);
return
result
;
}
static
int
proxy_traverse
(
PyObject
*
self
,
visitproc
visit
,
void
*
arg
)
{
proxyobject
*
pp
=
(
proxyobject
*
)
self
;
Py_VISIT
(
pp
->
dict
);
return
0
;
}
static
int
proxy_compare
(
proxyobject
*
v
,
PyObject
*
w
)
{
return
PyObject_Compare
(
v
->
dict
,
w
);
}
static
PyObject
*
proxy_richcompare
(
proxyobject
*
v
,
PyObject
*
w
,
int
op
)
{
return
PyObject_RichCompare
(
v
->
dict
,
w
,
op
);
}
PyTypeObject
PyDictProxy_Type
=
{
// Pyston change:
// PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"dictproxy"
,
/* tp_name */
sizeof
(
proxyobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
proxy_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
(
cmpfunc
)
proxy_compare
,
/* tp_compare */
(
reprfunc
)
proxy_repr
,
/* tp_repr */
0
,
/* tp_as_number */
&
proxy_as_sequence
,
/* tp_as_sequence */
&
proxy_as_mapping
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_call */
(
reprfunc
)
proxy_str
,
/* tp_str */
PyObject_GenericGetAttr
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
,
/* tp_flags */
0
,
/* tp_doc */
proxy_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
(
richcmpfunc
)
proxy_richcompare
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
(
getiterfunc
)
proxy_getiter
,
/* tp_iter */
0
,
/* tp_iternext */
proxy_methods
,
/* tp_methods */
0
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_dict */
0
,
/* tp_descr_get */
0
,
/* tp_descr_set */
};
PyObject
*
PyDictProxy_New
(
PyObject
*
dict
)
{
proxyobject
*
pp
;
pp
=
PyObject_GC_New
(
proxyobject
,
&
PyDictProxy_Type
);
if
(
pp
!=
NULL
)
{
Py_INCREF
(
dict
);
pp
->
dict
=
dict
;
_PyObject_GC_TRACK
(
pp
);
}
return
(
PyObject
*
)
pp
;
}
src/runtime/dict.cpp
View file @
f677127a
...
...
@@ -439,8 +439,17 @@ Box* dictContains(BoxedDict* self, Box* k) {
/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
extern
"C"
int
PyDict_Contains
(
PyObject
*
op
,
PyObject
*
key
)
noexcept
{
BoxedDict
*
mp
=
(
BoxedDict
*
)
op
;
try
{
if
(
op
->
cls
==
attrwrapper_cls
)
{
Box
*
rtn
=
PyObject_CallMethod
(
op
,
"__contains__"
,
"O"
,
key
);
if
(
!
rtn
)
return
-
1
;
return
rtn
==
True
;
}
BoxedDict
*
mp
=
(
BoxedDict
*
)
op
;
assert
(
isSubclass
(
mp
->
cls
,
dict_cls
));
return
mp
->
getOrNull
(
key
)
?
1
:
0
;
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
...
...
src/runtime/objmodel.cpp
View file @
f677127a
...
...
@@ -4391,8 +4391,8 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
base_heap_cls
->
nslots
()
*
sizeof
(
BoxedHeapClass
::
SlotOffset
));
}
if
(
!
made
->
getattr
(
"__dict__"
)
&&
(
made
->
instancesHaveHCAttrs
()
||
made
->
instancesHaveDictAttrs
()
))
made
->
giveAttr
(
"__dict__"
,
dict_descr
);
if
(
made
->
instancesHaveHCAttrs
()
||
made
->
instancesHaveDictAttrs
(
))
made
->
setattr
(
"__dict__"
,
dict_descr
,
NULL
);
for
(
const
auto
&
p
:
attr_dict
->
d
)
{
auto
k
=
coerceUnicodeToStr
(
p
.
first
);
...
...
src/runtime/types.cpp
View file @
f677127a
...
...
@@ -495,6 +495,12 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) {
}
static
Box
*
typeDict
(
Box
*
obj
,
void
*
context
)
{
if
(
obj
->
cls
->
instancesHaveHCAttrs
())
return
PyDictProxy_New
(
obj
->
getAttrWrapper
());
abort
();
}
static
Box
*
typeSubDict
(
Box
*
obj
,
void
*
context
)
{
if
(
obj
->
cls
->
instancesHaveHCAttrs
())
return
obj
->
getAttrWrapper
();
if
(
obj
->
cls
->
instancesHaveDictAttrs
())
...
...
@@ -502,7 +508,7 @@ static Box* typeDict(Box* obj, void* context) {
abort
();
}
static
void
typeSetDict
(
Box
*
obj
,
Box
*
val
,
void
*
context
)
{
static
void
typeS
ubS
etDict
(
Box
*
obj
,
Box
*
val
,
void
*
context
)
{
if
(
obj
->
cls
->
instancesHaveDictAttrs
())
{
RELEASE_ASSERT
(
val
->
cls
==
dict_cls
,
""
);
obj
->
setDict
(
static_cast
<
BoxedDict
*>
(
val
));
...
...
@@ -1635,6 +1641,20 @@ public:
return
new
AttrWrapperIter
(
self
);
}
static
Box
*
eq
(
Box
*
_self
,
Box
*
_other
)
{
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
// In order to not have to reimplement dict cmp: just create a real dict for now and us it.
BoxedDict
*
dict
=
(
BoxedDict
*
)
AttrWrapper
::
copy
(
_self
);
assert
(
dict
->
cls
==
dict_cls
);
const
std
::
string
eq_str
=
"__eq__"
;
return
callattrInternal
(
dict
,
&
eq_str
,
LookupScope
::
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
1
),
_other
,
NULL
,
NULL
,
NULL
,
NULL
);
}
static
Box
*
ne
(
Box
*
_self
,
Box
*
_other
)
{
return
eq
(
_self
,
_other
)
==
True
?
False
:
True
;
}
friend
class
AttrWrapperIter
;
};
...
...
@@ -2437,9 +2457,9 @@ void setupRuntime() {
str_cls
->
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
dict_descr
=
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
type
Dict
,
type
SetDict
,
NULL
);
dict_descr
=
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
type
SubDict
,
typeSub
SetDict
,
NULL
);
gc
::
registerPermanentRoot
(
dict_descr
);
type_cls
->
giveAttr
(
"__dict__"
,
dict_descr
);
type_cls
->
giveAttr
(
"__dict__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeDict
,
NULL
,
NULL
)
);
instancemethod_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
instancemethodGCHandler
,
0
,
...
...
@@ -2619,6 +2639,8 @@ void setupRuntime() {
attrwrapper_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
str
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"__contains__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
contains
,
UNKNOWN
,
2
)));
attrwrapper_cls
->
giveAttr
(
"__eq__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
eq
,
UNKNOWN
,
2
)));
attrwrapper_cls
->
giveAttr
(
"__ne__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
ne
,
UNKNOWN
,
2
)));
attrwrapper_cls
->
giveAttr
(
"keys"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
keys
,
LIST
,
1
)));
attrwrapper_cls
->
giveAttr
(
"values"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
values
,
LIST
,
1
)));
attrwrapper_cls
->
giveAttr
(
"items"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
items
,
LIST
,
1
)));
...
...
@@ -2652,6 +2674,7 @@ void setupRuntime() {
PyCallIter_AddHasNext
();
PyType_Ready
(
&
PyCallIter_Type
);
PyType_Ready
(
&
PyCObject_Type
);
PyType_Ready
(
&
PyDictProxy_Type
);
initerrno
();
init_sha
();
...
...
test/tests/data_descriptors.py
View file @
f677127a
...
...
@@ -31,9 +31,8 @@ print 'C.dd is %s' % str(C.dd)
print
'C.ndd is %s'
%
str
(
C
.
ndd
)
C
.
dd
=
6
C
.
ndd
=
7
#TODO it would be nice to print these out (once __dict__ is implemented)
#print C.__dict__['dd']
#print C.__dict__['ndd']
print
C
.
__dict__
[
'dd'
]
print
C
.
__dict__
[
'ndd'
]
print
C
.
dd
print
C
.
ndd
...
...
@@ -62,8 +61,8 @@ print 'D.dd is %s' % str(D.dd)
print
'D.ndd is %s'
%
str
(
D
.
ndd
)
D
.
dd
=
6
D
.
ndd
=
7
#
print D.__dict__['dd']
#
print D.__dict__['ndd']
print
D
.
__dict__
[
'dd'
]
print
D
.
__dict__
[
'ndd'
]
class
DataDescriptor
(
object
):
def
__get__
(
self
,
obj
,
type
):
return
1
...
...
@@ -82,7 +81,7 @@ print d1.a
print
'D1.a is %s'
%
str
(
D1
.
a
)
D1
.
a
=
6
#
print D1.__dict__['a']
print
D1
.
__dict__
[
'a'
]
class
C2
(
object
):
a
=
4
...
...
@@ -93,7 +92,7 @@ print d2.a
print
'D2.a is %s'
%
str
(
D2
.
a
)
D2
.
a
=
6
#
print D2.__dict__['a']
print
D2
.
__dict__
[
'a'
]
class
C3
(
object
):
a
=
NonDataDescriptor
()
...
...
@@ -104,15 +103,15 @@ print d3.a
print
'D3.a is %s'
%
str
(
D3
.
a
)
D3
.
a
=
6
#
print D3.__dict__['a']
print
D3
.
__dict__
[
'a'
]
class
C4
(
object
):
a
=
6
class
D4
(
C4
):
a
=
NonDataDescriptor
()
d4
=
D4
()
#
print d4.a
print
d4
.
a
print
'D4.a is %s'
%
str
(
D4
.
a
)
D4
.
a
=
6
#
print D4.__dict__['a']
print
D4
.
__dict__
[
'a'
]
test/tests/dict_setting.py
View file @
f677127a
...
...
@@ -49,3 +49,14 @@ d1.clear()
print
hasattr
(
c
,
"attr"
)
print
hasattr
(
c
,
"foo"
)
print
c
.
__dict__
is
d1
dictproxy
=
C
.
__dict__
print
type
(
dictproxy
)
print
"foo"
in
dictproxy
print
"foo"
in
dictproxy
.
keys
()
print
type
(
dictproxy
[
"foo"
])
print
dictproxy
==
dict
(
C
.
__dict__
)
try
:
dictproxy
[
"test"
]
=
"val"
except
Exception
as
e
:
print
e
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