def _add_trailing_padding(value, padding): """Inject the specified number of padding bytes at the end of a dtype""" from numpy.core import dtype if value.fields is None: vfields = {'f0': (value, 0)} else: vfields = dict(value.fields) if value.names and value.names[-1] == '' and \ value[''].char == 'V': # A trailing padding field is already present vfields[''] = ('V%d' % (vfields[''][0].itemsize + padding), vfields[''][1]) value = dtype(vfields) else: # Get a free name for the padding field j = 0 while True: name = 'pad%d' % j if name not in vfields: vfields[name] = ('V%d' % padding, value.itemsize) break j += 1 value = dtype(vfields) if '' not in vfields: # Strip out the name of the padding field names = list(value.names) names[-1] = '' value.names = tuple(names) return value
def add_newdoc_for_scalar_type(obj, fixed_aliases, doc): # note: `:field: value` is rST syntax which renders as field lists. o = getattr(_numerictypes, obj) character_code = dtype(o).char canonical_name_doc = ( "" if obj == o.__name__ else ":Canonical name: `numpy.{}`\n ".format(obj) ) alias_doc = "".join( ":Alias: `numpy.{}`\n ".format(alias) for alias in fixed_aliases ) alias_doc += "".join( ":Alias on this platform: `numpy.{}`: {}.\n ".format(alias, doc) for (alias_type, alias, doc) in possible_aliases if alias_type is o ) docstring = """ {doc} :Character code: ``'{character_code}'`` {canonical_name_doc}{alias_doc} """.format( doc=doc.strip(), character_code=character_code, canonical_name_doc=canonical_name_doc, alias_doc=alias_doc, ) add_newdoc("numpy.core.numerictypes", obj, docstring)
def _usefields(adict, align): from numpy.core import dtype try: names = adict[-1] except KeyError: names = None if names is None: names, formats, offsets, titles = _makenames_list(adict) else: formats = [] offsets = [] titles = [] for name in names: res = adict[name] formats.append(res[0]) offsets.append(res[1]) if (len(res) > 2): titles.append(res[2]) else: titles.append(None) return dtype({"names" : names, "formats" : formats, "offsets" : offsets, "titles" : titles}, align)
def _makenames_list(adict): from numpy.core import dtype allfields = [] fnames = adict.keys() for fname in fnames: obj = adict[fname] n = len(obj) if not isinstance(obj, tuple) or n not in [2,3]: raise ValueError("entry not a 2- or 3- tuple") if (n > 2) and (obj[2] == fname): continue num = int(obj[1]) if (num < 0): raise ValueError("invalid offset.") format = dtype(obj[0]) if (format.itemsize == 0): raise ValueError("all itemsizes must be fixed.") if (n > 2): title = obj[2] else: title = None allfields.append((fname, format, num, title)) # sort by offsets allfields.sort(key=lambda x: x[2]) names = [x[0] for x in allfields] formats = [x[1] for x in allfields] offsets = [x[2] for x in allfields] titles = [x[3] for x in allfields] return names, formats, offsets, titles
def _getintp_ctype(): from numpy.core import dtype val = _getintp_ctype.cache if val is not None: return val char = dtype('p').char import ctypes if (char == 'i'): val = ctypes.c_int elif char == 'l': val = ctypes.c_long elif char == 'q': val = ctypes.c_longlong else: val = ctypes.c_long _getintp_ctype.cache = val return val
def add_newdoc_for_scalar_type(obj, fixed_aliases, doc): # note: `:field: value` is rST syntax which renders as field lists. o = getattr(_numerictypes, obj) character_code = dtype(o).char canonical_name_doc = "" if obj == o.__name__ else \ f":Canonical name: `numpy.{obj}`\n " if fixed_aliases: alias_doc = ''.join(f":Alias: `numpy.{alias}`\n " for alias in fixed_aliases) else: alias_doc = '' alias_doc += ''.join(f"{_doc_alias_string} `numpy.{alias}`: {doc}.\n " for (alias_type, alias, doc) in possible_aliases if alias_type is o) docstring = f""" {doc.strip()} :Character code: ``'{character_code}'`` {canonical_name_doc}{alias_doc} """ add_newdoc('numpy.core.numerictypes', obj, docstring)
def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False): from numpy.core import dtype fields = {} offset = 0 explicit_name = False this_explicit_name = False common_alignment = 1 is_padding = False last_offset = 0 dummy_name_index = [0] def next_dummy_name(): dummy_name_index[0] += 1 def get_dummy_name(): while True: name = 'f%d' % dummy_name_index[0] if name not in fields: return name next_dummy_name() # Parse spec while spec: value = None # End of structure, bail out to upper level if spec[0] == '}': spec = spec[1:] break # Sub-arrays (1) shape = None if spec[0] == '(': j = spec.index(')') shape = tuple(map(int, spec[1:j].split(','))) spec = spec[j+1:] # Byte order if spec[0] in ('@', '=', '<', '>', '^', '!'): byteorder = spec[0] if byteorder == '!': byteorder = '>' spec = spec[1:] # Byte order characters also control native vs. standard type sizes if byteorder in ('@', '^'): type_map = _pep3118_native_map type_map_chars = _pep3118_native_typechars else: type_map = _pep3118_standard_map type_map_chars = _pep3118_standard_typechars # Item sizes itemsize = 1 if spec[0].isdigit(): j = 1 for j in xrange(1, len(spec)): if not spec[j].isdigit(): break itemsize = int(spec[:j]) spec = spec[j:] # Data types is_padding = False if spec[:2] == 'T{': value, spec, align, next_byteorder = _dtype_from_pep3118( spec[2:], byteorder=byteorder, is_subdtype=True) elif spec[0] in type_map_chars: next_byteorder = byteorder if spec[0] == 'Z': j = 2 else: j = 1 typechar = spec[:j] spec = spec[j:] is_padding = (typechar == 'x') dtypechar = type_map[typechar] if dtypechar in 'USV': dtypechar += '%d' % itemsize itemsize = 1 numpy_byteorder = {'@': '=', '^': '='}.get(byteorder, byteorder) value = dtype(numpy_byteorder + dtypechar) align = value.alignment else: raise ValueError("Unknown PEP 3118 data type specifier %r" % spec) # # Native alignment may require padding # # Here we assume that the presence of a '@' character implicitly implies # that the start of the array is *already* aligned. # extra_offset = 0 if byteorder == '@': start_padding = (-offset) % align intra_padding = (-value.itemsize) % align offset += start_padding if intra_padding != 0: if itemsize > 1 or (shape is not None and _prod(shape) > 1): # Inject internal padding to the end of the sub-item value = _add_trailing_padding(value, intra_padding) else: # We can postpone the injection of internal padding, # as the item appears at most once extra_offset += intra_padding # Update common alignment common_alignment = (align*common_alignment / _gcd(align, common_alignment)) # Convert itemsize to sub-array if itemsize != 1: value = dtype((value, (itemsize,))) # Sub-arrays (2) if shape is not None: value = dtype((value, shape)) # Field name this_explicit_name = False if spec and spec.startswith(':'): i = spec[1:].index(':') + 1 name = spec[1:i] spec = spec[i+1:] explicit_name = True this_explicit_name = True else: name = get_dummy_name() if not is_padding or this_explicit_name: if name in fields: raise RuntimeError("Duplicate field name '%s' in PEP3118 format" % name) fields[name] = (value, offset) last_offset = offset if not this_explicit_name: next_dummy_name() byteorder = next_byteorder offset += value.itemsize offset += extra_offset # Check if this was a simple 1-item type if len(fields.keys()) == 1 and not explicit_name and fields['f0'][1] == 0 \ and not is_subdtype: ret = fields['f0'][0] else: ret = dtype(fields) # Trailing padding must be explicitly added padding = offset - ret.itemsize if byteorder == '@': padding += (-offset) % common_alignment if is_padding and not this_explicit_name: ret = _add_trailing_padding(ret, padding) # Finished if is_subdtype: return ret, spec, common_alignment, byteorder else: return ret
value, and ``False`` otherwise. .. versionadded:: 1.22 Examples -------- >>> np.{float_name}(-2.0).is_integer() True >>> np.{float_name}(3.2).is_integer() False """)) for int_name in ('int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'int64', 'uint64', 'int64', 'uint64'): # Add negative examples for signed cases by checking typecode add_newdoc('numpy.core.numerictypes', int_name, ('bit_count', f""" {int_name}.bit_count() -> int Computes the number of 1-bits in the absolute value of the input. Analogous to the builtin `int.bit_count` or ``popcount`` in C++. Examples -------- >>> np.{int_name}(127).bit_count() 7""" + (f""" >>> np.{int_name}(-127).bit_count() 7 """ if dtype(int_name).char.islower() else "")))