Skip to content

Commit 51cdda5

Browse files
Merge pull request #707 from insertinterestingnamehere/type_constructor_removal
Remove calls to type constructors removed in libdynd
2 parents ea4a43a + df93d00 commit 51cdda5

10 files changed

Lines changed: 123 additions & 70 deletions

dynd/cpp/type.pxd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,13 @@ cdef extern from 'dynd/type.hpp' namespace 'dynd::ndt' nogil:
3636
type_id_t get_base_id() const
3737

3838
type make_type[T]() except +translate_exception
39+
40+
cppclass reg_info_t:
41+
type tp
42+
43+
# Ideally we wouldn't use the detail namespace, but this is currently
44+
# needed to map a type id back to the corresponding type.
45+
cdef extern from "<dynd/type.hpp>" nogil:
46+
# Function doesn't really exist.
47+
# Use this to avoid Cython's odd handling of lvalue references
48+
reg_info_t _get_reg_info "dynd::ndt::detail::infos().operator[]"(type_id_t) except +translate_exception

dynd/include/array_conversions.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
//
2+
// Copyright (C) 2011-16 DyND Developers
3+
// BSD 2-Clause License, see LICENSE.txt
4+
//
5+
6+
/* This file exists to expose whatever functionality from
7+
* nd/array.pyx and nd/callable.pyx needs to be available
8+
* in the C++ portions of the codebase.
9+
* Currently it exists only as a means of
10+
* exporting conversions between the Cython wrapper
11+
* types and their corresponding C++ types.
12+
* Those conversions must be exported from Cython
13+
* to the C++ code since the ABI for the wrapper types
14+
* must be defined there (and depends on Cython's ABI for
15+
* extension types).
16+
*
17+
* The conversions defined here lazily load the modules
18+
* that expose the core ABI for the wrapper types.
19+
*/
20+
121
#pragma once
222

323
#include <Python.h>

dynd/include/type_conversions.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
//
2-
// Copyright (C) 2011-15 DyND Developers
2+
// Copyright (C) 2011-16 DyND Developers
33
// BSD 2-Clause License, see LICENSE.txt
44
//
5+
6+
/* This file exists to expose whatever functionality from
7+
* ndt/type.pyx needs to be available throughout the
8+
* C++ codebase. Currently it exists only as a means
9+
* of providing conversions between the Cython wrapper
10+
* types and their corresponding C++ types.
11+
* Those conversions must be exported from Cython
12+
* to the C++ code since the ABI for the wrapper types
13+
* must be defined there (and depends on Cython's ABI for
14+
* extension types).
15+
*
16+
* The conversions defined here lazily load the modules
17+
* that expose the core ABI for the wrapper types.
18+
*/
19+
520
#pragma once
621

722
#include <Python.h>
@@ -17,6 +32,5 @@ PYDYND_API PyTypeObject *get_type_pytypeobject();
1732
PYDYND_API PyObject *type_from_cpp(const dynd::ndt::type &);
1833
PYDYND_API dynd::ndt::type dynd_ndt_as_cpp_type(PyObject *);
1934
PYDYND_API dynd::ndt::type dynd_ndt_cpp_type_for(PyObject *);
20-
PYDYND_API dynd::ndt::type ndt_type_from_pylist(PyObject *);
2135

2236
} // namespace pydynd

dynd/include/type_deduction.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,6 @@ void register_nd_array_type_deduction(PyTypeObject *, dynd::ndt::type (*)(PyObje
161161

162162
PYDYND_API dynd::ndt::type xtype_for_prefix(PyObject *obj);
163163

164+
PYDYND_API dynd::ndt::type ndt_type_from_pylist(PyObject *);
165+
164166
} // namespace pydynd

dynd/ndt/__init__.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,6 @@ def load_dynd_dll(rootpath):
5757
type_for
5858
from .type import *
5959

60-
intptr = type('intptr')
61-
uintptr = type('uintptr')
62-
# Aliases for people comfortable with the NumPy complex namings
63-
complex64 = complex_float32
64-
complex128 = complex_float64
65-
66-
string = type('string')
67-
#json = type('json')
68-
bytes = type('bytes')
69-
7060
# Some classes making dimension construction easier
7161
from .dim_helpers import *
7262

dynd/ndt/type.pyx

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ from cpython.object cimport Py_EQ, Py_NE, PyObject, PyTypeObject
44
from libc.stdint cimport (intptr_t, int8_t, int16_t, int32_t, int64_t,
55
uint8_t, uint16_t, uint32_t, uint64_t)
66
from libcpp.map cimport map
7-
from libcpp.string cimport string
7+
from libcpp.string cimport string as cpp_string
88
from libcpp.vector cimport vector
99
from libcpp.pair cimport pair
1010
from libcpp cimport bool as cpp_bool
@@ -33,7 +33,7 @@ from ..cpp.types.callable_type cimport callable_type as _callable_type
3333
from ..cpp.types.string_type cimport string_type
3434
from ..cpp.types.bytes_type cimport bytes_type
3535
from ..cpp.types.fixed_bytes_type cimport fixed_bytes_type
36-
from ..cpp.type cimport make_type
36+
from ..cpp.type cimport make_type, _get_reg_info
3737
from ..cpp.complex cimport complex as dynd_complex
3838

3939
from ..config cimport translate_exception
@@ -61,7 +61,7 @@ cdef extern from "type_conversions.hpp" namespace 'pydynd':
6161
cdef extern from 'type_functions.hpp' namespace 'pydynd':
6262
object _type_get_shape(_type&) except +translate_exception
6363
object _type_get_id(_type&) except +translate_exception
64-
string _type_str(_type &)
64+
cpp_string _type_str(_type &)
6565

6666
_type dynd_make_fixed_string_type(int, object) except +translate_exception
6767
_type dynd_make_string_type() except +translate_exception
@@ -97,11 +97,14 @@ init_type_functions()
9797
numpy_interop_init()
9898
_builtin_type = __builtins__.type
9999
_builtin_bool = __builtins__.bool
100+
_builtin_bytes = __builtins__.bytes
100101

101-
__all__ = ['type_ids', 'type', 'bool', 'int8', 'int16', 'int32', 'int64', 'int128', \
102-
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'float16', 'float32', \
103-
'float64', 'float128', 'complex_float32', 'complex_float64', 'void', \
104-
'tuple', 'struct', 'callable', 'scalar', 'astype']
102+
__all__ = ['type_ids', 'type', 'bool', 'int8', 'int16', 'int32', 'int64', 'int128',
103+
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'float16', 'float32',
104+
'float64', 'float128', 'complex64', 'complex_float32',
105+
'complex128', 'complex_float64', 'void', 'intptr', 'uintptr', 'string',
106+
'bytes', 'tuple', 'struct', 'callable',
107+
'scalar', 'astype']
105108

106109
type_ids = {}
107110
type_ids['UNINITIALIZED'] = uninitialized_id
@@ -383,7 +386,7 @@ cdef _type cpp_type_from_typeobject(object o) except *:
383386
return make_type[dynd_complex[double]]()
384387
elif o is str or o is unicode:
385388
return make_type[string_type]()
386-
elif o is bytes:
389+
elif o is _builtin_bytes:
387390
return make_type[bytes_type]()
388391
elif o is bytearray:
389392
return make_type[bytes_type]()
@@ -398,12 +401,10 @@ cdef _type as_cpp_type(object o) except *:
398401
return dynd_ndt_type_to_cpp(<type>o)
399402
elif _builtin_type(o) is str or PyUnicode_Check(<PyObject*>o):
400403
# Use Cython's automatic conversion to c++ strings.
401-
return _type(<string>o)
402-
elif _builtin_type(o) is int or _builtin_type(o) is long:
403-
return _type(<type_id_t>(<int>o))
404+
return _type(<cpp_string>o)
404405
elif is_numpy_dtype(<PyObject*>o):
405406
return _type_from_numpy_dtype(<PyArray_Descr*>o)
406-
elif issubclass(o, _ctypes_base_type):
407+
elif _builtin_type(o) is _builtin_type and issubclass(o, _ctypes_base_type):
407408
raise ValueError("Conversion from ctypes type to DyND type not currently supported.")
408409
elif PyType_Check(<PyObject*>o):
409410
return cpp_type_from_typeobject(o)
@@ -596,24 +597,33 @@ def make_var_dim(element_tp):
596597
result.v = make_type[_var_dim_type](as_cpp_type(element_tp))
597598
return result
598599

599-
bool = type(bool_id)
600-
int8 = type(int8_id)
601-
int16 = type(int16_id)
602-
int32 = type(int32_id)
603-
int64 = type(int64_id)
604-
int128 = type(int128_id)
605-
uint8 = type(uint8_id)
606-
uint16 = type(uint16_id)
607-
uint32 = type(uint32_id)
608-
uint64 = type(uint64_id)
609-
uint128 = type(uint128_id)
610-
float16 = type(float16_id)
611-
float32 = type(float32_id)
612-
float64 = type(float64_id)
613-
float128 = type(float128_id)
614-
complex_float32 = type(complex_float32_id)
615-
complex_float64 = type(complex_float64_id)
616-
void = type(void_id)
600+
bool = type('bool')
601+
int8 = type('int8')
602+
int16 = type('int16')
603+
int32 = type('int32')
604+
int64 = type('int64')
605+
int128 = type('int128')
606+
uint8 = type('uint8')
607+
uint16 = type('uint16')
608+
uint32 = type('uint32')
609+
uint64 = type('uint64')
610+
uint128 = type('uint128')
611+
float16 = type('float16')
612+
float32 = type('float32')
613+
float64 = type('float64')
614+
float128 = type('float128')
615+
# Until we have some sort of indexing scheme
616+
# for parameterized types exposed to Python,
617+
# we will have to use these aliases for complex types.
618+
complex64 = type('complex64')
619+
complex_float32 = complex64
620+
complex128 = type('complex128')
621+
complex_float64 = complex128
622+
void = type('void')
623+
intptr = type('intptr')
624+
uintptr = type('uintptr')
625+
string = type('string')
626+
bytes = type('bytes')
617627

618628
def tuple(*args):
619629
cdef vector[_type] _args
@@ -632,14 +642,12 @@ def tuple(*args):
632642

633643
return wrap(make_type[tuple_type]())
634644

635-
from libcpp.string cimport string
636-
637645
def struct(**kwds):
638646
# TODO: require an ordered dict here since struct types are ordered.
639647
# TODO: Use something other than dynd arrays to pass these arguments.
640648
# See the comment in the tuple function for details.
641649
cdef vector[_type] _kwds
642-
cdef vector[string] _names
650+
cdef vector[cpp_string] _names
643651

644652
if kwds:
645653
for kwd in kwds.values():
@@ -718,7 +726,8 @@ cdef as_numba_type(_type tp):
718726
return _to_numba_type[tp.get_id()]
719727

720728
cdef _type from_numba_type(tp):
721-
return _type(<type_id_t> _from_numba_type[tp])
729+
730+
return _get_reg_info((<type_id_t> _from_numba_type[tp])).tp
722731

723732
cdef _type cpp_type_for(object obj) except *:
724733
cdef _type tp = xtype_for_prefix(obj)

dynd/src/array_from_py.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static dynd::nd::array array_from_pylist(PyObject *obj)
235235
// TODO: Add ability to specify access flags (e.g. immutable)
236236
// Do a pass through all the data to deduce its type and shape
237237
vector<intptr_t> shape;
238-
ndt::type tp(void_id);
238+
ndt::type tp = ndt::make_type<void>();
239239
Py_ssize_t size = PyList_GET_SIZE(obj);
240240
shape.push_back(size);
241241
for (Py_ssize_t i = 0; i < size; ++i) {

dynd/src/assign.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <dynd/functional.hpp>
1010
#include <dynd/kernels/tuple_assignment_kernels.hpp>
11+
#include <dynd/type.hpp>
1112

1213
#include "assign.hpp"
1314
#include "callables/assign_from_pyobject_callable.hpp"
@@ -26,12 +27,19 @@ PYDYND_API void assign_init()
2627
types;
2728

2829
PyDateTime_IMPORT;
30+
// TODO: There should be an interface that allows adding overloads
31+
// based on type id rather than on actual type. The current interface
32+
// makes for a lot of mapping back and forth between types and their
33+
// corresponding type ids.
34+
// For now, just use the infos vector from the type registry to map
35+
// ids back to their corresponding types.
36+
auto infos = ndt::detail::infos();
2937

3038
for (const auto &pair : nd::callable::make_all<pydynd::nd::assign_from_pyobject_callable, types>()) {
31-
nd::assign.overload(pair.first[0], {ndt::make_type<pyobject_type>()}, pair.second);
39+
nd::assign.overload(infos[pair.first[0]].tp, {ndt::make_type<pyobject_type>()}, pair.second);
3240
}
3341
for (const auto &pair : nd::callable::make_all<pydynd::nd::assign_to_pyobject_callable, types>()) {
34-
nd::assign.overload(ndt::make_type<pyobject_type>(), {ndt::type(pair.first[0])}, pair.second);
42+
nd::assign.overload(ndt::make_type<pyobject_type>(), {infos[pair.first[0]].tp}, pair.second);
3543
}
3644
}
3745

dynd/src/type_conversions.cpp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#include "type_functions.hpp"
2-
#include "type_deduction.hpp"
1+
#include "type_conversions.hpp"
2+
33
#include "type_api.h"
44

55
dynd::ndt::type &pydynd::type_to_cpp_ref(PyObject *o)
@@ -64,22 +64,3 @@ dynd::ndt::type pydynd::dynd_ndt_cpp_type_for(PyObject *o)
6464
}
6565
return cpp_type_for(o);
6666
}
67-
68-
dynd::ndt::type pydynd::ndt_type_from_pylist(PyObject *obj)
69-
{
70-
// TODO: Add ability to specify access flags (e.g. immutable)
71-
// Do a pass through all the data to deduce its type and shape
72-
std::vector<intptr_t> shape;
73-
dynd::ndt::type tp(dynd::void_id);
74-
Py_ssize_t size = PyList_GET_SIZE(obj);
75-
shape.push_back(size);
76-
for (Py_ssize_t i = 0; i < size; ++i) {
77-
deduce_pylist_shape_and_dtype(PyList_GET_ITEM(obj, i), shape, tp, 1);
78-
}
79-
80-
if (tp.get_id() == dynd::void_id) {
81-
tp = dynd::ndt::type(dynd::int32_id);
82-
}
83-
84-
return dynd::ndt::make_type(shape.size(), shape.data(), tp);
85-
}

dynd/src/type_deduction.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,22 @@ dynd::ndt::type pydynd::xtype_for_prefix(PyObject *obj)
323323

324324
return dynd::ndt::type();
325325
}
326+
327+
dynd::ndt::type pydynd::ndt_type_from_pylist(PyObject *obj)
328+
{
329+
// TODO: Add ability to specify access flags (e.g. immutable)
330+
// Do a pass through all the data to deduce its type and shape
331+
std::vector<intptr_t> shape;
332+
dynd::ndt::type tp = dynd::ndt::make_type<void>();
333+
Py_ssize_t size = PyList_GET_SIZE(obj);
334+
shape.push_back(size);
335+
for (Py_ssize_t i = 0; i < size; ++i) {
336+
deduce_pylist_shape_and_dtype(PyList_GET_ITEM(obj, i), shape, tp, 1);
337+
}
338+
339+
if (tp.get_id() == dynd::void_id) {
340+
tp = dynd::ndt::make_type<int32_t>();
341+
}
342+
343+
return dynd::ndt::make_type(shape.size(), shape.data(), tp);
344+
}

0 commit comments

Comments
 (0)