File: support.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (219 lines) | stat: -rw-r--r-- 8,291 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
from rpython.rlib import jit
from rpython.rlib.rarithmetic import ovfcheck
from rpython.rtyper.lltypesystem import rffi, lltype

from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import unwrap_spec, appdef
from pypy.interpreter.typedef import GetSetProperty
from pypy.objspace.std.typeobject import W_TypeObject
from pypy.objspace.std.objspace import StdObjSpace
from pypy.module.micronumpy import constants as NPY
from pypy.module.exceptions.interp_exceptions import _new_exception, W_UserWarning

W_VisibleDeprecationWarning = _new_exception('VisibleDeprecationWarning', W_UserWarning,
    """Visible deprecation warning.

    By default, python will not show deprecation warnings, so this class
    can be used when a very visible warning is helpful, for example because
    the usage is most likely a user bug.

    """)


def issequence_w(space, w_obj):
    from pypy.module.micronumpy.base import W_NDimArray
    return (space.isinstance_w(w_obj, space.w_tuple) or
           space.isinstance_w(w_obj, space.w_list) or
           space.isinstance_w(w_obj, space.w_memoryview) or
           isinstance(w_obj, W_NDimArray))


def index_w(space, w_obj):
    try:
        return space.int_w(space.index(w_obj))
    except OperationError:
        try:
            return space.int_w(space.int(w_obj))
        except OperationError:
            raise oefmt(space.w_IndexError, "only integers, slices (`:`), "
                "ellipsis (`...`), numpy.newaxis (`None`) and integer or "
                "boolean arrays are valid indices")


@jit.unroll_safe
def product(s):
    i = 1
    for x in s:
        i *= x
    return i

@jit.unroll_safe
def product_check(s):
    i = 1
    for x in s:
        try:
            i = ovfcheck(i * x)
        except OverflowError:
            raise
    return i

def check_and_adjust_index(space, index, size, axis):
    if index < -size or index >= size:
        if axis >= 0:
            raise oefmt(space.w_IndexError,
                        "index %d is out of bounds for axis %d with size %d",
                        index, axis, size)
        else:
            raise oefmt(space.w_IndexError,
                        "index %d is out of bounds for size %d",
                        index, size)
    if index < 0:
        index += size
    return index

def _next_non_white_space(s, offset):
    ret = offset
    while ret < len(s) and (s[ret] == ' ' or s[ret] == '\t'):
        ret += 1
        if ret >= len(s):
            break
    return ret

def _is_alpha_underscore(ch):
    return (ch >= 'A' and ch <= 'Z') or (ch >= 'a' and ch <= 'z') or ch == '_'

def _is_alnum_underscore(ch):
    return _is_alpha_underscore(ch) or (ch >= '0' and ch <='9')

def _parse_signature(space, ufunc, signature):
    '''
    rewritten from _parse_signature in numpy/core/src/umath/ufunc_object.c
    it takes a signature like '(),()->()' or '(i)->(i)' or '(i,j),(j,k)->(i,k)'
    and sets up the ufunc to handle the actual call appropriately

    cpython numpy chops the dim names i,j,k out of the signature using pointers with
    no copying, while faster than this code it seems like a marginally useful optimization.
    We copy them out into var_names
    '''
    i = _next_non_white_space(signature, 0)
    cur_arg = 0
    cur_core_dim = 0 # index into ufunc.cor_dim_ixs
    nd = 0           # number of dims of the current argument
    var_names = {}
    while i < len(signature):
        # loop over input/output arguments
        if cur_arg == ufunc.nin:
            if signature[i:i+2] != '->':
                raise oefmt(space.w_ValueError, '%s at %d in "%s"',
                    "expect '->'", i, signature)
            i = _next_non_white_space(signature, i+2)
        # parse core dimensions of one argument,
        # e.g. "()", "(i)", or "(i,j)"
        if signature[i] != '(':
            raise oefmt(space.w_ValueError, '%s at %d in "%s"',
                    "expect '('", i, signature)
        i = _next_non_white_space(signature, i+1)
        end_of_arg = signature.find(')', i)
        if end_of_arg < 0:
            raise oefmt(space.w_ValueError, '%s %d in "%s"',
                    "could not find ')' after", i, signature)
        if end_of_arg == i:
            # no named arg, skip the next loop
            next_comma = -1
            i += 1
        else:
            next_comma = signature.find(',', i, end_of_arg)
            if next_comma < 0:
                next_comma = end_of_arg
        while next_comma > 0 and next_comma <= end_of_arg:
            # loop over core dimensions
            name_end = next_comma - 1
            while signature[name_end] == ' ' or signature[name_end] == '\t':
                name_end -= 1
            if name_end < i:
                raise oefmt(space.w_ValueError, '%s at %d in "%s"',
                    "expect dimension name", i, signature)
            var_name = signature[i:name_end + 1]
            for s in var_name:
                if not _is_alnum_underscore(s):
                    raise oefmt(space.w_ValueError, '%s at %d in "%s"',
                        "expect dimension name", i, signature)
            if var_name not in var_names:
                var_names[var_name] = ufunc.core_num_dim_ix
                ufunc.core_num_dim_ix += 1
            ufunc.core_dim_ixs.append(var_names[var_name])
            cur_core_dim += 1
            nd += 1
            i = next_comma
            if signature[i] == ',':
                i = _next_non_white_space(signature, i + 1);
                if signature[i] == ')':
                    raise oefmt(space.w_ValueError, '%s at %d in "%s"',
                        "',' must not be followed by ')'", i, signature)
            if end_of_arg <= i:
                next_comma = -1
                i = end_of_arg + 1
            else:
                next_comma = signature.find(',', i, end_of_arg)
                if next_comma < 0:
                    next_comma = end_of_arg
        ufunc.core_num_dims[cur_arg] = nd
        ufunc.core_offsets[cur_arg] = cur_core_dim - nd
        cur_arg += 1
        nd = 0
        if i < len(signature):
            i = _next_non_white_space(signature, i)
        if cur_arg != ufunc.nin and cur_arg != ufunc.nargs:
            # The list of input arguments (or output arguments) was
            # only read partially
            if signature[i] != ',':
                raise oefmt(space.w_ValueError, '%s at %d in "%s"',
                    "expect ','", i, signature)
            i = _next_non_white_space(signature, i + 1);
    if cur_arg != ufunc.nargs:
        raise oefmt(space.w_ValueError, '%s at %d in "%s"',
            "incomplete signature: not all arguments found", i, signature)
    if cur_core_dim == 0:
        ufunc.core_enabled = False
    return 0 # for historical reasons, any failures will raise

def get_storage_as_int(storage, start=0):
        return rffi.cast(lltype.Signed, storage) + start

def is_rhs_priority_higher(space, w_lhs, w_rhs):
    w_zero = space.newfloat(0.0)
    w_priority_l = space.findattr(w_lhs, space.newtext('__array_priority__')) or w_zero
    w_priority_r = space.findattr(w_rhs, space.newtext('__array_priority__')) or w_zero
    # XXX what is better, unwrapping values or space.gt?
    return space.is_true(space.gt(w_priority_r, w_priority_l))

def get_order_as_CF(proto_order, req_order):
    if req_order == NPY.CORDER:
        return NPY.CORDER
    elif req_order == NPY.FORTRANORDER:
        return NPY.FORTRANORDER
    return proto_order

def descr_set_docstring(space, w_obj, w_docstring):
    if not isinstance(space, StdObjSpace):
        raise oefmt(space.w_NotImplementedError,
                    "This only works with the real object space")
    if isinstance(w_obj, W_TypeObject):
        w_obj.w_doc = w_docstring
        return
    elif isinstance(w_obj, GetSetProperty):
        if space.is_none(w_docstring):
            doc = None
        else:
            doc = space.text_w(w_docstring)
        w_obj.doc = doc
        return
    app_set_docstring(space, w_obj, w_docstring)

app_set_docstring = appdef("""app_set_docstring_(obj, docstring):
    import types
    if isinstance(obj, types.MethodType):
        obj.im_func.__doc__ = docstring
    else:
        obj.__doc__ = docstring
""")