Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
PyPy
pypy
Commits
4748c02be810
Commit
d6e3f63f
authored
Oct 31, 2019
by
Armin Rigo
Browse files
Add _PySet_Next{,Entry}. Based on the _PySet_NextEntry branch but for pypy2
parent
28382af84334
Changes
7
Hide whitespace changes
Inline
Side-by-side
pypy/module/cpyext/dictobject.py
View file @
4748c02b
...
...
@@ -267,14 +267,15 @@ def PyDict_Next(space, w_dict, ppos, pkey, pvalue):
if
pos
==
0
:
# Store the current keys in the PyDictObject.
from
pypy.objspace.std.listobject
import
W_ListObject
decref
(
space
,
py_dict
.
c__tmpkeys
)
w_keys
=
space
.
call_method
(
space
.
w_dict
,
"keys"
,
w_dict
)
# w_keys must use the object strategy in order to keep the keys alive
if
not
isinstance
(
w_keys
,
W_ListObject
):
return
0
# XXX should not call keys() above
w_keys
.
switch_to_object_strategy
()
oldkeys
=
py_dict
.
c__tmpkeys
py_dict
.
c__tmpkeys
=
create_ref
(
space
,
w_keys
)
incref
(
space
,
py_dict
.
c__tmpkeys
)
decref
(
space
,
oldkeys
)
else
:
if
not
py_dict
.
c__tmpkeys
:
# pos should have been 0, cannot fail so return 0
...
...
pypy/module/cpyext/include/Python.h
View file @
4748c02b
...
...
@@ -107,6 +107,7 @@
#include "descrobject.h"
#include "tupleobject.h"
#include "dictobject.h"
#include "setobject.h"
#include "intobject.h"
#include "listobject.h"
#include "longobject.h"
...
...
pypy/module/cpyext/include/setobject.h
0 → 100644
View file @
4748c02b
/* set object interface */
#ifndef Py_SETOBJECT_H
#define Py_SETOBJECT_H
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
{
PyObject_HEAD
PyObject
*
_tmplist
;
/* a private place to put values during _PySet_Next */
}
PySetObject
;
#ifdef __cplusplus
}
#endif
#endif
/* !Py_SETOBJECT_H */
pypy/module/cpyext/object.py
View file @
4748c02b
...
...
@@ -359,11 +359,11 @@ def PyObject_Hash(space, w_obj):
"""
Compute and return the hash value of an object o. On failure, return -1.
This is the equivalent of the Python expression hash(o)."""
return
space
.
int_w
(
space
.
hash
(
w_obj
)
)
return
space
.
hash
_w
(
w_obj
)
@
cpython_api
([
rffi
.
DOUBLE
],
rffi
.
LONG
,
error
=-
1
)
def
_Py_HashDouble
(
space
,
v
):
return
space
.
int_w
(
space
.
hash
(
space
.
newfloat
(
v
))
)
return
space
.
hash
_w
(
space
.
newfloat
(
v
))
@
cpython_api
([
PyObject
],
lltype
.
Signed
,
error
=-
1
)
def
PyObject_HashNotImplemented
(
space
,
o
):
...
...
pypy/module/cpyext/setobject.py
View file @
4748c02b
from
pypy.interpreter.error
import
OperationError
,
oefmt
from
rpython.rtyper.lltypesystem
import
rffi
,
lltype
from
pypy.module.cpyext.api
import
(
cpython_api
,
Py_ssize_t
,
CANNOT_FAIL
,
build_type_checkers
)
from
pypy.module.cpyext.api
import
(
cpython_api
,
Py_ssize_t
,
Py_ssize_tP
,
CANNOT_FAIL
,
build_type_checkers
,
PyObjectFields
,
cpython_struct
,
bootstrap_function
,
slot_function
)
from
pypy.module.cpyext.pyobject
import
(
PyObject
,
PyObjectP
,
make_ref
,
from_ref
)
make_ref
,
from_ref
,
as_pyobj
,
create_ref
,
make_typedescr
,
incref
,
decref
)
from
pypy.module.cpyext.object
import
_dealloc
from
pypy.module.cpyext.pyerrors
import
PyErr_BadInternalCall
from
pypy.objspace.std.setobject
import
W_SetObject
,
W_FrozensetObject
,
newset
PySetObjectStruct
=
lltype
.
ForwardReference
()
PySetObject
=
lltype
.
Ptr
(
PySetObjectStruct
)
PySetObjectFields
=
PyObjectFields
+
\
((
"_tmplist"
,
PyObject
),)
cpython_struct
(
"PySetObject"
,
PySetObjectFields
,
PySetObjectStruct
)
@
bootstrap_function
def
init_setobject
(
space
):
"Type description of PySetObject"
make_typedescr
(
space
.
w_set
.
layout
.
typedef
,
basestruct
=
PySetObject
.
TO
,
attach
=
set_attach
,
dealloc
=
set_dealloc
)
make_typedescr
(
space
.
w_frozenset
.
layout
.
typedef
,
# same as 'set'
basestruct
=
PySetObject
.
TO
,
attach
=
set_attach
,
dealloc
=
set_dealloc
)
def
set_attach
(
space
,
py_obj
,
w_obj
,
w_userdata
=
None
):
"""
Fills a newly allocated PySetObject with the given set object.
"""
py_set
=
rffi
.
cast
(
PySetObject
,
py_obj
)
py_set
.
c__tmplist
=
lltype
.
nullptr
(
PyObject
.
TO
)
@
slot_function
([
PyObject
],
lltype
.
Void
)
def
set_dealloc
(
space
,
py_obj
):
py_set
=
rffi
.
cast
(
PySetObject
,
py_obj
)
decref
(
space
,
py_set
.
c__tmplist
)
py_set
.
c__tmplist
=
lltype
.
nullptr
(
PyObject
.
TO
)
_dealloc
(
space
,
py_obj
)
PySet_Check
,
PySet_CheckExact
=
build_type_checkers
(
"Set"
)
PyFrozenSet_Check
,
PyFrozenSet_CheckExact
=
build_type_checkers
(
"FrozenSet"
)
...
...
@@ -23,7 +56,7 @@ def PyAnySet_CheckExact(space, w_obj):
"""Return true if obj is a set object or a frozenset object but
not an instance of a subtype."""
w_obj_type
=
space
.
type
(
w_obj
)
return
(
space
.
is_w
(
w_obj_type
,
space
.
gettypefor
(
W_SetObject
))
or
return
(
space
.
is_w
(
w_obj_type
,
space
.
gettypefor
(
W_SetObject
))
or
space
.
is_w
(
w_obj_type
,
space
.
gettypefor
(
W_FrozensetObject
)))
@
cpython_api
([
PyObject
],
PyObject
)
...
...
@@ -126,4 +159,43 @@ def PyFrozenSet_New(space, w_iterable):
else
:
return
space
.
call_function
(
space
.
w_frozenset
,
w_iterable
)
@
cpython_api
([
PyObject
,
Py_ssize_tP
,
PyObjectP
,
Py_ssize_tP
],
rffi
.
INT_real
,
error
=-
1
)
def
_PySet_NextEntry
(
space
,
w_set
,
ppos
,
pkey
,
phash
):
if
w_set
is
None
or
not
PyAnySet_Check
(
space
,
w_set
):
PyErr_BadInternalCall
(
space
)
return
-
1
if
not
pkey
:
PyErr_BadInternalCall
(
space
)
return
-
1
pos
=
ppos
[
0
]
py_obj
=
as_pyobj
(
space
,
w_set
)
py_set
=
rffi
.
cast
(
PySetObject
,
py_obj
)
if
pos
==
0
:
# Store the current item list in the PySetObject.
# w_keys must use the object strategy in order to keep the keys alive
w_keys
=
space
.
newlist
(
space
.
listview
(
w_set
))
w_keys
.
switch_to_object_strategy
()
oldlist
=
py_set
.
c__tmplist
py_set
.
c__tmplist
=
create_ref
(
space
,
w_keys
)
incref
(
space
,
py_set
.
c__tmplist
)
decref
(
space
,
oldlist
)
else
:
if
not
py_set
.
c__tmplist
:
# pos should have been 0, cannot fail so return 0
return
0
;
w_keys
=
from_ref
(
space
,
py_set
.
c__tmplist
)
ppos
[
0
]
+=
1
if
pos
>=
space
.
len_w
(
w_keys
):
decref
(
space
,
py_set
.
c__tmplist
)
py_set
.
c__tmplist
=
lltype
.
nullptr
(
PyObject
.
TO
)
return
0
w_key
=
space
.
listview
(
w_keys
)[
pos
]
pkey
[
0
]
=
as_pyobj
(
space
,
w_key
)
if
phash
:
phash
[
0
]
=
space
.
hash_w
(
w_key
)
return
1
@
cpython_api
([
PyObject
,
Py_ssize_tP
,
PyObjectP
],
rffi
.
INT_real
,
error
=-
1
)
def
_PySet_Next
(
space
,
w_set
,
ppos
,
pkey
):
null
=
lltype
.
nullptr
(
Py_ssize_tP
.
TO
)
return
_PySet_NextEntry
(
space
,
w_set
,
ppos
,
pkey
,
null
)
pypy/module/cpyext/test/test_setobject.py
View file @
4748c02b
from
rpython.rtyper.lltypesystem
import
lltype
from
pypy.module.cpyext.test.test_api
import
BaseApiTest
,
raises_w
from
pypy.module.cpyext.test.test_cpyext
import
AppTestCpythonExtensionBase
from
pypy.module.cpyext.setobject
import
(
PySet_Check
,
PyFrozenSet_Check
,
PyFrozenSet_CheckExact
,
PySet_Add
,
PySet_Size
,
PySet_GET_SIZE
)
from
pypy.module.cpyext.api
import
Py_ssize_tP
,
PyObjectP
from
pypy.module.cpyext.pyobject
import
from_ref
class
TestTupleObject
(
BaseApiTest
):
...
...
@@ -62,6 +65,42 @@ class TestTupleObject(BaseApiTest):
"""
)
assert
api
.
PyAnySet_Check
(
w_instance
)
def
test_pyset_next
(
self
,
space
,
api
):
w_set
=
space
.
call_function
(
space
.
w_set
,
space
.
newtext
(
"ab"
))
with
lltype
.
scoped_alloc
(
Py_ssize_tP
.
TO
,
1
)
as
pos_p
:
with
lltype
.
scoped_alloc
(
PyObjectP
.
TO
,
1
)
as
result_p
:
pos_p
[
0
]
=
0
res
=
api
.
_PySet_Next
(
w_set
,
pos_p
,
result_p
)
assert
res
==
1
letter1
=
space
.
text_w
(
from_ref
(
space
,
result_p
[
0
]))
res
=
api
.
_PySet_Next
(
w_set
,
pos_p
,
result_p
)
assert
res
==
1
letter2
=
space
.
text_w
(
from_ref
(
space
,
result_p
[
0
]))
res
=
api
.
_PySet_Next
(
w_set
,
pos_p
,
result_p
)
assert
res
==
0
assert
set
([
letter1
,
letter2
])
==
set
(
"ab"
)
def
test_pyset_nextentry
(
self
,
space
,
api
):
w_set
=
space
.
call_function
(
space
.
w_set
,
space
.
newtext
(
"ab"
))
with
lltype
.
scoped_alloc
(
Py_ssize_tP
.
TO
,
1
)
as
pos_p
:
with
lltype
.
scoped_alloc
(
PyObjectP
.
TO
,
1
)
as
result_p
:
with
lltype
.
scoped_alloc
(
Py_ssize_tP
.
TO
,
1
)
as
hash_p
:
pos_p
[
0
]
=
0
res
=
api
.
_PySet_NextEntry
(
w_set
,
pos_p
,
result_p
,
hash_p
)
assert
res
==
1
w_obj
=
from_ref
(
space
,
result_p
[
0
])
letter1
=
space
.
text_w
(
w_obj
)
assert
hash_p
[
0
]
==
space
.
hash_w
(
w_obj
)
res
=
api
.
_PySet_NextEntry
(
w_set
,
pos_p
,
result_p
,
hash_p
)
assert
res
==
1
w_obj
=
from_ref
(
space
,
result_p
[
0
])
letter2
=
space
.
text_w
(
w_obj
)
assert
hash_p
[
0
]
==
space
.
hash_w
(
w_obj
)
res
=
api
.
_PySet_NextEntry
(
w_set
,
pos_p
,
result_p
,
hash_p
)
assert
res
==
0
assert
set
([
letter1
,
letter2
])
==
set
(
"ab"
)
class
AppTestSetObject
(
AppTestCpythonExtensionBase
):
def
test_set_macro_cast
(
self
):
module
=
self
.
import_extension
(
'foo'
,
[
...
...
pypy/module/cpyext/userslot.py
View file @
4748c02b
...
...
@@ -22,7 +22,7 @@ def slot_sq_length(space, w_obj):
@
slot_function
([
PyObject
],
lltype
.
Signed
,
error
=-
1
)
def
slot_tp_hash
(
space
,
w_obj
):
return
space
.
int_w
(
space
.
hash
(
w_obj
)
)
return
space
.
hash
_w
(
w_obj
)
@
slot_function
([
PyObject
,
Py_ssize_t
],
PyObject
)
def
slot_sq_item
(
space
,
w_obj
,
index
):
...
...
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