Commit 4148f516 authored by Stefan Behnel's avatar Stefan Behnel

replacement implementation for set/frozenset in Py3, mainly by Lisandro

parent 344e435f
......@@ -109,18 +109,13 @@ builtin_types_table = [
("slice", "PySlice_Type", []),
("file", "PyFile_Type", []),
("set", "PySet_Type", [("clear", "O", "i", "PySet_Clear"),
("discard", "OO", "i", "PySet_Discard"),
("add", "OO", "i", "PySet_Add"),
("pop", "O", "O", "PySet_Pop")]),
("frozenset", "PyFrozenSet_Type", []),
]
if 'set' in __builtin__.__dict__:
builtin_types_table += [
("set", "PySet_Type", [("clear", "O", "i", "PySet_Clear"),
("discard", "OO", "i", "PySet_Discard"),
("add", "OO", "i", "PySet_Add"),
("pop", "O", "O", "PySet_Pop")]),
("frozenset", "PyFrozenSet_Type", []),
]
builtin_structs_table = [
......@@ -166,9 +161,104 @@ intern_utility_code = ["""
""","""
"""]
py23_set_utility_code = ["""
#if PY_VERSION_HEX < 0x02050000
#ifndef PyAnySet_CheckExact
#define PyAnySet_CheckExact(ob) \
((ob)->ob_type == ((PyTypeObject*)&PySet_Type) || \
(ob)->ob_type == ((PyTypeObject*)&PyFrozenSet_Type))
#define PySet_Pop(set) PyObject_CallMethod(set, "pop", NULL)
static INLINE int PySet_Clear(PyObject *set) {
PyObject *ret = PyObject_CallMethod(set, "clear", NULL);
if (!ret) return -1;
Py_DECREF(ret); return 0;
}
static INLINE int PySet_Discard(PyObject *set, PyObject *key) {
PyObject *ret = PyObject_CallMethod(set, "discard", "O", key);
if (!ret) return -1;
Py_DECREF(ret); return 0;
}
static INLINE int PySet_Add(PyObject *set, PyObject *key) {
PyObject *ret = PyObject_CallMethod(set, "add", "O", key);
if (!ret) return -1;
Py_DECREF(ret); return 0;
}
#endif /* PyAnySet_CheckExact (<= Py2.4) */
#if PY_VERSION_HEX < 0x02040000
#ifndef Py_SETOBJECT_H
#define Py_SETOBJECT_H
static PyTypeObject *PySet_Type = NULL;
static PyTypeObject *PyFrozenSet_Type = NULL;
#define PyAnySet_Check(ob) \
(PyAnySet_CheckExact(ob) || \
PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type)
#define PySet_New(iterable) \
PyObject_CallFunctionObjArgs((PyObject *)PySet_Type, iterable, NULL)
#define Pyx_PyFrozenSet_New(iterable) \
PyObject_CallFunctionObjArgs((PyObject *)PyFrozenSet_Type, iterable, NULL)
#define PySet_Size(anyset) PyObject_Size(anyset)
#define PySet_Contains(anyset, key) PySequence_Contains(anyset, key)
/* ---------------------------------------------------------------- */
static int __Pyx_Py23SetsImport(void) {
PyObject *sets=0, *Set=0, *ImmutableSet=0;
sets = PyImport_ImportModule("sets");
if (!sets) goto bad;
Set = PyObject_GetAttrString(sets, "Set");
if (!Set) goto bad;
ImmutableSet = PyObject_GetAttrString(sets, "ImmutableSet");
if (!ImmutableSet) goto bad;
Py_DECREF(sets);
PySet_Type = (PyTypeObject*) Set;
PyFrozenSet_Type = (PyTypeObject*) ImmutableSet;
/* FIXME: this should be done in dedicated module cleanup code */
/*
Py_DECREF(Set);
Py_DECREF(ImmutableSet);
*/
return 0;
bad:
Py_XDECREF(sets);
Py_XDECREF(Set);
Py_XDECREF(ImmutableSet);
return -1;
}
/* ---------------------------------------------------------------- */
#else
static int py23sets_import(void) { return 0; }
#endif /* !Py_SETOBJECT_H */
#endif /* < Py2.4 */
#endif /* < Py2.5 */
""","""
"""]
builtin_utility_code = {
'getattr3': getattr3_utility_code,
'intern' : intern_utility_code,
'getattr3' : getattr3_utility_code,
'intern' : intern_utility_code,
'set' : py23_set_utility_code,
'frozenset' : py23_set_utility_code,
}
builtin_scope = BuiltinScope()
......@@ -185,7 +275,8 @@ def init_builtin_funcs():
def init_builtin_types():
for name, cname, funcs in builtin_types_table:
the_type = builtin_scope.declare_builtin_type(name, cname)
utility = builtin_utility_code.get(name)
the_type = builtin_scope.declare_builtin_type(name, cname, utility)
for name, args, ret, cname in funcs:
sig = Signature(args, ret)
the_type.scope.declare_cfunction(name, sig.function_type(), None, cname)
......
......@@ -1567,6 +1567,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Initialize various global constants etc. ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
code.putln("#if PY_VERSION_HEX < 0x02040000")
code.putln(code.error_goto_if_neg("__Pyx_Py23SetsImport()", self.pos))
code.putln("#endif")
code.putln("/*--- Module creation code ---*/")
self.generate_module_creation_code(env, code)
......@@ -1574,7 +1578,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Builtin init code ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
self.pos))
code.putln("%s = 0;" % Naming.skip_dispatch_cname);
code.putln("/*--- Global init code ---*/")
......
......@@ -706,7 +706,7 @@ class BuiltinScope(Scope):
entry.as_variable = var_entry
return entry
def declare_builtin_type(self, name, cname):
def declare_builtin_type(self, name, cname, utility_code = None):
name = EncodedString(name)
type = PyrexTypes.BuiltinObjectType(name, cname)
type.set_scope(CClassScope(name, outer_scope=None, visibility='extern'))
......@@ -720,6 +720,7 @@ class BuiltinScope(Scope):
var_entry.is_variable = 1
var_entry.is_cglobal = 1
var_entry.is_readonly = 1
var_entry.utility_code = utility_code
entry.as_variable = var_entry
return type
......
......@@ -19,7 +19,8 @@ EXT_DEP_MODULES = {
}
VER_DEP_MODULES = {
(2,4) : lambda x: x in ['run.set']
# such as:
# (2,4) : lambda x: x in ['run.set']
}
INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment