ยปCore Development>Code coverage>Objects/namespaceobject.c

Python code coverage for Objects/namespaceobject.c

#countcontent
1n/a// namespace object implementation
2n/a
3n/a#include "Python.h"
4n/a#include "structmember.h"
5n/a
6n/a
7n/atypedef struct {
8n/a PyObject_HEAD
9n/a PyObject *ns_dict;
10n/a} _PyNamespaceObject;
11n/a
12n/a
13n/astatic PyMemberDef namespace_members[] = {
14n/a {"__dict__", T_OBJECT, offsetof(_PyNamespaceObject, ns_dict), READONLY},
15n/a {NULL}
16n/a};
17n/a
18n/a
19n/a// Methods
20n/a
21n/astatic PyObject *
22n/anamespace_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23n/a{
24n/a PyObject *self;
25n/a
26n/a assert(type != NULL && type->tp_alloc != NULL);
27n/a self = type->tp_alloc(type, 0);
28n/a if (self != NULL) {
29n/a _PyNamespaceObject *ns = (_PyNamespaceObject *)self;
30n/a ns->ns_dict = PyDict_New();
31n/a if (ns->ns_dict == NULL) {
32n/a Py_DECREF(ns);
33n/a return NULL;
34n/a }
35n/a }
36n/a return self;
37n/a}
38n/a
39n/a
40n/astatic int
41n/anamespace_init(_PyNamespaceObject *ns, PyObject *args, PyObject *kwds)
42n/a{
43n/a // ignore args if it's NULL or empty
44n/a if (args != NULL) {
45n/a Py_ssize_t argcount = PyObject_Size(args);
46n/a if (argcount < 0)
47n/a return -1;
48n/a else if (argcount > 0) {
49n/a PyErr_Format(PyExc_TypeError, "no positional arguments expected");
50n/a return -1;
51n/a }
52n/a }
53n/a if (kwds == NULL)
54n/a return 0;
55n/a return PyDict_Update(ns->ns_dict, kwds);
56n/a}
57n/a
58n/a
59n/astatic void
60n/anamespace_dealloc(_PyNamespaceObject *ns)
61n/a{
62n/a PyObject_GC_UnTrack(ns);
63n/a Py_CLEAR(ns->ns_dict);
64n/a Py_TYPE(ns)->tp_free((PyObject *)ns);
65n/a}
66n/a
67n/a
68n/astatic PyObject *
69n/anamespace_repr(PyObject *ns)
70n/a{
71n/a int i, loop_error = 0;
72n/a PyObject *pairs = NULL, *d = NULL, *keys = NULL, *keys_iter = NULL;
73n/a PyObject *key;
74n/a PyObject *separator, *pairsrepr, *repr = NULL;
75n/a const char * name;
76n/a
77n/a name = (Py_TYPE(ns) == &_PyNamespace_Type) ? "namespace"
78n/a : ns->ob_type->tp_name;
79n/a
80n/a i = Py_ReprEnter(ns);
81n/a if (i != 0) {
82n/a return i > 0 ? PyUnicode_FromFormat("%s(...)", name) : NULL;
83n/a }
84n/a
85n/a pairs = PyList_New(0);
86n/a if (pairs == NULL)
87n/a goto error;
88n/a
89n/a d = ((_PyNamespaceObject *)ns)->ns_dict;
90n/a assert(d != NULL);
91n/a Py_INCREF(d);
92n/a
93n/a keys = PyDict_Keys(d);
94n/a if (keys == NULL)
95n/a goto error;
96n/a if (PyList_Sort(keys) != 0)
97n/a goto error;
98n/a
99n/a keys_iter = PyObject_GetIter(keys);
100n/a if (keys_iter == NULL)
101n/a goto error;
102n/a
103n/a while ((key = PyIter_Next(keys_iter)) != NULL) {
104n/a if (PyUnicode_Check(key) && PyUnicode_GET_LENGTH(key) > 0) {
105n/a PyObject *value, *item;
106n/a
107n/a value = PyDict_GetItem(d, key);
108n/a assert(value != NULL);
109n/a
110n/a item = PyUnicode_FromFormat("%S=%R", key, value);
111n/a if (item == NULL) {
112n/a loop_error = 1;
113n/a }
114n/a else {
115n/a loop_error = PyList_Append(pairs, item);
116n/a Py_DECREF(item);
117n/a }
118n/a }
119n/a
120n/a Py_DECREF(key);
121n/a if (loop_error)
122n/a goto error;
123n/a }
124n/a
125n/a separator = PyUnicode_FromString(", ");
126n/a if (separator == NULL)
127n/a goto error;
128n/a
129n/a pairsrepr = PyUnicode_Join(separator, pairs);
130n/a Py_DECREF(separator);
131n/a if (pairsrepr == NULL)
132n/a goto error;
133n/a
134n/a repr = PyUnicode_FromFormat("%s(%S)", name, pairsrepr);
135n/a Py_DECREF(pairsrepr);
136n/a
137n/aerror:
138n/a Py_XDECREF(pairs);
139n/a Py_XDECREF(d);
140n/a Py_XDECREF(keys);
141n/a Py_XDECREF(keys_iter);
142n/a Py_ReprLeave(ns);
143n/a
144n/a return repr;
145n/a}
146n/a
147n/a
148n/astatic int
149n/anamespace_traverse(_PyNamespaceObject *ns, visitproc visit, void *arg)
150n/a{
151n/a Py_VISIT(ns->ns_dict);
152n/a return 0;
153n/a}
154n/a
155n/a
156n/astatic int
157n/anamespace_clear(_PyNamespaceObject *ns)
158n/a{
159n/a Py_CLEAR(ns->ns_dict);
160n/a return 0;
161n/a}
162n/a
163n/a
164n/astatic PyObject *
165n/anamespace_richcompare(PyObject *self, PyObject *other, int op)
166n/a{
167n/a if (PyObject_TypeCheck(self, &_PyNamespace_Type) &&
168n/a PyObject_TypeCheck(other, &_PyNamespace_Type))
169n/a return PyObject_RichCompare(((_PyNamespaceObject *)self)->ns_dict,
170n/a ((_PyNamespaceObject *)other)->ns_dict, op);
171n/a Py_RETURN_NOTIMPLEMENTED;
172n/a}
173n/a
174n/a
175n/aPyDoc_STRVAR(namespace_reduce__doc__, "Return state information for pickling");
176n/a
177n/astatic PyObject *
178n/anamespace_reduce(_PyNamespaceObject *ns)
179n/a{
180n/a PyObject *result, *args = PyTuple_New(0);
181n/a
182n/a if (!args)
183n/a return NULL;
184n/a
185n/a result = PyTuple_Pack(3, (PyObject *)Py_TYPE(ns), args, ns->ns_dict);
186n/a Py_DECREF(args);
187n/a return result;
188n/a}
189n/a
190n/a
191n/astatic PyMethodDef namespace_methods[] = {
192n/a {"__reduce__", (PyCFunction)namespace_reduce, METH_NOARGS,
193n/a namespace_reduce__doc__},
194n/a {NULL, NULL} // sentinel
195n/a};
196n/a
197n/a
198n/aPyDoc_STRVAR(namespace_doc,
199n/a"A simple attribute-based namespace.\n\
200n/a\n\
201n/aSimpleNamespace(**kwargs)");
202n/a
203n/aPyTypeObject _PyNamespace_Type = {
204n/a PyVarObject_HEAD_INIT(&PyType_Type, 0)
205n/a "types.SimpleNamespace", /* tp_name */
206n/a sizeof(_PyNamespaceObject), /* tp_size */
207n/a 0, /* tp_itemsize */
208n/a (destructor)namespace_dealloc, /* tp_dealloc */
209n/a 0, /* tp_print */
210n/a 0, /* tp_getattr */
211n/a 0, /* tp_setattr */
212n/a 0, /* tp_reserved */
213n/a (reprfunc)namespace_repr, /* tp_repr */
214n/a 0, /* tp_as_number */
215n/a 0, /* tp_as_sequence */
216n/a 0, /* tp_as_mapping */
217n/a 0, /* tp_hash */
218n/a 0, /* tp_call */
219n/a 0, /* tp_str */
220n/a PyObject_GenericGetAttr, /* tp_getattro */
221n/a PyObject_GenericSetAttr, /* tp_setattro */
222n/a 0, /* tp_as_buffer */
223n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
224n/a Py_TPFLAGS_BASETYPE, /* tp_flags */
225n/a namespace_doc, /* tp_doc */
226n/a (traverseproc)namespace_traverse, /* tp_traverse */
227n/a (inquiry)namespace_clear, /* tp_clear */
228n/a namespace_richcompare, /* tp_richcompare */
229n/a 0, /* tp_weaklistoffset */
230n/a 0, /* tp_iter */
231n/a 0, /* tp_iternext */
232n/a namespace_methods, /* tp_methods */
233n/a namespace_members, /* tp_members */
234n/a 0, /* tp_getset */
235n/a 0, /* tp_base */
236n/a 0, /* tp_dict */
237n/a 0, /* tp_descr_get */
238n/a 0, /* tp_descr_set */
239n/a offsetof(_PyNamespaceObject, ns_dict), /* tp_dictoffset */
240n/a (initproc)namespace_init, /* tp_init */
241n/a PyType_GenericAlloc, /* tp_alloc */
242n/a (newfunc)namespace_new, /* tp_new */
243n/a PyObject_GC_Del, /* tp_free */
244n/a};
245n/a
246n/a
247n/aPyObject *
248n/a_PyNamespace_New(PyObject *kwds)
249n/a{
250n/a PyObject *ns = namespace_new(&_PyNamespace_Type, NULL, NULL);
251n/a if (ns == NULL)
252n/a return NULL;
253n/a
254n/a if (kwds == NULL)
255n/a return ns;
256n/a if (PyDict_Update(((_PyNamespaceObject *)ns)->ns_dict, kwds) != 0) {
257n/a Py_DECREF(ns);
258n/a return NULL;
259n/a }
260n/a
261n/a return (PyObject *)ns;
262n/a}