ndtypes 0.2.0dev4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +2 -0
- data/History.md +0 -0
- data/README.md +19 -0
- data/Rakefile +125 -0
- data/ext/ruby_ndtypes/extconf.rb +55 -0
- data/ext/ruby_ndtypes/gc_guard.c +36 -0
- data/ext/ruby_ndtypes/gc_guard.h +12 -0
- data/ext/ruby_ndtypes/ndtypes/AUTHORS.txt +5 -0
- data/ext/ruby_ndtypes/ndtypes/INSTALL.txt +101 -0
- data/ext/ruby_ndtypes/ndtypes/LICENSE.txt +29 -0
- data/ext/ruby_ndtypes/ndtypes/MANIFEST.in +3 -0
- data/ext/ruby_ndtypes/ndtypes/Makefile.in +87 -0
- data/ext/ruby_ndtypes/ndtypes/README.rst +47 -0
- data/ext/ruby_ndtypes/ndtypes/config.guess +1530 -0
- data/ext/ruby_ndtypes/ndtypes/config.h.in +67 -0
- data/ext/ruby_ndtypes/ndtypes/config.sub +1782 -0
- data/ext/ruby_ndtypes/ndtypes/configure +5260 -0
- data/ext/ruby_ndtypes/ndtypes/configure.ac +161 -0
- data/ext/ruby_ndtypes/ndtypes/doc/Makefile +14 -0
- data/ext/ruby_ndtypes/ndtypes/doc/_static/copybutton.js +66 -0
- data/ext/ruby_ndtypes/ndtypes/doc/conf.py +26 -0
- data/ext/ruby_ndtypes/ndtypes/doc/grammar/grammar.rst +27 -0
- data/ext/ruby_ndtypes/ndtypes/doc/index.rst +56 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/context.rst +131 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/encodings.rst +68 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/fields-values.rst +175 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/functions.rst +72 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/index.rst +43 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/init.rst +48 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/io.rst +100 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/memory.rst +124 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/predicates.rst +110 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/typedef.rst +31 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/types.rst +594 -0
- data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/util.rst +166 -0
- data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/buffer-protocol.rst +27 -0
- data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/index.rst +21 -0
- data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/pattern-matching.rst +330 -0
- data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/quickstart.rst +144 -0
- data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +544 -0
- data/ext/ruby_ndtypes/ndtypes/doc/releases/index.rst +35 -0
- data/ext/ruby_ndtypes/ndtypes/install-sh +527 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +271 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +269 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +230 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.c +268 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.h +109 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.in +73 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.vc +70 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/README.txt +16 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +2179 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +134 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +428 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +2543 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +735 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +176 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +543 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +110 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/context.c +228 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +634 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.c +116 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +288 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +3067 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +180 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +417 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +1658 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +2773 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +734 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +222 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +1132 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +2323 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +893 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/overflow.h +161 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +473 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +92 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +246 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +269 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +197 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.in +48 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.vc +46 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +1007 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +442 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/slice.h +42 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +238 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +50 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +371 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +100 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +55 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +45 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.c +82 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.h +49 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +1657 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +85 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +115 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +137 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_indent.c +201 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +2397 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_numba.c +57 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +349 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +27839 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +350 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +231 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +375 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typedef.c +65 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/valgrind.supp +30 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/bench.c +79 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/indent.c +94 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/print_ast.c +96 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +474 -0
- data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +228 -0
- data/ext/ruby_ndtypes/ndtypes/python/bench.py +49 -0
- data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +409 -0
- data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +14 -0
- data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +70 -0
- data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +1332 -0
- data/ext/ruby_ndtypes/ndtypes/python/ndtypes/docstrings.h +319 -0
- data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +154 -0
- data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +1977 -0
- data/ext/ruby_ndtypes/ndtypes/setup.py +288 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/INSTALL.txt +41 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest32.bat +15 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest64.bat +13 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild32.bat +38 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild64.bat +38 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/vcclean.bat +13 -0
- data/ext/ruby_ndtypes/ndtypes/vcbuild/vcdistclean.bat +14 -0
- data/ext/ruby_ndtypes/ruby_ndtypes.c +1003 -0
- data/ext/ruby_ndtypes/ruby_ndtypes.h +37 -0
- data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +28 -0
- data/lib/ndtypes.rb +45 -0
- data/lib/ndtypes/errors.rb +2 -0
- data/lib/ndtypes/version.rb +6 -0
- data/ndtypes.gemspec +47 -0
- data/spec/gc_table_spec.rb +10 -0
- data/spec/ndtypes_spec.rb +289 -0
- data/spec/spec_helper.rb +241 -0
- metadata +242 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
def skip_if(condition, reason):
|
|
5
|
+
if condition:
|
|
6
|
+
raise unittest.SkipTest(reason)
|
|
7
|
+
|
|
8
|
+
HAVE_PYTHON_36 = sys.version_info >= (3, 6, 0)
|
|
9
|
+
HAVE_32_BIT_LINUX = sys.maxsize == 2**31-1 and sys.platform == 'linux'
|
|
10
|
+
|
|
11
|
+
requires_py36 = unittest.skipUnless(
|
|
12
|
+
sys.version_info > (3, 6),
|
|
13
|
+
"test requires Python 3.6 or greater")
|
|
14
|
+
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#
|
|
2
|
+
# BSD 3-Clause License
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2018, plures
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
# and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# 3. Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from
|
|
19
|
+
# this software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
#
|
|
26
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
27
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
28
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
29
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
30
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
31
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
A module for typing memory blocks using a close variant of the datashape type
|
|
36
|
+
language.
|
|
37
|
+
|
|
38
|
+
The underlying library -- libndtypes -- implements the type part of a compiler
|
|
39
|
+
frontend. It can describe C types needed for array computing and additionally
|
|
40
|
+
includes symbolic types for dynamic type checking.
|
|
41
|
+
|
|
42
|
+
libndtypes has the concept of abstract and concrete types. Concrete types
|
|
43
|
+
contain the exact data layout and all sizes that are required to access
|
|
44
|
+
subtypes or individual elements in memory.
|
|
45
|
+
|
|
46
|
+
Abstract types are for type checking and include functions, symbolic dimensions
|
|
47
|
+
and type variables. Module support is planned at a later stage.
|
|
48
|
+
|
|
49
|
+
Concrete types with rich layout information make it possible to write
|
|
50
|
+
relatively small container libraries that can traverse memory without
|
|
51
|
+
type erasure.
|
|
52
|
+
|
|
53
|
+
The xnd module uses ndtypes to implement a general container for mapping most
|
|
54
|
+
Python types relevant for scientific computing directly to memory.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def _pretty_repr(self):
|
|
58
|
+
return """\
|
|
59
|
+
ApplySpec(
|
|
60
|
+
flags=%r,
|
|
61
|
+
sig=%r,
|
|
62
|
+
in_types=%r,
|
|
63
|
+
in_broadcast=%r,
|
|
64
|
+
out_types=%r,
|
|
65
|
+
outer_dims=%r
|
|
66
|
+
)""" % (self.flags, self.sig, self.in_types, self.in_broadcast, self.out_types, self.outer_dims)
|
|
67
|
+
|
|
68
|
+
from . import _ndtypes
|
|
69
|
+
_ndtypes.ApplySpec.__repr__ = _pretty_repr
|
|
70
|
+
from ._ndtypes import *
|
|
@@ -0,0 +1,1332 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BSD 3-Clause License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017-2018, plures
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
|
9
|
+
*
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer.
|
|
12
|
+
*
|
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
* and/or other materials provided with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
|
19
|
+
* this software without specific prior written permission.
|
|
20
|
+
*
|
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#include <Python.h>
|
|
35
|
+
#include <stdlib.h>
|
|
36
|
+
#include "ndtypes.h"
|
|
37
|
+
#include "docstrings.h"
|
|
38
|
+
|
|
39
|
+
#define NDTYPES_MODULE
|
|
40
|
+
#include "pyndtypes.h"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
#ifdef _MSC_VER
|
|
44
|
+
#ifndef UNUSED
|
|
45
|
+
#define UNUSED
|
|
46
|
+
#endif
|
|
47
|
+
#else
|
|
48
|
+
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
|
49
|
+
#define UNUSED __attribute__((unused))
|
|
50
|
+
#else
|
|
51
|
+
#define UNUSED
|
|
52
|
+
#endif
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/****************************************************************************/
|
|
57
|
+
/* Resource Buffer Object */
|
|
58
|
+
/****************************************************************************/
|
|
59
|
+
|
|
60
|
+
/* This object handles resources like offsets that are shared by several
|
|
61
|
+
ndt objects. It is never exposed to the Python level.
|
|
62
|
+
|
|
63
|
+
At a later stage, the object will need to communicate with Arrow
|
|
64
|
+
or other formats to store external resources. */
|
|
65
|
+
|
|
66
|
+
static PyObject *seterr(ndt_context_t *ctx);
|
|
67
|
+
|
|
68
|
+
typedef struct {
|
|
69
|
+
PyObject_HEAD
|
|
70
|
+
ndt_meta_t *m;
|
|
71
|
+
} ResourceBufferObject;
|
|
72
|
+
|
|
73
|
+
static PyTypeObject ResourceBuffer_Type;
|
|
74
|
+
|
|
75
|
+
static PyObject *
|
|
76
|
+
rbuf_alloc(void)
|
|
77
|
+
{
|
|
78
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
79
|
+
ResourceBufferObject *self;
|
|
80
|
+
|
|
81
|
+
self = (ResourceBufferObject *)
|
|
82
|
+
PyObject_GC_New(ResourceBufferObject, &ResourceBuffer_Type);
|
|
83
|
+
if (self == NULL) {
|
|
84
|
+
return NULL;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
self->m = ndt_meta_new(&ctx);
|
|
88
|
+
if (self->m == NULL) {
|
|
89
|
+
return seterr(&ctx);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
PyObject_GC_Track(self);
|
|
93
|
+
return (PyObject *)self;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static int
|
|
97
|
+
rbuf_traverse(ResourceBufferObject *self UNUSED, visitproc visit UNUSED,
|
|
98
|
+
void *arg UNUSED)
|
|
99
|
+
{
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static void
|
|
104
|
+
rbuf_dealloc(ResourceBufferObject *self)
|
|
105
|
+
{
|
|
106
|
+
ndt_meta_del(self->m);
|
|
107
|
+
self->m = NULL;
|
|
108
|
+
PyObject_GC_UnTrack(self);
|
|
109
|
+
PyObject_GC_Del(self);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static int
|
|
113
|
+
rbuf_init_from_offset_list(ResourceBufferObject *rbuf, PyObject *list)
|
|
114
|
+
{
|
|
115
|
+
ndt_meta_t * const m = rbuf->m;
|
|
116
|
+
PyObject *lst;
|
|
117
|
+
|
|
118
|
+
if (!PyList_Check(list)) {
|
|
119
|
+
PyErr_SetString(PyExc_TypeError, "expected a list of offset lists");
|
|
120
|
+
return -1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const int64_t n = PyList_GET_SIZE(list);
|
|
124
|
+
if (n < 1 || n > NDT_MAX_DIM) {
|
|
125
|
+
PyErr_Format(PyExc_ValueError,
|
|
126
|
+
"number of offset lists must be in [1, %d]", NDT_MAX_DIM);
|
|
127
|
+
return -1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
m->ndims = 0;
|
|
131
|
+
for (int64_t i = n-1; i >= 0; i--) {
|
|
132
|
+
lst = PyList_GET_ITEM(list, i);
|
|
133
|
+
if (!PyList_Check(lst)) {
|
|
134
|
+
PyErr_SetString(PyExc_TypeError,
|
|
135
|
+
"expected a list of offset lists");
|
|
136
|
+
return -1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const int64_t noffsets = PyList_GET_SIZE(lst);
|
|
140
|
+
if (noffsets < 2 || noffsets > INT32_MAX) {
|
|
141
|
+
PyErr_SetString(PyExc_ValueError,
|
|
142
|
+
"length of a single offset list must be in [2, INT32_MAX]");
|
|
143
|
+
return -1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
int32_t * const offsets = ndt_alloc(noffsets, sizeof(int32_t));
|
|
147
|
+
if (offsets == NULL) {
|
|
148
|
+
PyErr_NoMemory();
|
|
149
|
+
return -1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (int32_t k = 0; k < noffsets; k++) {
|
|
153
|
+
long long x = PyLong_AsLongLong(PyList_GET_ITEM(lst, k));
|
|
154
|
+
if (x == -1 && PyErr_Occurred()) {
|
|
155
|
+
ndt_free(offsets);
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (x < 0 || x > INT32_MAX) {
|
|
160
|
+
ndt_free(offsets);
|
|
161
|
+
PyErr_SetString(PyExc_ValueError,
|
|
162
|
+
"offset must be in [0, INT32_MAX]");
|
|
163
|
+
return -1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
offsets[k] = (int32_t)x;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
m->noffsets[m->ndims] = (int32_t)noffsets;
|
|
170
|
+
m->offsets[m->ndims] = offsets;
|
|
171
|
+
m->ndims++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static PyObject *
|
|
178
|
+
rbuf_from_offset_lists(PyObject *list)
|
|
179
|
+
{
|
|
180
|
+
PyObject *rbuf;
|
|
181
|
+
|
|
182
|
+
rbuf = rbuf_alloc();
|
|
183
|
+
if (rbuf == NULL) {
|
|
184
|
+
return NULL;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (rbuf_init_from_offset_list((ResourceBufferObject *)rbuf, list) < 0) {
|
|
188
|
+
Py_DECREF(rbuf);
|
|
189
|
+
return NULL;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return rbuf;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static PyTypeObject ResourceBuffer_Type = {
|
|
196
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
197
|
+
.tp_name = "_ndtypes.resource",
|
|
198
|
+
.tp_basicsize = sizeof(ResourceBufferObject),
|
|
199
|
+
.tp_dealloc = (destructor)rbuf_dealloc,
|
|
200
|
+
.tp_getattro = PyObject_GenericGetAttr,
|
|
201
|
+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
|
|
202
|
+
.tp_traverse = (traverseproc)rbuf_traverse
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
/****************************************************************************/
|
|
207
|
+
/* Cached objects */
|
|
208
|
+
/****************************************************************************/
|
|
209
|
+
|
|
210
|
+
static PyObject *Deserialize = NULL;
|
|
211
|
+
static PyTypeObject *ApplySpec = NULL;
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
/****************************************************************************/
|
|
215
|
+
/* Error handling */
|
|
216
|
+
/****************************************************************************/
|
|
217
|
+
|
|
218
|
+
static PyObject *
|
|
219
|
+
seterr(ndt_context_t *ctx)
|
|
220
|
+
{
|
|
221
|
+
PyObject *exc = PyExc_RuntimeError;
|
|
222
|
+
|
|
223
|
+
switch (ctx->err) {
|
|
224
|
+
case NDT_Success: /* should never be set on error */
|
|
225
|
+
exc = PyExc_RuntimeError;
|
|
226
|
+
break;
|
|
227
|
+
case NDT_ValueError:
|
|
228
|
+
exc = PyExc_ValueError;
|
|
229
|
+
break;
|
|
230
|
+
case NDT_TypeError:
|
|
231
|
+
exc = PyExc_TypeError;
|
|
232
|
+
break;
|
|
233
|
+
case NDT_InvalidArgumentError:
|
|
234
|
+
exc = PyExc_ValueError;
|
|
235
|
+
break;
|
|
236
|
+
case NDT_NotImplementedError:
|
|
237
|
+
exc = PyExc_NotImplementedError;
|
|
238
|
+
break;
|
|
239
|
+
case NDT_IndexError:
|
|
240
|
+
exc = PyExc_IndexError;
|
|
241
|
+
break;
|
|
242
|
+
case NDT_LexError: case NDT_ParseError:
|
|
243
|
+
exc = PyExc_ValueError;
|
|
244
|
+
break;
|
|
245
|
+
case NDT_OSError:
|
|
246
|
+
exc = PyExc_OSError;
|
|
247
|
+
break;
|
|
248
|
+
case NDT_RuntimeError:
|
|
249
|
+
exc = PyExc_RuntimeError;
|
|
250
|
+
break;
|
|
251
|
+
case NDT_MemoryError:
|
|
252
|
+
exc = PyExc_MemoryError;
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
PyErr_SetString(exc, ndt_context_msg(ctx));
|
|
257
|
+
ndt_context_del(ctx);
|
|
258
|
+
|
|
259
|
+
return NULL;
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
/****************************************************************************/
|
|
264
|
+
/* ndt object */
|
|
265
|
+
/****************************************************************************/
|
|
266
|
+
|
|
267
|
+
static PyTypeObject Ndt_Type;
|
|
268
|
+
|
|
269
|
+
static PyObject *
|
|
270
|
+
ndtype_alloc(PyTypeObject *type)
|
|
271
|
+
{
|
|
272
|
+
NdtObject *self;
|
|
273
|
+
|
|
274
|
+
self = (NdtObject *)type->tp_alloc(type, 0);
|
|
275
|
+
if (self == NULL) {
|
|
276
|
+
return NULL;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
RBUF(self) = NULL;
|
|
280
|
+
NDT(self) = NULL;
|
|
281
|
+
|
|
282
|
+
return (PyObject *)self;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static int
|
|
286
|
+
ndtype_traverse(NdtObject *self, visitproc visit, void *arg)
|
|
287
|
+
{
|
|
288
|
+
Py_VISIT(self->rbuf);
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
static void
|
|
293
|
+
ndtype_dealloc(NdtObject *self)
|
|
294
|
+
{
|
|
295
|
+
PyObject_GC_UnTrack(self);
|
|
296
|
+
ndt_del(NDT(self));
|
|
297
|
+
Py_CLEAR(self->rbuf);
|
|
298
|
+
Py_TYPE(self)->tp_free(self);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static PyObject *
|
|
302
|
+
ndtype_from_object(PyTypeObject *tp, PyObject *type)
|
|
303
|
+
{
|
|
304
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
305
|
+
PyObject *self;
|
|
306
|
+
const char *cp;
|
|
307
|
+
|
|
308
|
+
if (Ndt_Check(type)) {
|
|
309
|
+
Py_INCREF(type);
|
|
310
|
+
return type;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
cp = PyUnicode_AsUTF8(type);
|
|
314
|
+
if (cp == NULL) {
|
|
315
|
+
return NULL;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
self = ndtype_alloc(tp);
|
|
319
|
+
if (self == NULL) {
|
|
320
|
+
return NULL;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
RBUF(self) = rbuf_alloc();
|
|
324
|
+
if (RBUF(self) == NULL) {
|
|
325
|
+
Py_DECREF(self);
|
|
326
|
+
return NULL;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
NDT(self) = ndt_from_string_fill_meta(RBUF_NDT_META(self), cp, &ctx);
|
|
330
|
+
if (NDT(self) == NULL) {
|
|
331
|
+
Py_DECREF(self);
|
|
332
|
+
return seterr(&ctx);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return self;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
static PyObject *
|
|
339
|
+
ndtype_from_format(PyTypeObject *tp, PyObject *format)
|
|
340
|
+
{
|
|
341
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
342
|
+
PyObject *self;
|
|
343
|
+
const char *cp;
|
|
344
|
+
|
|
345
|
+
cp = PyUnicode_AsUTF8(format);
|
|
346
|
+
if (cp == NULL) {
|
|
347
|
+
return NULL;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
self = ndtype_alloc(tp);
|
|
351
|
+
if (self == NULL) {
|
|
352
|
+
return NULL;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
NDT(self) = ndt_from_bpformat(cp, &ctx);
|
|
356
|
+
if (NDT(self) == NULL) {
|
|
357
|
+
Py_DECREF(self);
|
|
358
|
+
return seterr(&ctx);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return self;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
static PyObject *
|
|
365
|
+
ndtype_to_format(PyObject *self, PyObject *args UNUSED)
|
|
366
|
+
{
|
|
367
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
368
|
+
PyObject *ret;
|
|
369
|
+
char *cp;
|
|
370
|
+
|
|
371
|
+
cp = ndt_to_bpformat(NDT(self), &ctx);
|
|
372
|
+
if (cp == NULL) {
|
|
373
|
+
return seterr(&ctx);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
ret = PyUnicode_FromString(cp);
|
|
377
|
+
ndt_free(cp);
|
|
378
|
+
|
|
379
|
+
return ret;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
static PyObject *
|
|
383
|
+
ndtype_from_offsets_and_dtype(PyTypeObject *tp, PyObject *offsets, PyObject *dtype)
|
|
384
|
+
{
|
|
385
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
386
|
+
PyObject *self;
|
|
387
|
+
const char *cp;
|
|
388
|
+
|
|
389
|
+
cp = PyUnicode_AsUTF8(dtype);
|
|
390
|
+
if (cp == NULL) {
|
|
391
|
+
return NULL;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
self = ndtype_alloc(tp);
|
|
395
|
+
if (self == NULL) {
|
|
396
|
+
return NULL;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
RBUF(self) = rbuf_from_offset_lists(offsets);
|
|
400
|
+
if (RBUF(self) == NULL) {
|
|
401
|
+
Py_DECREF(self);
|
|
402
|
+
return NULL;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
NDT(self) = ndt_from_metadata_and_dtype(RBUF_NDT_META(self), cp, &ctx);
|
|
406
|
+
|
|
407
|
+
if (NDT(self) == NULL) {
|
|
408
|
+
Py_DECREF(self);
|
|
409
|
+
return seterr(&ctx);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return self;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
static PyObject *
|
|
416
|
+
ndtype_deserialize(PyTypeObject *tp, PyObject *bytes)
|
|
417
|
+
{
|
|
418
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
419
|
+
PyObject *self;
|
|
420
|
+
|
|
421
|
+
if (!PyBytes_Check(bytes)) {
|
|
422
|
+
PyErr_SetString(PyExc_TypeError, "expected bytes object");
|
|
423
|
+
return NULL;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
self = ndtype_alloc(tp);
|
|
427
|
+
if (self == NULL) {
|
|
428
|
+
return NULL;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
RBUF(self) = rbuf_alloc();
|
|
432
|
+
if (RBUF(self) == NULL) {
|
|
433
|
+
Py_DECREF(self);
|
|
434
|
+
return NULL;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
NDT(self) = ndt_deserialize(RBUF_NDT_META(self), PyBytes_AS_STRING(bytes),
|
|
438
|
+
PyBytes_GET_SIZE(bytes), &ctx);
|
|
439
|
+
if (NDT(self) == NULL) {
|
|
440
|
+
Py_DECREF(self);
|
|
441
|
+
return seterr(&ctx);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return self;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
static PyObject *
|
|
448
|
+
ndtype_new(PyTypeObject *tp, PyObject *args, PyObject *kwds)
|
|
449
|
+
{
|
|
450
|
+
static char *kwlist[] = {"type", "offsets", NULL};
|
|
451
|
+
PyObject *offsets = Py_None;
|
|
452
|
+
PyObject *type;
|
|
453
|
+
|
|
454
|
+
if (!PyArg_ParseTupleAndKeywords(
|
|
455
|
+
args, kwds, "O|O", kwlist, &type, &offsets)) {
|
|
456
|
+
return NULL;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (offsets == Py_None) {
|
|
460
|
+
return ndtype_from_object(tp, type);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return ndtype_from_offsets_and_dtype(tp, offsets, type);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
static PyObject *
|
|
467
|
+
ndtype_str(PyObject *self)
|
|
468
|
+
{
|
|
469
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
470
|
+
PyObject *res;
|
|
471
|
+
char *cp;
|
|
472
|
+
|
|
473
|
+
cp = ndt_as_string(NDT(self), &ctx);
|
|
474
|
+
if (cp == NULL) {
|
|
475
|
+
return seterr(&ctx);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
res = PyUnicode_FromString(cp);
|
|
479
|
+
ndt_free(cp);
|
|
480
|
+
return res;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
static PyObject *
|
|
484
|
+
ndtype_repr(PyObject *self)
|
|
485
|
+
{
|
|
486
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
487
|
+
PyObject *res;
|
|
488
|
+
char *cp;
|
|
489
|
+
|
|
490
|
+
cp = ndt_as_string(NDT(self), &ctx);
|
|
491
|
+
if (cp == NULL) {
|
|
492
|
+
return seterr(&ctx);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
res = PyUnicode_FromFormat("ndt(\"%s\")", cp);
|
|
496
|
+
ndt_free(cp);
|
|
497
|
+
return res;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
static PyObject *
|
|
501
|
+
ndtype_pformat(PyObject *self, PyObject *args UNUSED)
|
|
502
|
+
{
|
|
503
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
504
|
+
PyObject *res;
|
|
505
|
+
char *cp;
|
|
506
|
+
|
|
507
|
+
cp = ndt_indent(NDT(self), &ctx);
|
|
508
|
+
if (cp == NULL) {
|
|
509
|
+
return seterr(&ctx);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
res = PyUnicode_FromString(cp);
|
|
513
|
+
ndt_free(cp);
|
|
514
|
+
return res;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
static PyObject *
|
|
518
|
+
ndtype_pprint(PyObject *self, PyObject *args UNUSED)
|
|
519
|
+
{
|
|
520
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
521
|
+
char *cp;
|
|
522
|
+
|
|
523
|
+
cp = ndt_indent(NDT(self), &ctx);
|
|
524
|
+
if (cp == NULL) {
|
|
525
|
+
return seterr(&ctx);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
printf("%s\n", cp);
|
|
529
|
+
fflush(stdout);
|
|
530
|
+
|
|
531
|
+
ndt_free(cp);
|
|
532
|
+
Py_RETURN_NONE;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
static PyObject *
|
|
536
|
+
ndtype_ast_repr(PyObject *self, PyObject *args UNUSED)
|
|
537
|
+
{
|
|
538
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
539
|
+
PyObject *res;
|
|
540
|
+
char *cp;
|
|
541
|
+
|
|
542
|
+
cp = ndt_ast_repr(NDT(self), &ctx);
|
|
543
|
+
if (cp == NULL) {
|
|
544
|
+
return seterr(&ctx);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
res = PyUnicode_FromString(cp);
|
|
548
|
+
ndt_free(cp);
|
|
549
|
+
return res;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
static PyObject *
|
|
553
|
+
ndtype_copy(PyObject *self, PyObject *args UNUSED)
|
|
554
|
+
{
|
|
555
|
+
Py_INCREF(self);
|
|
556
|
+
return self;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
static PyObject *
|
|
560
|
+
ndtype_serialize(PyObject *self, PyObject *args UNUSED)
|
|
561
|
+
{
|
|
562
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
563
|
+
PyObject *res;
|
|
564
|
+
char *bytes;
|
|
565
|
+
int64_t size;
|
|
566
|
+
|
|
567
|
+
size = ndt_serialize(&bytes, NDT(self), &ctx);
|
|
568
|
+
if (size < 0) {
|
|
569
|
+
return seterr(&ctx);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
res = PyBytes_FromStringAndSize(bytes, (Py_ssize_t)size);
|
|
573
|
+
ndt_free(bytes);
|
|
574
|
+
return res;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
/******************************************************************************/
|
|
579
|
+
/* Ndt methods */
|
|
580
|
+
/******************************************************************************/
|
|
581
|
+
|
|
582
|
+
#define Ndtype_BoolFunc(NDTFUNC) \
|
|
583
|
+
static PyObject * \
|
|
584
|
+
ndtype_##NDTFUNC(PyObject *self, PyObject *args UNUSED) \
|
|
585
|
+
{ \
|
|
586
|
+
if (NDTFUNC(NDT(self))) { \
|
|
587
|
+
Py_RETURN_TRUE; \
|
|
588
|
+
} \
|
|
589
|
+
Py_RETURN_FALSE; \
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
Ndtype_BoolFunc(ndt_is_abstract)
|
|
593
|
+
Ndtype_BoolFunc(ndt_is_concrete)
|
|
594
|
+
|
|
595
|
+
Ndtype_BoolFunc(ndt_is_optional)
|
|
596
|
+
Ndtype_BoolFunc(ndt_is_scalar)
|
|
597
|
+
Ndtype_BoolFunc(ndt_is_signed)
|
|
598
|
+
Ndtype_BoolFunc(ndt_is_unsigned)
|
|
599
|
+
Ndtype_BoolFunc(ndt_is_float)
|
|
600
|
+
Ndtype_BoolFunc(ndt_is_complex)
|
|
601
|
+
|
|
602
|
+
Ndtype_BoolFunc(ndt_is_c_contiguous)
|
|
603
|
+
Ndtype_BoolFunc(ndt_is_f_contiguous)
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
static PyObject *
|
|
607
|
+
ndtype_richcompare(PyObject *self, PyObject *other, int op)
|
|
608
|
+
{
|
|
609
|
+
int r = 0;
|
|
610
|
+
|
|
611
|
+
assert(Ndt_Check(self));
|
|
612
|
+
|
|
613
|
+
if (Ndt_Check(other)) {
|
|
614
|
+
r = ndt_equal(NDT(self), NDT(other));
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
switch (op) {
|
|
618
|
+
case Py_EQ:
|
|
619
|
+
return PyBool_FromLong(r);
|
|
620
|
+
case Py_NE:
|
|
621
|
+
return PyBool_FromLong(!r);
|
|
622
|
+
default:
|
|
623
|
+
Py_RETURN_NOTIMPLEMENTED;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
static Py_hash_t
|
|
628
|
+
ndtype_hash(PyObject *self)
|
|
629
|
+
{
|
|
630
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
631
|
+
Py_hash_t res;
|
|
632
|
+
|
|
633
|
+
res = ndt_hash(NDT(self), &ctx);
|
|
634
|
+
if (res == -1) {
|
|
635
|
+
(void)seterr(&ctx);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return res;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
static PyObject *
|
|
642
|
+
ndtype_match(PyObject *self, PyObject *other)
|
|
643
|
+
{
|
|
644
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
645
|
+
int res;
|
|
646
|
+
|
|
647
|
+
if (!Ndt_Check(other)) {
|
|
648
|
+
PyErr_SetString(PyExc_TypeError, "argument must be 'ndt'");
|
|
649
|
+
return NULL;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
res = ndt_match(NDT(self), NDT(other), &ctx);
|
|
653
|
+
if (res == -1) {
|
|
654
|
+
return seterr(&ctx);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
return PyBool_FromLong(res);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
static PyObject *
|
|
661
|
+
ndtype_apply(PyObject *self, PyObject *args)
|
|
662
|
+
{
|
|
663
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
664
|
+
ndt_t *sig = NDT(self);
|
|
665
|
+
const ndt_t *in[NDT_MAX_ARGS];
|
|
666
|
+
ndt_apply_spec_t spec;
|
|
667
|
+
PyObject *flags = NULL, *out = NULL, *broadcast = NULL, *outer_dims = NULL;
|
|
668
|
+
PyObject *res = NULL;
|
|
669
|
+
Py_ssize_t nin;
|
|
670
|
+
Py_ssize_t i;
|
|
671
|
+
|
|
672
|
+
if (!PyTuple_Check(args) && !PyList_Check(args)) {
|
|
673
|
+
PyErr_SetString(PyExc_TypeError, "arguments must be a tuple or a list");
|
|
674
|
+
return NULL;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
nin = PySequence_Fast_GET_SIZE(args);
|
|
678
|
+
if (nin > NDT_MAX_ARGS) {
|
|
679
|
+
PyErr_Format(PyExc_ValueError,
|
|
680
|
+
"maximum number of arguments is %d", NDT_MAX_ARGS);
|
|
681
|
+
return NULL;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
for (i = 0; i < nin; i++) {
|
|
685
|
+
PyObject *tmp = PySequence_Fast_GET_ITEM(args, i);
|
|
686
|
+
if (!Ndt_Check(tmp)) {
|
|
687
|
+
PyErr_Format(PyExc_TypeError, "argument types must be ndt");
|
|
688
|
+
return NULL;
|
|
689
|
+
}
|
|
690
|
+
in[i] = CONST_NDT(tmp);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
spec = ndt_apply_spec_empty;
|
|
694
|
+
if (ndt_typecheck(&spec, sig, in, (int)nin, NULL, NULL, &ctx) < 0) {
|
|
695
|
+
return seterr(&ctx);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
flags = PyUnicode_FromString(ndt_apply_flags_as_string(&spec));
|
|
699
|
+
if (flags == NULL) {
|
|
700
|
+
return NULL;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
out = PyList_New(spec.nout);
|
|
704
|
+
if (out == NULL) {
|
|
705
|
+
ndt_apply_spec_clear(&spec);
|
|
706
|
+
goto finish;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
for (i=spec.nout-1; i >= 0; i--) {
|
|
710
|
+
PyObject *x = ndtype_alloc(&Ndt_Type);
|
|
711
|
+
if (x == NULL) {
|
|
712
|
+
ndt_apply_spec_clear(&spec);
|
|
713
|
+
goto finish;
|
|
714
|
+
}
|
|
715
|
+
NDT(x) = spec.out[i];
|
|
716
|
+
spec.out[i] = NULL; spec.nout--;
|
|
717
|
+
PyList_SET_ITEM(out, i, x);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
broadcast = PyList_New(spec.nbroadcast);
|
|
721
|
+
if (broadcast == NULL) {
|
|
722
|
+
ndt_apply_spec_clear(&spec);
|
|
723
|
+
goto finish;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
for (i=spec.nbroadcast-1; i >= 0; i--) {
|
|
727
|
+
PyObject *x = ndtype_alloc(&Ndt_Type);
|
|
728
|
+
if (x == NULL) {
|
|
729
|
+
ndt_apply_spec_clear(&spec);
|
|
730
|
+
goto finish;
|
|
731
|
+
}
|
|
732
|
+
NDT(x) = spec.broadcast[i];
|
|
733
|
+
spec.broadcast[i] = NULL; spec.nbroadcast--;
|
|
734
|
+
PyList_SET_ITEM(broadcast, i, x);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
outer_dims = PyLong_FromLong(spec.outer_dims);
|
|
738
|
+
if (outer_dims == NULL) {
|
|
739
|
+
goto finish;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
res = PyObject_CallFunctionObjArgs((PyObject *)ApplySpec, flags, self,
|
|
743
|
+
args, broadcast, out, outer_dims, NULL);
|
|
744
|
+
|
|
745
|
+
finish:
|
|
746
|
+
Py_XDECREF(flags);
|
|
747
|
+
Py_XDECREF(out);
|
|
748
|
+
Py_XDECREF(broadcast);
|
|
749
|
+
Py_XDECREF(outer_dims);
|
|
750
|
+
return res;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
static PyObject *
|
|
754
|
+
tuple_from_int64(int64_t x[NDT_MAX_DIM], int ndim)
|
|
755
|
+
{
|
|
756
|
+
PyObject *tuple;
|
|
757
|
+
int i;
|
|
758
|
+
|
|
759
|
+
tuple = PyTuple_New(ndim);
|
|
760
|
+
if (tuple == NULL) {
|
|
761
|
+
return NULL;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
for (i = 0; i < ndim; i++) {
|
|
765
|
+
PyObject *v = PyLong_FromLongLong(x[i]);
|
|
766
|
+
if (v == NULL) {
|
|
767
|
+
Py_DECREF(tuple);
|
|
768
|
+
return NULL;
|
|
769
|
+
}
|
|
770
|
+
PyTuple_SET_ITEM(tuple, i, v);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
return tuple;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
static PyObject *
|
|
777
|
+
ndtype_ndim(PyObject *self, PyObject *args UNUSED)
|
|
778
|
+
{
|
|
779
|
+
const ndt_t *t = NDT(self);
|
|
780
|
+
|
|
781
|
+
if (ndt_is_abstract(t)) {
|
|
782
|
+
PyErr_SetString(PyExc_TypeError,
|
|
783
|
+
"abstract type has no ndim");
|
|
784
|
+
return NULL;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
return PyLong_FromLong(t->ndim);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
static PyObject *
|
|
791
|
+
ndtype_datasize(PyObject *self, PyObject *args UNUSED)
|
|
792
|
+
{
|
|
793
|
+
const ndt_t *t = NDT(self);
|
|
794
|
+
|
|
795
|
+
if (ndt_is_abstract(t)) {
|
|
796
|
+
PyErr_SetString(PyExc_TypeError,
|
|
797
|
+
"abstract type has no datasize");
|
|
798
|
+
return NULL;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
return PyLong_FromLongLong(t->datasize);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
static PyObject *
|
|
805
|
+
ndtype_itemsize(PyObject *self, PyObject *args UNUSED)
|
|
806
|
+
{
|
|
807
|
+
const ndt_t *t = NDT(self);
|
|
808
|
+
int64_t size;
|
|
809
|
+
|
|
810
|
+
if (ndt_is_abstract(t)) {
|
|
811
|
+
PyErr_SetString(PyExc_TypeError,
|
|
812
|
+
"abstract type has no itemsize");
|
|
813
|
+
return NULL;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
switch (t->tag) {
|
|
817
|
+
case FixedDim:
|
|
818
|
+
size = t->Concrete.FixedDim.itemsize;
|
|
819
|
+
break;
|
|
820
|
+
case VarDim:
|
|
821
|
+
size = t->Concrete.VarDim.itemsize;
|
|
822
|
+
break;
|
|
823
|
+
default:
|
|
824
|
+
size = t->datasize;
|
|
825
|
+
break;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
return PyLong_FromLongLong(size);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
static PyObject *
|
|
832
|
+
ndtype_shape(PyObject *self, PyObject *args UNUSED)
|
|
833
|
+
{
|
|
834
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
835
|
+
ndt_ndarray_t x;
|
|
836
|
+
|
|
837
|
+
if (ndt_as_ndarray(&x, NDT(self), &ctx) < 0) {
|
|
838
|
+
return seterr(&ctx);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
return tuple_from_int64(x.shape, x.ndim);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
static PyObject *
|
|
845
|
+
ndtype_strides(PyObject *self, PyObject *args UNUSED)
|
|
846
|
+
{
|
|
847
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
848
|
+
ndt_ndarray_t x;
|
|
849
|
+
|
|
850
|
+
if (ndt_as_ndarray(&x, NDT(self), &ctx) < 0) {
|
|
851
|
+
return seterr(&ctx);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
return tuple_from_int64(x.strides, x.ndim);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
static PyObject *
|
|
858
|
+
ndtype_hidden_dtype(PyObject *self, PyObject *args UNUSED)
|
|
859
|
+
{
|
|
860
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
861
|
+
const ndt_t *t = NDT(self);
|
|
862
|
+
const ndt_t *dtype;
|
|
863
|
+
ndt_t *u;
|
|
864
|
+
|
|
865
|
+
dtype = ndt_hidden_dtype(t);
|
|
866
|
+
|
|
867
|
+
u = ndt_copy(dtype, &ctx);
|
|
868
|
+
if (u == NULL) {
|
|
869
|
+
return seterr(&ctx);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
return Ndt_FromType(u);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
static PyObject *
|
|
876
|
+
ndtype_align(PyObject *self, PyObject *args UNUSED)
|
|
877
|
+
{
|
|
878
|
+
if (ndt_is_abstract(NDT(self))) {
|
|
879
|
+
PyErr_SetString(PyExc_TypeError,
|
|
880
|
+
"abstract type has no alignment");
|
|
881
|
+
return NULL;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
return PyLong_FromLong(NDT(self)->align);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
static PyObject *
|
|
888
|
+
ndtype_reduce(PyObject *self, PyObject *args UNUSED)
|
|
889
|
+
{
|
|
890
|
+
PyObject *bytes;
|
|
891
|
+
PyObject *res;
|
|
892
|
+
|
|
893
|
+
bytes = ndtype_serialize(self, NULL);
|
|
894
|
+
if (bytes == NULL) {
|
|
895
|
+
return NULL;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
res = Py_BuildValue("O(O)", Deserialize, bytes);
|
|
899
|
+
Py_DECREF(bytes);
|
|
900
|
+
|
|
901
|
+
return res;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
static PyObject *
|
|
905
|
+
ndtype_to_nbformat(PyObject *self, PyObject *args UNUSED)
|
|
906
|
+
{
|
|
907
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
908
|
+
PyObject *sig;
|
|
909
|
+
PyObject *core;
|
|
910
|
+
PyObject *ret;
|
|
911
|
+
char *s;
|
|
912
|
+
char *c;
|
|
913
|
+
|
|
914
|
+
if (ndt_to_nbformat(&s, &c, NDT(self), &ctx) < 0) {
|
|
915
|
+
return seterr(&ctx);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
sig = PyUnicode_FromString(s);
|
|
919
|
+
ndt_free(s);
|
|
920
|
+
if (s == NULL) {
|
|
921
|
+
ndt_free(c);
|
|
922
|
+
return NULL;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
core = PyUnicode_FromString(c);
|
|
926
|
+
ndt_free(c);
|
|
927
|
+
if (s == NULL) {
|
|
928
|
+
Py_DECREF(sig);
|
|
929
|
+
return NULL;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
ret = PyTuple_New(2);
|
|
933
|
+
if (ret == NULL) {
|
|
934
|
+
Py_DECREF(sig);
|
|
935
|
+
Py_DECREF(core);
|
|
936
|
+
return NULL;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
PyTuple_SET_ITEM(ret, 0, sig);
|
|
940
|
+
PyTuple_SET_ITEM(ret, 1, core);
|
|
941
|
+
|
|
942
|
+
return ret;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
static PyGetSetDef ndtype_getsets [] =
|
|
947
|
+
{
|
|
948
|
+
{ "align", (getter)ndtype_align, NULL, doc_align, NULL},
|
|
949
|
+
{ "datasize", (getter)ndtype_datasize, NULL, doc_datasize, NULL},
|
|
950
|
+
{ "itemsize", (getter)ndtype_itemsize, NULL, doc_itemsize, NULL},
|
|
951
|
+
{ "ndim", (getter)ndtype_ndim, NULL, doc_ndim, NULL},
|
|
952
|
+
{ "shape", (getter)ndtype_shape, NULL, doc_shape, NULL},
|
|
953
|
+
{ "strides", (getter)ndtype_strides, NULL, doc_strides, NULL},
|
|
954
|
+
{ "hidden_dtype", (getter)ndtype_hidden_dtype, NULL, doc_strides, NULL},
|
|
955
|
+
{NULL}
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
static PyMethodDef ndtype_methods [] =
|
|
959
|
+
{
|
|
960
|
+
/* Boolean functions */
|
|
961
|
+
{ "isoptional", (PyCFunction)ndtype_ndt_is_optional, METH_NOARGS, doc_isoptional },
|
|
962
|
+
{ "isabstract", (PyCFunction)ndtype_ndt_is_abstract, METH_NOARGS, doc_isabstract },
|
|
963
|
+
{ "isconcrete", (PyCFunction)ndtype_ndt_is_concrete, METH_NOARGS, doc_isconcrete },
|
|
964
|
+
{ "isscalar", (PyCFunction)ndtype_ndt_is_scalar, METH_NOARGS, doc_isscalar },
|
|
965
|
+
{ "issigned", (PyCFunction)ndtype_ndt_is_signed, METH_NOARGS, doc_issigned },
|
|
966
|
+
{ "isunsigned", (PyCFunction)ndtype_ndt_is_unsigned, METH_NOARGS, doc_isunsigned },
|
|
967
|
+
{ "isfloat", (PyCFunction)ndtype_ndt_is_float, METH_NOARGS, doc_isfloat },
|
|
968
|
+
{ "iscomplex", (PyCFunction)ndtype_ndt_is_complex, METH_NOARGS, doc_iscomplex },
|
|
969
|
+
|
|
970
|
+
/* Boolean functions on array types */
|
|
971
|
+
{ "is_c_contiguous", (PyCFunction)ndtype_ndt_is_c_contiguous, METH_NOARGS, doc_is_c_contiguous },
|
|
972
|
+
{ "is_f_contiguous", (PyCFunction)ndtype_ndt_is_f_contiguous, METH_NOARGS, doc_is_f_contiguous },
|
|
973
|
+
|
|
974
|
+
/* Binary functions */
|
|
975
|
+
{ "match", (PyCFunction)ndtype_match, METH_O, doc_match },
|
|
976
|
+
{ "apply", (PyCFunction)ndtype_apply, METH_O, "method likely to change" },
|
|
977
|
+
|
|
978
|
+
/* Other functions */
|
|
979
|
+
{ "to_format", (PyCFunction)ndtype_to_format, METH_NOARGS, NULL },
|
|
980
|
+
{ "to_nbformat", (PyCFunction)ndtype_to_nbformat, METH_NOARGS, NULL },
|
|
981
|
+
{ "pformat", (PyCFunction)ndtype_pformat, METH_NOARGS, doc_pformat },
|
|
982
|
+
{ "pprint", (PyCFunction)ndtype_pprint, METH_NOARGS, doc_pprint },
|
|
983
|
+
{ "ast_repr", (PyCFunction)ndtype_ast_repr, METH_NOARGS, doc_ast_repr },
|
|
984
|
+
{ "serialize", (PyCFunction)ndtype_serialize, METH_NOARGS, doc_serialize },
|
|
985
|
+
|
|
986
|
+
/* Class methods */
|
|
987
|
+
{ "from_format", (PyCFunction)ndtype_from_format, METH_O|METH_CLASS, doc_from_format },
|
|
988
|
+
{ "deserialize", (PyCFunction)ndtype_deserialize, METH_O|METH_CLASS, doc_deserialize },
|
|
989
|
+
|
|
990
|
+
/* Special methods */
|
|
991
|
+
{ "__copy__", ndtype_copy, METH_NOARGS, NULL },
|
|
992
|
+
{ "__deepcopy__", ndtype_copy, METH_O, NULL },
|
|
993
|
+
{ "__reduce__", ndtype_reduce, METH_NOARGS, NULL },
|
|
994
|
+
|
|
995
|
+
{ NULL, NULL, 1 }
|
|
996
|
+
};
|
|
997
|
+
|
|
998
|
+
static PyTypeObject Ndt_Type =
|
|
999
|
+
{
|
|
1000
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1001
|
+
.tp_name = "ndtypes.ndt",
|
|
1002
|
+
.tp_basicsize = sizeof(NdtObject),
|
|
1003
|
+
.tp_dealloc = (destructor) ndtype_dealloc,
|
|
1004
|
+
.tp_repr = (reprfunc) ndtype_repr,
|
|
1005
|
+
.tp_hash = ndtype_hash,
|
|
1006
|
+
.tp_str = (reprfunc) ndtype_str,
|
|
1007
|
+
.tp_getattro = (getattrofunc) PyObject_GenericGetAttr,
|
|
1008
|
+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
|
|
1009
|
+
.tp_traverse = (traverseproc)ndtype_traverse,
|
|
1010
|
+
.tp_richcompare = ndtype_richcompare,
|
|
1011
|
+
.tp_methods = ndtype_methods,
|
|
1012
|
+
.tp_getset = ndtype_getsets,
|
|
1013
|
+
.tp_alloc = PyType_GenericAlloc,
|
|
1014
|
+
.tp_new = ndtype_new,
|
|
1015
|
+
.tp_free = PyObject_GC_Del
|
|
1016
|
+
};
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
/****************************************************************************/
|
|
1020
|
+
/* C-API */
|
|
1021
|
+
/****************************************************************************/
|
|
1022
|
+
|
|
1023
|
+
static void **ndtypes_api[NDTYPES_MAX_API];
|
|
1024
|
+
|
|
1025
|
+
static int
|
|
1026
|
+
Ndt_CheckExact(const PyObject *v)
|
|
1027
|
+
{
|
|
1028
|
+
return Py_TYPE(v) == &Ndt_Type;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
static int
|
|
1032
|
+
Ndt_Check(const PyObject *v)
|
|
1033
|
+
{
|
|
1034
|
+
return PyObject_TypeCheck(v, &Ndt_Type);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
static const ndt_t *
|
|
1038
|
+
CONST_NDT(const PyObject *v)
|
|
1039
|
+
{
|
|
1040
|
+
assert(Ndt_Check(v));
|
|
1041
|
+
return ((NdtObject *)v)->ndt;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
static PyObject *
|
|
1045
|
+
Ndt_SetError(ndt_context_t *ctx)
|
|
1046
|
+
{
|
|
1047
|
+
return seterr(ctx);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
static PyObject *
|
|
1051
|
+
Ndt_CopySubtree(const PyObject *src, const ndt_t *t)
|
|
1052
|
+
{
|
|
1053
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
1054
|
+
PyObject *dest;
|
|
1055
|
+
|
|
1056
|
+
if (!Ndt_Check(src)) {
|
|
1057
|
+
PyErr_SetString(PyExc_TypeError, "expected ndt object");
|
|
1058
|
+
return NULL;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
dest = ndtype_alloc(Py_TYPE(src));
|
|
1062
|
+
if (dest == NULL) {
|
|
1063
|
+
return NULL;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
NDT(dest) = ndt_copy(t, &ctx);
|
|
1067
|
+
if (NDT(dest) == NULL) {
|
|
1068
|
+
return seterr(&ctx);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
RBUF(dest) = RBUF(src);
|
|
1072
|
+
Py_XINCREF(RBUF(dest));
|
|
1073
|
+
|
|
1074
|
+
return dest;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
static PyObject *
|
|
1078
|
+
Ndt_MoveSubtree(const PyObject *src, ndt_t *t)
|
|
1079
|
+
{
|
|
1080
|
+
PyObject *dest;
|
|
1081
|
+
|
|
1082
|
+
if (!Ndt_Check(src)) {
|
|
1083
|
+
PyErr_SetString(PyExc_TypeError, "expected ndt object");
|
|
1084
|
+
return NULL;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
dest = ndtype_alloc(Py_TYPE(src));
|
|
1088
|
+
if (dest == NULL) {
|
|
1089
|
+
ndt_del(t);
|
|
1090
|
+
return NULL;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
NDT(dest) = t;
|
|
1094
|
+
RBUF(dest) = RBUF(src);
|
|
1095
|
+
Py_XINCREF(RBUF(dest));
|
|
1096
|
+
|
|
1097
|
+
return dest;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
static PyObject *
|
|
1101
|
+
Ndt_FromType(ndt_t *type)
|
|
1102
|
+
{
|
|
1103
|
+
PyObject *self;
|
|
1104
|
+
|
|
1105
|
+
self = ndtype_alloc(&Ndt_Type);
|
|
1106
|
+
if (self == NULL) {
|
|
1107
|
+
ndt_del(type);
|
|
1108
|
+
return NULL;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
NDT(self) = type;
|
|
1112
|
+
return self;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
static PyObject *
|
|
1116
|
+
Ndt_FromObject(PyObject *obj)
|
|
1117
|
+
{
|
|
1118
|
+
return ndtype_from_object(&Ndt_Type, obj);
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
static PyObject *
|
|
1122
|
+
init_api(void)
|
|
1123
|
+
{
|
|
1124
|
+
ndtypes_api[Ndt_CheckExact_INDEX] = (void *)Ndt_CheckExact;
|
|
1125
|
+
ndtypes_api[Ndt_Check_INDEX] = (void *)Ndt_Check;
|
|
1126
|
+
ndtypes_api[CONST_NDT_INDEX] = (void *)CONST_NDT;
|
|
1127
|
+
ndtypes_api[Ndt_SetError_INDEX] = (void *)Ndt_SetError;
|
|
1128
|
+
ndtypes_api[Ndt_CopySubtree_INDEX] = (void *)Ndt_CopySubtree;
|
|
1129
|
+
ndtypes_api[Ndt_MoveSubtree_INDEX] = (void *)Ndt_MoveSubtree;
|
|
1130
|
+
ndtypes_api[Ndt_FromType_INDEX] = (void *)Ndt_FromType;
|
|
1131
|
+
ndtypes_api[Ndt_FromObject_INDEX] = (void *)Ndt_FromObject;
|
|
1132
|
+
|
|
1133
|
+
return PyCapsule_New(ndtypes_api, "ndtypes._ndtypes._API", NULL);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
/****************************************************************************/
|
|
1138
|
+
/* Module */
|
|
1139
|
+
/****************************************************************************/
|
|
1140
|
+
|
|
1141
|
+
static PyObject *
|
|
1142
|
+
ndtype_typedef(PyObject *mod UNUSED, PyObject *args, PyObject *kwds)
|
|
1143
|
+
{
|
|
1144
|
+
static char *kwlist[] = {"name", "type", NULL};
|
|
1145
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
1146
|
+
PyObject *name, *type;
|
|
1147
|
+
const char *cname, *ctype;
|
|
1148
|
+
ndt_t *t;
|
|
1149
|
+
|
|
1150
|
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &name, &type)) {
|
|
1151
|
+
return NULL;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
cname = PyUnicode_AsUTF8(name);
|
|
1155
|
+
if (cname == NULL) {
|
|
1156
|
+
return NULL;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
ctype = PyUnicode_AsUTF8(type);
|
|
1160
|
+
if (ctype == NULL) {
|
|
1161
|
+
return NULL;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
t = ndt_from_string(ctype, &ctx);
|
|
1165
|
+
if (t == NULL) {
|
|
1166
|
+
return seterr(&ctx);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
if (ndt_typedef(cname, t, NULL, &ctx) < 0) {
|
|
1170
|
+
return seterr(&ctx);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
Py_RETURN_NONE;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
static PyObject *
|
|
1177
|
+
ndtype_instantiate(PyObject *mod UNUSED, PyObject *args, PyObject *kwds)
|
|
1178
|
+
{
|
|
1179
|
+
static char *kwlist[] = {"name", "type", NULL};
|
|
1180
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
1181
|
+
PyObject *name, *type;
|
|
1182
|
+
const char *cname;
|
|
1183
|
+
char *cp;
|
|
1184
|
+
ndt_t *t, *tp;
|
|
1185
|
+
|
|
1186
|
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &name, &type)) {
|
|
1187
|
+
return NULL;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
cname = PyUnicode_AsUTF8(name);
|
|
1191
|
+
if (cname == NULL) {
|
|
1192
|
+
return NULL;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
if (!Ndt_Check(type)) {
|
|
1196
|
+
PyErr_SetString(PyExc_TypeError, "type argument must be ndt");
|
|
1197
|
+
return NULL;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
cp = ndt_strdup(cname, &ctx);
|
|
1201
|
+
if (cp == NULL) {
|
|
1202
|
+
return seterr(&ctx);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
tp = ndt_copy(NDT(type), &ctx);
|
|
1206
|
+
if (tp == NULL) {
|
|
1207
|
+
ndt_free(cp);
|
|
1208
|
+
return seterr(&ctx);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
t = ndt_nominal(cp, tp, &ctx);
|
|
1212
|
+
if (t == NULL) {
|
|
1213
|
+
return seterr(&ctx);
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
return Ndt_MoveSubtree(type, t);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
static PyMethodDef _ndtypes_methods [] =
|
|
1220
|
+
{
|
|
1221
|
+
{ "typedef", (PyCFunction)ndtype_typedef, METH_VARARGS|METH_KEYWORDS, NULL},
|
|
1222
|
+
{ "instantiate", (PyCFunction)ndtype_instantiate, METH_VARARGS|METH_KEYWORDS, NULL},
|
|
1223
|
+
{ NULL, NULL, 1, NULL }
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
static struct PyModuleDef ndtypes_module = {
|
|
1228
|
+
PyModuleDef_HEAD_INIT, /* m_base */
|
|
1229
|
+
"_ndtypes", /* m_name */
|
|
1230
|
+
doc_module, /* m_doc */
|
|
1231
|
+
-1, /* m_size */
|
|
1232
|
+
_ndtypes_methods, /* m_methods */
|
|
1233
|
+
NULL, /* m_slots */
|
|
1234
|
+
NULL, /* m_traverse */
|
|
1235
|
+
NULL, /* m_clear */
|
|
1236
|
+
NULL /* m_free */
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
PyMODINIT_FUNC
|
|
1241
|
+
PyInit__ndtypes(void)
|
|
1242
|
+
{
|
|
1243
|
+
NDT_STATIC_CONTEXT(ctx);
|
|
1244
|
+
PyObject *m = NULL;
|
|
1245
|
+
PyObject *collections = NULL;
|
|
1246
|
+
PyObject *obj = NULL;
|
|
1247
|
+
static PyObject *capsule = NULL;
|
|
1248
|
+
static int initialized = 0;
|
|
1249
|
+
|
|
1250
|
+
if (!initialized) {
|
|
1251
|
+
capsule = init_api();
|
|
1252
|
+
if (capsule == NULL) {
|
|
1253
|
+
return NULL;
|
|
1254
|
+
}
|
|
1255
|
+
if (ndt_init(&ctx) < 0) {
|
|
1256
|
+
return seterr(&ctx);
|
|
1257
|
+
}
|
|
1258
|
+
initialized = 1;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
if (PyType_Ready(&ResourceBuffer_Type) < 0) {
|
|
1262
|
+
goto error;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
Ndt_Type.tp_base = &PyBaseObject_Type;
|
|
1266
|
+
if (PyType_Ready(&Ndt_Type) < 0) {
|
|
1267
|
+
goto error;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/* ApplySpec */
|
|
1271
|
+
collections = PyImport_ImportModule("collections");
|
|
1272
|
+
if (collections == NULL) {
|
|
1273
|
+
goto error;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
ApplySpec = (PyTypeObject *)PyObject_CallMethod(collections,
|
|
1277
|
+
"namedtuple", "(ss)", "ApplySpec",
|
|
1278
|
+
"flags sig in_types in_broadcast out_types outer_dims");
|
|
1279
|
+
if (ApplySpec == NULL) {
|
|
1280
|
+
goto error;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
obj = PyUnicode_FromString("ndtypes");
|
|
1284
|
+
if (obj == NULL) {
|
|
1285
|
+
goto error;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
if (PyDict_SetItemString(ApplySpec->tp_dict, "__module__", obj) < 0) {
|
|
1289
|
+
goto error;
|
|
1290
|
+
}
|
|
1291
|
+
Py_CLEAR(obj);
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
m = PyModule_Create(&ndtypes_module);
|
|
1295
|
+
if (m == NULL) {
|
|
1296
|
+
goto error;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
Deserialize = PyObject_GetAttrString((PyObject *)&Ndt_Type, "deserialize");
|
|
1300
|
+
if (Deserialize == NULL) {
|
|
1301
|
+
goto error;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
Py_INCREF(&Ndt_Type);
|
|
1305
|
+
if (PyModule_AddObject(m, "ndt", (PyObject *)&Ndt_Type) < 0) {
|
|
1306
|
+
goto error;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
Py_INCREF(ApplySpec);
|
|
1310
|
+
if (PyModule_AddObject(m, "ApplySpec", (PyObject *)ApplySpec) < 0) {
|
|
1311
|
+
goto error;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
if (PyModule_AddIntConstant(m, "MAX_DIM", NDT_MAX_DIM) < 0) {
|
|
1315
|
+
goto error;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
Py_INCREF(capsule);
|
|
1319
|
+
if (PyModule_AddObject(m, "_API", capsule) < 0) {
|
|
1320
|
+
goto error;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
return m;
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
error:
|
|
1328
|
+
Py_CLEAR(m);
|
|
1329
|
+
return NULL;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
|