Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
e52e8771
Commit
e52e8771
authored
Dec 16, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support strings buffer format characters
parent
e17c1f59
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
126 additions
and
21 deletions
+126
-21
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+9
-7
Cython/Utility/Buffer.c
Cython/Utility/Buffer.c
+38
-13
tests/run/memslice.pyx
tests/run/memslice.pyx
+17
-0
tests/run/numpy_memoryview.pyx
tests/run/numpy_memoryview.pyx
+62
-1
No files found.
Cython/Compiler/Buffer.py
View file @
e52e8771
...
@@ -666,13 +666,15 @@ def mangle_dtype_name(dtype):
...
@@ -666,13 +666,15 @@ def mangle_dtype_name(dtype):
return
prefix
+
type_decl
.
replace
(
"["
,
"_"
).
replace
(
"]"
,
"_"
)
return
prefix
+
type_decl
.
replace
(
"["
,
"_"
).
replace
(
"]"
,
"_"
)
def
get_type_information_cname
(
code
,
dtype
,
maxdepth
=
None
):
def
get_type_information_cname
(
code
,
dtype
,
maxdepth
=
None
):
# Output the run-time type information (__Pyx_TypeInfo) for given dtype,
"""
# and return the name of the type info struct.
Output the run-time type information (__Pyx_TypeInfo) for given dtype,
#
and return the name of the type info struct.
# Structs with two floats of the same size are encoded as complex numbers.
# One can seperate between complex numbers declared as struct or with native
Structs with two floats of the same size are encoded as complex numbers.
# encoding by inspecting to see if the fields field of the type is
One can seperate between complex numbers declared as struct or with native
# filled in.
encoding by inspecting to see if the fields field of the type is
filled in.
"""
namesuffix
=
mangle_dtype_name
(
dtype
)
namesuffix
=
mangle_dtype_name
(
dtype
)
name
=
"__Pyx_TypeInfo_%s"
%
namesuffix
name
=
"__Pyx_TypeInfo_%s"
%
namesuffix
structinfo_name
=
"__Pyx_StructFields_%s"
%
namesuffix
structinfo_name
=
"__Pyx_StructFields_%s"
%
namesuffix
...
...
Cython/Utility/Buffer.c
View file @
e52e8771
...
@@ -180,6 +180,7 @@ static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
...
@@ -180,6 +180,7 @@ static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
case
'T'
:
return
"a struct"
;
case
'T'
:
return
"a struct"
;
case
'O'
:
return
"Python object"
;
case
'O'
:
return
"Python object"
;
case
'P'
:
return
"a pointer"
;
case
'P'
:
return
"a pointer"
;
case
's'
:
case
'p'
:
return
"a string"
;
case
0
:
return
"end"
;
case
0
:
return
"end"
;
default:
return
"unparseable format string"
;
default:
return
"unparseable format string"
;
}
}
...
@@ -187,7 +188,7 @@ static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
...
@@ -187,7 +188,7 @@ static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
static
size_t
__Pyx_BufFmt_TypeCharToStandardSize
(
char
ch
,
int
is_complex
)
{
static
size_t
__Pyx_BufFmt_TypeCharToStandardSize
(
char
ch
,
int
is_complex
)
{
switch
(
ch
)
{
switch
(
ch
)
{
case
'?'
:
case
'c'
:
case
'b'
:
case
'B'
:
return
1
;
case
'?'
:
case
'c'
:
case
'b'
:
case
'B'
:
case
's'
:
case
'p'
:
return
1
;
case
'h'
:
case
'H'
:
return
2
;
case
'h'
:
case
'H'
:
return
2
;
case
'i'
:
case
'I'
:
case
'l'
:
case
'L'
:
return
4
;
case
'i'
:
case
'I'
:
case
'l'
:
case
'L'
:
return
4
;
case
'q'
:
case
'Q'
:
return
8
;
case
'q'
:
case
'Q'
:
return
8
;
...
@@ -206,7 +207,7 @@ static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
...
@@ -206,7 +207,7 @@ static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
static
size_t
__Pyx_BufFmt_TypeCharToNativeSize
(
char
ch
,
int
is_complex
)
{
static
size_t
__Pyx_BufFmt_TypeCharToNativeSize
(
char
ch
,
int
is_complex
)
{
switch
(
ch
)
{
switch
(
ch
)
{
case
'c'
:
case
'b'
:
case
'B'
:
return
1
;
case
'c'
:
case
'b'
:
case
'B'
:
case
's'
:
case
'p'
:
return
1
;
case
'h'
:
case
'H'
:
return
sizeof
(
short
);
case
'h'
:
case
'H'
:
return
sizeof
(
short
);
case
'i'
:
case
'I'
:
return
sizeof
(
int
);
case
'i'
:
case
'I'
:
return
sizeof
(
int
);
case
'l'
:
case
'L'
:
return
sizeof
(
long
);
case
'l'
:
case
'L'
:
return
sizeof
(
long
);
...
@@ -237,7 +238,7 @@ typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
...
@@ -237,7 +238,7 @@ typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
static
size_t
__Pyx_BufFmt_TypeCharToAlignment
(
char
ch
,
int
is_complex
)
{
static
size_t
__Pyx_BufFmt_TypeCharToAlignment
(
char
ch
,
int
is_complex
)
{
switch
(
ch
)
{
switch
(
ch
)
{
case
'?'
:
case
'c'
:
case
'b'
:
case
'B'
:
return
1
;
case
'?'
:
case
'c'
:
case
'b'
:
case
'B'
:
case
's'
:
case
'p'
:
return
1
;
case
'h'
:
case
'H'
:
return
sizeof
(
__Pyx_st_short
)
-
sizeof
(
short
);
case
'h'
:
case
'H'
:
return
sizeof
(
__Pyx_st_short
)
-
sizeof
(
short
);
case
'i'
:
case
'I'
:
return
sizeof
(
__Pyx_st_int
)
-
sizeof
(
int
);
case
'i'
:
case
'I'
:
return
sizeof
(
__Pyx_st_int
)
-
sizeof
(
int
);
case
'l'
:
case
'L'
:
return
sizeof
(
__Pyx_st_long
)
-
sizeof
(
long
);
case
'l'
:
case
'L'
:
return
sizeof
(
__Pyx_st_long
)
-
sizeof
(
long
);
...
@@ -271,7 +272,7 @@ typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
...
@@ -271,7 +272,7 @@ typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
static
size_t
__Pyx_BufFmt_TypeCharToPadding
(
char
ch
,
int
is_complex
)
{
static
size_t
__Pyx_BufFmt_TypeCharToPadding
(
char
ch
,
int
is_complex
)
{
switch
(
ch
)
{
switch
(
ch
)
{
case
'?'
:
case
'c'
:
case
'b'
:
case
'B'
:
return
1
;
case
'?'
:
case
'c'
:
case
'b'
:
case
'B'
:
case
's'
:
case
'p'
:
return
1
;
case
'h'
:
case
'H'
:
return
sizeof
(
__Pyx_pad_short
)
-
sizeof
(
short
);
case
'h'
:
case
'H'
:
return
sizeof
(
__Pyx_pad_short
)
-
sizeof
(
short
);
case
'i'
:
case
'I'
:
return
sizeof
(
__Pyx_pad_int
)
-
sizeof
(
int
);
case
'i'
:
case
'I'
:
return
sizeof
(
__Pyx_pad_int
)
-
sizeof
(
int
);
case
'l'
:
case
'L'
:
return
sizeof
(
__Pyx_pad_long
)
-
sizeof
(
long
);
case
'l'
:
case
'L'
:
return
sizeof
(
__Pyx_pad_long
)
-
sizeof
(
long
);
...
@@ -290,11 +291,17 @@ static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, int is_complex) {
...
@@ -290,11 +291,17 @@ static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, int is_complex) {
static
char
__Pyx_BufFmt_TypeCharToGroup
(
char
ch
,
int
is_complex
)
{
static
char
__Pyx_BufFmt_TypeCharToGroup
(
char
ch
,
int
is_complex
)
{
switch
(
ch
)
{
switch
(
ch
)
{
case
'c'
:
case
'b'
:
case
'h'
:
case
'i'
:
case
'l'
:
case
'q'
:
return
'I'
;
case
'c'
:
case
'b'
:
case
'h'
:
case
'i'
:
case
'B'
:
case
'H'
:
case
'I'
:
case
'L'
:
case
'Q'
:
return
'U'
;
case
'l'
:
case
'q'
:
case
's'
:
case
'p'
:
case
'f'
:
case
'd'
:
case
'g'
:
return
(
is_complex
?
'C'
:
'R'
);
return
'I'
;
case
'O'
:
return
'O'
;
case
'B'
:
case
'H'
:
case
'I'
:
case
'L'
:
case
'Q'
:
case
'P'
:
return
'P'
;
return
'U'
;
case
'f'
:
case
'd'
:
case
'g'
:
return
(
is_complex
?
'C'
:
'R'
);
case
'O'
:
return
'O'
;
case
'P'
:
return
'P'
;
default:
{
default:
{
__Pyx_BufFmt_RaiseUnexpectedChar
(
ch
);
__Pyx_BufFmt_RaiseUnexpectedChar
(
ch
);
return
0
;
return
0
;
...
@@ -332,20 +339,36 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
...
@@ -332,20 +339,36 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
char
group
;
char
group
;
size_t
size
,
offset
,
arraysize
=
1
;
size_t
size
,
offset
,
arraysize
=
1
;
/* printf("processing... %s\n", ctx->head->field->type->name); */
if
(
ctx
->
enc_type
==
0
)
return
0
;
if
(
ctx
->
enc_type
==
0
)
return
0
;
/* Validate array size */
/* Validate array size */
if
(
ctx
->
head
->
field
->
type
->
arraysize
[
0
])
{
if
(
ctx
->
head
->
field
->
type
->
arraysize
[
0
])
{
int
i
;
int
i
,
ndim
=
0
;
/* handle strings ('s' and 'p') */
if
(
ctx
->
enc_type
==
's'
||
ctx
->
enc_type
==
'p'
)
{
ctx
->
is_valid_array
=
ctx
->
head
->
field
->
type
->
ndim
==
1
;
ndim
=
1
;
if
(
ctx
->
enc_count
!=
ctx
->
head
->
field
->
type
->
arraysize
[
0
])
{
PyErr_Format
(
PyExc_ValueError
,
"Expected a dimension of size %zu, got %zu"
,
ctx
->
head
->
field
->
type
->
arraysize
[
0
],
ctx
->
enc_count
);
return
-
1
;
}
}
if
(
!
ctx
->
is_valid_array
)
{
if
(
!
ctx
->
is_valid_array
)
{
PyErr_Format
(
PyExc_ValueError
,
"Expected %d dimensions, got
0
"
,
PyErr_Format
(
PyExc_ValueError
,
"Expected %d dimensions, got
%d
"
,
ctx
->
head
->
field
->
type
->
ndim
);
ctx
->
head
->
field
->
type
->
ndim
,
ndim
);
return
-
1
;
return
-
1
;
}
}
for
(
i
=
0
;
i
<
ctx
->
head
->
field
->
type
->
ndim
;
i
++
)
{
for
(
i
=
0
;
i
<
ctx
->
head
->
field
->
type
->
ndim
;
i
++
)
{
arraysize
*=
ctx
->
head
->
field
->
type
->
arraysize
[
i
];
arraysize
*=
ctx
->
head
->
field
->
type
->
arraysize
[
i
];
}
}
ctx
->
is_valid_array
=
0
;
ctx
->
is_valid_array
=
0
;
ctx
->
enc_count
=
1
;
}
}
group
=
__Pyx_BufFmt_TypeCharToGroup
(
ctx
->
enc_type
,
ctx
->
is_complex
);
group
=
__Pyx_BufFmt_TypeCharToGroup
(
ctx
->
enc_type
,
ctx
->
is_complex
);
...
@@ -492,6 +515,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
...
@@ -492,6 +515,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
while
(
1
)
{
while
(
1
)
{
switch
(
*
ts
)
{
switch
(
*
ts
)
{
/* puts(ts); */
case
0
:
case
0
:
if
(
ctx
->
enc_type
!=
0
&&
ctx
->
head
==
NULL
)
{
if
(
ctx
->
enc_type
!=
0
&&
ctx
->
head
==
NULL
)
{
__Pyx_BufFmt_RaiseExpected
(
ctx
);
__Pyx_BufFmt_RaiseExpected
(
ctx
);
...
@@ -543,6 +567,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
...
@@ -543,6 +567,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
}
}
if
(
__Pyx_BufFmt_ProcessTypeChunk
(
ctx
)
==
-
1
)
return
NULL
;
if
(
__Pyx_BufFmt_ProcessTypeChunk
(
ctx
)
==
-
1
)
return
NULL
;
ctx
->
enc_type
=
0
;
/* Erase processed last struct element */
ctx
->
enc_type
=
0
;
/* Erase processed last struct element */
ctx
->
enc_count
=
0
;
ctx
->
struct_alignment
=
0
;
ctx
->
struct_alignment
=
0
;
++
ts
;
++
ts
;
ts_after_sub
=
ts
;
ts_after_sub
=
ts
;
...
@@ -585,7 +610,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
...
@@ -585,7 +610,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
case
'c'
:
case
'b'
:
case
'B'
:
case
'h'
:
case
'H'
:
case
'i'
:
case
'I'
:
case
'c'
:
case
'b'
:
case
'B'
:
case
'h'
:
case
'H'
:
case
'i'
:
case
'I'
:
case
'l'
:
case
'L'
:
case
'q'
:
case
'Q'
:
case
'l'
:
case
'L'
:
case
'q'
:
case
'Q'
:
case
'f'
:
case
'd'
:
case
'g'
:
case
'f'
:
case
'd'
:
case
'g'
:
case
'O'
:
case
'O'
:
case
's'
:
case
'p'
:
if
(
ctx
->
enc_type
==
*
ts
&&
got_Z
==
ctx
->
is_complex
&&
if
(
ctx
->
enc_type
==
*
ts
&&
got_Z
==
ctx
->
is_complex
&&
ctx
->
enc_packmode
==
ctx
->
new_packmode
)
{
ctx
->
enc_packmode
==
ctx
->
new_packmode
)
{
/* Continue pooling same type */
/* Continue pooling same type */
...
...
tests/run/memslice.pyx
View file @
e52e8771
...
@@ -1576,7 +1576,24 @@ def test_padded_structs():
...
@@ -1576,7 +1576,24 @@ def test_padded_structs():
>>> test_padded_structs()
>>> test_padded_structs()
"""
"""
cdef
ArrayStruct
a1
[
10
]
cdef
ArrayStruct
a1
[
10
]
cdef
PackedArrayStruct
a2
[
10
]
cdef
AlignedNested
a3
[
10
]
cdef
AlignedNestedNormal
a4
[
10
]
cdef
A
a5
[
10
]
cdef
B
a6
[
10
]
cdef
C
a7
[
10
]
cdef
D
a8
[
10
]
_test_padded
(
a1
)
_test_padded
(
a1
)
_test_padded
(
a2
)
_test_padded
(
a3
)
_test_padded
(
a4
)
_test_padded
(
a5
)
_test_padded
(
a6
)
_test_padded
(
a7
)
# There is a pre-existing bug that doesn't parse the format for this
# struct properly -- fix this
#_test_padded(a8)
cdef
_test_padded
(
FusedPadded
myarray
[
10
]):
cdef
_test_padded
(
FusedPadded
myarray
[
10
]):
# test that the buffer format parser accepts our format string...
# test that the buffer format parser accepts our format string...
...
...
tests/run/numpy_memoryview.pyx
View file @
e52e8771
...
@@ -418,7 +418,25 @@ def test_memslice_structarray(data, dtype):
...
@@ -418,7 +418,25 @@ def test_memslice_structarray(data, dtype):
11
11
eggs
eggs
Todo: test with string format specifier
Test the same thing with the string format specifier
>>> dtype = np.dtype([('a', '4i'), ('b', 'S5')])
>>> test_memslice_structarray(data, dtype)
0
1
2
3
spam
4
5
6
7
ham
8
9
10
11
eggs
"""
"""
a
=
np
.
empty
((
3
,),
dtype
=
dtype
)
a
=
np
.
empty
((
3
,),
dtype
=
dtype
)
a
[:]
=
data
a
[:]
=
data
...
@@ -446,4 +464,47 @@ def test_structarray_errors(StructArray[:] a):
...
@@ -446,4 +464,47 @@ def test_structarray_errors(StructArray[:] a):
Traceback (most recent call last):
Traceback (most recent call last):
...
...
ValueError: Expected 1 dimension(s), got 2
ValueError: Expected 1 dimension(s), got 2
Test the same thing with the string format specifier
>>> dtype = np.dtype([('a', '4i'), ('b', 'S5')])
>>> test_structarray_errors(np.empty((5,), dtype=dtype))
>>> dtype = np.dtype([('a', '6i'), ('b', 'S5')])
>>> test_structarray_errors(np.empty((5,), dtype=dtype))
Traceback (most recent call last):
...
ValueError: Expected a dimension of size 4, got 6
>>> dtype = np.dtype([('a', '(4,4)i'), ('b', 'S5')])
>>> test_structarray_errors(np.empty((5,), dtype=dtype))
Traceback (most recent call last):
...
ValueError: Expected 1 dimension(s), got 2
"""
cdef
struct
StringStruct
:
char
c
[
4
][
4
]
ctypedef
char
String
[
4
][
4
]
def
stringstructtest
(
StringStruct
[:]
view
):
pass
def
stringtest
(
String
[:]
view
):
pass
@
testcase_numpy_1_5
def
test_string_invalid_dims
():
"""
>>> dtype = np.dtype([('a', 'S4')])
>>> data = ['spam', 'eggs']
>>> stringstructtest(np.array(data, dtype=dtype))
Traceback (most recent call last):
...
ValueError: Expected 2 dimensions, got 1
>>> stringtest(np.array(data, dtype='S4'))
Traceback (most recent call last):
...
ValueError: Expected 2 dimensions, got 1
"""
"""
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