Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Kirill Smelkov
cpython
Commits
beb3101b
Commit
beb3101b
authored
Aug 16, 2005
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a C API for sets and frozensets.
parent
e2eca0b7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
210 additions
and
12 deletions
+210
-12
Doc/api/concrete.tex
Doc/api/concrete.tex
+125
-0
Include/setobject.h
Include/setobject.h
+9
-0
Misc/NEWS
Misc/NEWS
+2
-0
Objects/setobject.c
Objects/setobject.c
+72
-8
Python/marshal.c
Python/marshal.c
+2
-4
No files found.
Doc/api/concrete.tex
View file @
beb3101b
...
...
@@ -2897,3 +2897,128 @@ Macros for the convenience of modules implementing the DB API:
tuple suitable for passing to
\code
{
datetime.date.fromtimestamp()
}
.
\versionadded
{
2.4
}
\end{cfuncdesc}
\subsection
{
Set Objects
\label
{
setObjects
}}
\sectionauthor
{
Raymond D. Hettinger
}{
python@rcn.com
}
\obindex
{
set
}
\obindex
{
frozenset
}
\versionadded
{
2.5
}
This section details the public API for
\class
{
set
}
and
\class
{
frozenset
}
objects. Any functionality not listed below is best accessed using the
abstract object API (including
\cfunction
{
PyObject
_
CallMethod()
}
,
\cfunction
{
PyObject
_
RichCompareBool()
}
,
\cfunction
{
PyObject
_
Hash()
}
,
\cfunction
{
PyObject
_
Repr()
}
,
\cfunction
{
PyObject
_
IsTrue()
}
,
\cfunction
{
PyObject
_
Print()
}
, and
\cfunction
{
PyObject
_
GetIter()
}
).
\begin{ctypedesc}
{
PySetObject
}
This subtype of
\ctype
{
PyObject
}
is used to hold the internal data for
both
\class
{
set
}
and
\class
{
frozenset
}
objects. It is like a
\ctype
{
PyDictObject
}
in that it is a fixed size for small sets
(much like tuple storage) and will point to a separate, variable sized
block of memory for medium and large sized sets (much like list storage).
None of the fields of this structure should be considered public and
are subject to change. All access should be done through the
documented API.
\end{ctypedesc}
\begin{cvardesc}
{
PyTypeObject
}{
PySet
_
Type
}
This is an instance of
\ctype
{
PyTypeObject
}
representing the Python
\class
{
set
}
type.
\end{cvardesc}
\begin{cvardesc}
{
PyTypeObject
}{
PyFrozenSet
_
Type
}
This is an instance of
\ctype
{
PyTypeObject
}
representing the Python
\class
{
frozenset
}
type.
\end{cvardesc}
The following type check macros work on pointers to any Python object.
Likewise, the constructor functions work with any iterable Python object.
\begin{cfuncdesc}
{
int
}{
PyAnySet
_
Check
}{
PyObject *p
}
Returns true if
\var
{
p
}
is a
\class
{
set
}
object, a
\class
{
frozenset
}
object, or an instance of a subtype.
\end{cfuncdesc}
\begin{cfuncdesc}
{
int
}{
PyAnySet
_
CheckExact
}{
PyObject *p
}
Returns true if
\var
{
p
}
is a
\class
{
set
}
object or a
\class
{
frozenset
}
object but not an instance of a subtype.
\end{cfuncdesc}
\begin{cfuncdesc}
{
int
}{
PyFrozenSet
_
CheckExact
}{
PyObject *p
}
Returns true if
\var
{
p
}
is a
\class
{
frozenset
}
object
but not an instance of a subtype.
\end{cfuncdesc}
\begin{cfuncdesc}
{
PyObject*
}{
PySet
_
New
}{
PyObject *iterable
}
Returns a new
\class
{
set
}
containing objects returned by the
\var
{
iterable
}
. The
\var
{
iterable
}
may be
\NULL
{}
to create a
new empty set. Returns the new set on success or
\NULL
{}
on
failure.
\end{cfuncdesc}
\begin{cfuncdesc}
{
PyObject*
}{
PyFrozenSet
_
New
}{
PyObject *iterable
}
Returns a new
\class
{
frozenset
}
containing objects returned by the
\var
{
iterable
}
. The
\var
{
iterable
}
may be
\NULL
{}
to create a
new empty frozenset. Returns the new set on success or
\NULL
{}
on
failure.
\end{cfuncdesc}
The following functions and macros are available for instances of
\class
{
set
}
or
\class
{
frozenset
}
or instances of their subtypes.
\begin{cfuncdesc}
{
int
}{
PySet
_
Size
}{
PyObject *anyset
}
Returns the length of a
\class
{
set
}
or
\class
{
frozenset
}
object.
Equivalent to
\samp
{
len(
\var
{
anyset
}
)
}
. Raises a
\exception
{
PyExc
_
SystemError
}
if the argument is not a
\class
{
set
}
,
\class
{
frozenset
}
, or an instance of a subtype.
\bifuncindex
{
len
}
\end{cfuncdesc}
\begin{cfuncdesc}
{
int
}{
PySet
_
GET
_
SIZE
}{
PyObject *anyset
}
Macro form of
\cfunction
{
PySet
_
Size()
}
without error checking.
\end{cfuncdesc}
\begin{cfuncdesc}
{
int
}{
PySet
_
Contains
}{
PyObject *anyset, PyObject *key
}
Returns 1 if found, 0 if not found, and -1 if an error is
encountered. Unlike the Python
\method
{__
contains
__
()
}
method, this
function does not automatically convert unhashable sets into temporary
frozensets. Raises a
\exception
{
TypeError
}
if the key is unhashable.
\end{cfuncdesc}
\begin{cfuncdesc}
{
int
}{
PySet
_
Discard
}{
PyObject *anyset, PyObject *key
}
Returns 1 if found and removed, 0 if not found (no action taken),
and -1 if an error is encountered. Does not raise
\exception
{
KeyError
}
for missing keys. Raises a
\exception
{
TypeError
}
if the key is unhashable.
Unlike the Python
\method
{
discard()
}
method, this function does
not automatically convert unhashable sets into temporary frozensets.
\end{cfuncdesc}
The following functions are available for instances of
\class
{
set
}
or
its subtypes but not for instances of
\class
{
frozenset
}
or its subtypes.
\begin{cfuncdesc}
{
int
}{
PySet
_
Add
}{
PyObject *set, PyObject *key
}
Adds
\var
{
key
}
to a
\class
{
set
}
instance. Does not apply to
\class
{
frozenset
}
instances. Returns 0 on success or -1 on failure.
Raises a
\exception
{
TypeError
}
if the key is unhashable.
Raises a
\exception
{
MemoryError
}
if there is no room to grow.
Raises a
\exception
{
SystemError
}
if
\var
{
key
}
is an not an instance
of
\class
{
set
}
or its subtype.
\end{cfuncdesc}
\begin{cfuncdesc}
{
PyObject*
}{
PySet
_
Pop
}{
PyObject *set
}
Returns a new reference to an arbitrary object in the
\var
{
set
}
,
and removes the object from the
\var
{
set
}
. Returns
\NULL
{}
on
failure. Raises
\exception
{
KeyError
}
if the set is empty.
Raises a
\exception
{
SystemError
}
if
\var
{
key
}
is an not an instance
of
\class
{
set
}
or its subtype.
\end{cfuncdesc}
Include/setobject.h
View file @
beb3101b
...
...
@@ -74,6 +74,15 @@ PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
PyAPI_FUNC
(
PyObject
*
)
PySet_New
(
PyObject
*
);
PyAPI_FUNC
(
PyObject
*
)
PyFrozenSet_New
(
PyObject
*
);
PyAPI_FUNC
(
int
)
PySet_Size
(
PyObject
*
anyset
);
#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used)
PyAPI_FUNC
(
int
)
PySet_Contains
(
PyObject
*
anyset
,
PyObject
*
key
);
PyAPI_FUNC
(
int
)
PySet_Discard
(
PyObject
*
anyset
,
PyObject
*
key
);
PyAPI_FUNC
(
int
)
PySet_Add
(
PyObject
*
set
,
PyObject
*
key
);
PyAPI_FUNC
(
PyObject
*
)
PySet_Pop
(
PyObject
*
set
);
#ifdef __cplusplus
}
#endif
...
...
Misc/NEWS
View file @
beb3101b
...
...
@@ -439,6 +439,8 @@ Build
C
API
-----
-
Added
a
C
API
for
set
and
frozenset
objects
.
-
Removed
PyRange_New
().
...
...
Objects/setobject.c
View file @
beb3101b
...
...
@@ -843,7 +843,7 @@ frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return
iterable
;
}
result
=
make_new_set
(
type
,
iterable
);
if
(
result
==
NULL
||
set_len
(
result
))
if
(
result
==
NULL
||
PySet_GET_SIZE
(
result
))
return
result
;
Py_DECREF
(
result
);
}
...
...
@@ -1052,7 +1052,7 @@ set_intersection(PySetObject *so, PyObject *other)
int
pos
=
0
;
setentry
*
entry
;
if
(
set_len
(
other
)
>
set_len
((
PyObject
*
)
so
))
{
if
(
PySet_GET_SIZE
(
other
)
>
PySet_GET_SIZE
(
so
))
{
tmp
=
(
PyObject
*
)
so
;
so
=
(
PySetObject
*
)
other
;
other
=
tmp
;
...
...
@@ -1381,7 +1381,7 @@ set_issubset(PySetObject *so, PyObject *other)
Py_DECREF
(
tmp
);
return
result
;
}
if
(
set_len
((
PyObject
*
)
so
)
>
set_len
(
other
))
if
(
PySet_GET_SIZE
(
so
)
>
PySet_GET_SIZE
(
other
))
Py_RETURN_FALSE
;
while
(
set_next
(
so
,
&
pos
,
&
entry
))
{
...
...
@@ -1426,11 +1426,11 @@ set_richcompare(PySetObject *v, PyObject *w, int op)
}
switch
(
op
)
{
case
Py_EQ
:
if
(
set_len
((
PyObject
*
)
v
)
!=
set_len
(
w
))
if
(
PySet_GET_SIZE
(
v
)
!=
PySet_GET_SIZE
(
w
))
Py_RETURN_FALSE
;
return
set_issubset
(
v
,
w
);
case
Py_NE
:
if
(
set_len
((
PyObject
*
)
v
)
!=
set_len
(
w
))
if
(
PySet_GET_SIZE
(
v
)
!=
PySet_GET_SIZE
(
w
))
Py_RETURN_TRUE
;
r1
=
set_issubset
(
v
,
w
);
assert
(
r1
!=
NULL
);
...
...
@@ -1442,11 +1442,11 @@ set_richcompare(PySetObject *v, PyObject *w, int op)
case
Py_GE
:
return
set_issuperset
(
v
,
w
);
case
Py_LT
:
if
(
set_len
((
PyObject
*
)
v
)
>=
set_len
(
w
))
if
(
PySet_GET_SIZE
(
v
)
>=
PySet_GET_SIZE
(
w
))
Py_RETURN_FALSE
;
return
set_issubset
(
v
,
w
);
case
Py_GT
:
if
(
set_len
((
PyObject
*
)
v
)
<=
set_len
(
w
))
if
(
PySet_GET_SIZE
(
v
)
<=
PySet_GET_SIZE
(
w
))
Py_RETURN_FALSE
;
return
set_issuperset
(
v
,
w
);
}
...
...
@@ -1472,7 +1472,7 @@ frozenset_hash(PyObject *self)
if
(
so
->
hash
!=
-
1
)
return
so
->
hash
;
hash
*=
set_len
(
self
)
+
1
;
hash
*=
PySet_GET_SIZE
(
self
)
+
1
;
while
(
set_next
(
so
,
&
pos
,
&
entry
))
{
/* Work to increase the bit dispersion for closely spaced hash
values. The is important because some use cases have many
...
...
@@ -1918,3 +1918,67 @@ PyTypeObject PyFrozenSet_Type = {
frozenset_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
};
/***** C API functions *************************************************/
PyObject
*
PySet_New
(
PyObject
*
iterable
)
{
return
make_new_set
(
&
PySet_Type
,
iterable
);
}
PyObject
*
PyFrozenSet_New
(
PyObject
*
iterable
)
{
PyObject
*
args
=
NULL
,
*
result
;
if
(
iterable
!=
NULL
)
{
args
=
PyTuple_Pack
(
1
,
iterable
);
if
(
args
==
NULL
)
return
NULL
;
}
result
=
frozenset_new
(
&
PyFrozenSet_Type
,
args
,
NULL
);
Py_DECREF
(
args
);
return
result
;
}
int
PySet_Contains
(
PyObject
*
anyset
,
PyObject
*
key
)
{
if
(
!
PyAnySet_Check
(
anyset
))
{
PyErr_BadInternalCall
();
return
-
1
;
}
return
set_contains_key
((
PySetObject
*
)
anyset
,
key
);
}
int
PySet_Discard
(
PyObject
*
anyset
,
PyObject
*
key
)
{
if
(
!
PyAnySet_Check
(
anyset
))
{
PyErr_BadInternalCall
();
return
-
1
;
}
return
set_discard_key
((
PySetObject
*
)
anyset
,
key
);
}
int
PySet_Add
(
PyObject
*
set
,
PyObject
*
key
)
{
if
(
!
PyType_IsSubtype
(
set
->
ob_type
,
&
PySet_Type
))
{
PyErr_BadInternalCall
();
return
-
1
;
}
return
set_add_key
((
PySetObject
*
)
set
,
key
);
}
PyObject
*
PySet_Pop
(
PyObject
*
set
)
{
if
(
!
PyType_IsSubtype
(
set
->
ob_type
,
&
PySet_Type
))
{
PyErr_BadInternalCall
();
return
NULL
;
}
return
set_pop
((
PySetObject
*
)
set
);
}
Python/marshal.c
View file @
beb3101b
...
...
@@ -773,11 +773,9 @@ r_object(RFILE *p)
if
(
v
==
NULL
)
return
v
;
if
(
type
==
TYPE_SET
)
v3
=
PyObject_CallFunctionObjArgs
(
(
PyObject
*
)
&
PySet_Type
,
v
,
NULL
);
v3
=
PySet_New
(
v
);
else
v3
=
PyObject_CallFunctionObjArgs
(
(
PyObject
*
)
&
PyFrozenSet_Type
,
v
,
NULL
);
v3
=
PyFrozenSet_New
(
v
);
Py_DECREF
(
v
);
return
v3
;
...
...
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