Coverage for pygeodesy/basics.py : 97%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*-
''' # make sure int/int division yields float quotient raise ImportError('%s 1/2 == %s' % ('division', division))
_TypeError, _TypesError, _ValueError, _xkwds_get _invalid_, _N_A_, _name_, _SPACE_, _UNDER_, \ _utf_8_, _version_, _0_0, _1_0
except ImportError: try: _Ints = int, long # int objects (C{tuple}) except NameError: # Python 3+ _Ints = int, # int objects (C{tuple})
except ImportError: try: _Scalars = int, long, float # scalar objects (C{tuple}) except NameError: _Scalars = int, float # scalar objects (C{tuple})
except ImportError: # no .abc in Python 2.7- from collections import Sequence as _Sequence # imported by .points # and isinstance(range(1), _Sequence): else: raise ImportError # _AssertionError except ImportError: _Sequence = tuple # immutable for .points._Basequence _Seqs = list, _Sequence # , range for function len2 below
_Strs = basestring, str
def _Xstr(exc): # PYCHOK no cover '''I{Invoke only with caught import exception} B{C{exc}}.
C{... "cannot import name _distributor_init" ...}
only for numpy, scipy on arm64 macOS' Python 2.7.16? ''' t = str(exc) if '_distributor_init' in t: from sys import exc_info from traceback import extract_tb tb = exc_info()[2] # 3-tuple (type, value, traceback) t4 = extract_tb(tb, 1)[0] # 4-tuple (file, line, name, 'import ...') t = _SPACE_('cannot', t4[3] or _N_A_) del tb, t4 return t
except NameError: # Python 3+ _Bytes = bytes, bytearray _Strs = str, # tuple _Xstr = str
'''Clip a string to the given length limit.
@arg bstr: String (C{bytes} or C{str}). @kwarg limit: Length limit (C{int}). @kwarg white: Optionally, replace all whitespace (C{str}).
@return: The clipped or unclipped B{C{bstr}}. '''
'''Like C{math.copysign(x, y)} except C{zero}, I{unsigned}.
@return: C{math.copysign(B{x}, B{y})} if B{C{x}} else C{0}. '''
'''Return the value of B{x} as C{type} of C{y}.
@return: C{type(B{y})(B{x})}. '''
'''Split a string in 2 halfs.
@arg str2: String to split (C{str}).
@return: 2-Tuple (_1st, _2nd) half (C{str}).
@raise ValueError: Zero or odd C{len}(B{C{str2}}). ''' raise _ValueError(str2=str2, txt='odd')
'''Check whether an object is C{bool}ean.
@arg obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is C{bool}ean, C{False} otherwise. ''' # or obj is False)
if _FOR_DOCS: # XXX avoid epidoc Python 2.7 error def isclass(obj): '''Return C{True} if B{C{obj}} is a C{class}.
@see: Python's C{inspect.isclass}. ''' return _isclass(obj) else:
except ImportError:
def isfinite(obj): '''Check for C{Inf} and C{NaN} values.
@arg obj: Value (C{scalar}).
@return: C{False} if B{C{obj}} is C{INF} or C{NAN}, C{True} otherwise.
@raise TypeError: Non-scalar B{C{obj}}. ''' if not isscalar(obj): raise _IsnotError(isscalar.__name__, obj=obj) return not (isinf(obj) or isnan(obj))
except AttributeError: # Python 2-
def isidentifier(obj): '''Return C{True} if B{C{obj}} is a valid Python identifier. ''' return True if (obj and obj.replace(_UNDER_, NN).isalnum() and not obj[:1].isdigit()) else False
# from math import isinf
'''Check for C{int} type or an integer C{float} value.
@arg obj: The object (any C{type}). @kwarg both: Optionally, check C{float} type and value (C{bool}).
@return: C{True} if B{C{obj}} is C{int} or an integer C{float}, C{False} otherwise.
@note: C{isint(True)} or C{isint(False)} returns C{False} (and no longer C{True}). ''' except AttributeError: return False # XXX float(int(obj)) == obj?
except ImportError:
def iskeyword(unused): '''Not Implemented. Return C{False}, always. ''' return False
# from math import isnan
'''Is B{C{x}} near zero?
@arg x: Value (C{scalar}). @kwarg eps0: Near-zero (C{EPS0}).
@return: C{True} if C{abs(B{x}) < B{eps0}}, C{False} otherwise.
@see: Function L{isnon0}. '''
'''Is B{C{x}} near one?
@arg x: Value (C{scalar}). @kwarg eps0: Near-zero (C{EPS0}).
@return: C{isnear0(B{x} - 1)}.
@see: Function L{isnear0}. '''
'''Check for L{NEG0}, negative C{0.0}.
@arg x: Value (C{scalar}).
@return: C{True} if B{C{x}} is C{NEG0} or C{-0.0}, C{False} otherwise. ''' # and str(x).startswith('-')
'''Is B{C{x}} non-zero?
@arg x: Value (C{scalar}). @kwarg eps0: Near-zero (C{EPS0}).
@return: C{True} if C{abs(B{x}) > B{eps0}}, C{False} otherwise.
@see: Function L{isnear0}. '''
'''Is B{C{x}} odd?
@arg x: Value (C{scalar}).
@return: C{True} if B{C{x}} is odd, C{False} otherwise. '''
'''Check for scalar types.
@arg obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is C{scalar}, C{False} otherwise. '''
'''Check for sequence types.
@arg obj: The object (any C{type}). @arg excluded: Optional exclusions (C{type}).
@note: Excluding C{tuple} implies excluding C{namedtuple}.
@return: C{True} if B{C{obj}} is a sequence, C{False} otherwise. ''' isinstance(obj, _Seqs)
'''Check for string types.
@arg obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is C{str}, C{False} otherwise. '''
'''Check whether a class is a sub-class of some class(es).
@arg Sub: The sub-class (C{class}). @arg Supers: One or more C(super) classes (C{class}).
@return: C{True} if B{C{Sub}} is a sub-class of any B{C{Supers}}, C{False} otherwise (C{bool}). '''
'''Make built-in function L{len} work for generators, iterators, etc. since those can only be started exactly once.
@arg items: Generator, iterator, list, range, tuple, etc.
@return: 2-Tuple C{(n, items)} of the number of items (C{int}) and the items (C{list} or C{tuple}). '''
'''Apply each argument to a single-argument function and return a C{tuple} of results.
@arg fun1: 1-Arg function to apply (C{callable}). @arg xs: Arguments to apply (C{any positional}).
@return: Function results (C{tuple}). '''
'''Apply arguments to a function and return a C{tuple} of results.
Unlike Python 2's built-in L{map}, Python 3+ L{map} returns a L{map} object, an iterator-like object which generates the results only once. Converting the L{map} object to a tuple maintains Python 2 behavior.
@arg func: Function to apply (C{callable}). @arg xs: Arguments to apply (C{list, tuple, ...}).
@return: Function results (C{tuple}). '''
'''Negate C{x} unless C{zero} or C{NEG0}.
@return: C{-B{x}} if B{C{x}} else C{0.0}. '''
'''Negate all of C{xs} with L{neg}.
@return: A C{tuple(neg(x) for x in B{xs})}. '''
'''Return sign of C{x} as C{int}.
@return: -1, 0 or +1 (C{int}). '''
'''Split an iterable into C{n} slices.
@arg iterable: Items to be spliced (C{list}, C{tuple}, ...). @kwarg n: Number of slices to generate (C{int}). @kwarg fill: Optional fill value for missing items.
@return: A generator for each of B{C{n}} slices, M{iterable[i::n] for i=0..n}.
@raise TypeError: Invalid B{C{n}}.
@note: Each generated slice is a C{tuple} or a C{list}, the latter only if the B{C{iterable}} is a C{list}.
@example:
>>> from pygeodesy import splice
>>> a, b = splice(range(10)) >>> a, b ((0, 2, 4, 6, 8), (1, 3, 5, 7, 9))
>>> a, b, c = splice(range(10), n=3) >>> a, b, c ((0, 3, 6, 9), (1, 4, 7), (2, 5, 8))
>>> a, b, c = splice(range(10), n=3, fill=-1) >>> a, b, c ((0, 3, 6, 9), (1, 4, 7, -1), (2, 5, 8, -1))
>>> tuple(splice(list(range(9)), n=5)) ([0, 5], [1, 6], [2, 7], [3, 8], [4])
>>> splice(range(9), n=1) <generator object splice at 0x0...> ''' raise _TypeError(n=n)
# XXX t[i::n] chokes PyChecker else: yield t
'''Convert C{unicode} or C{bytes} to C{str}. '''
'''Return unsigned C{0.0}.
@return: C{B{x}} if B{C{x}} else C{0.0}. '''
'''(INTERNAL) Copy an object, shallow or deep.
@arg inst: The object to copy (any C{type}). @kwarg deep: If C{True} make a deep, otherwise a shallow copy (C{bool}).
@return: The copy of B{C{inst}}. '''
'''(INTERNAL) Duplicate an object, replacing some attributes.
@arg inst: The object to copy (any C{type}). @kwarg items: Attributes to be changed (C{any}).
@return: Shallow duplicate of B{C{inst}} with modified attributes, if any B{C{items}}.
@raise AttributeError: Some B{C{items}} invalid. ''' from pygeodesy.named import classname t = _SPACE_(_DOT_(classname(inst), n), _invalid_) raise _AttributeError(txt=t, this=inst, **items)
'''(INTERNAL) Embellish an C{ImportError}. '''
'''(INTERNAL) Check C{Types} of all C{name=value} pairs.
@arg Types: One or more classes or types (C{class}). @kwarg name_value_pairs: One or more C{B{name}=value} pairs with the C{value} to be checked.
@raise TypeError: At least one of the B{C{name_value_pairs}} is not any of the B{C{Types}}. ''' raise _TypesError(n, v, *Types)
'''(INTERNAL) Import C{numpy} and check required version ''' except ImportError as x: raise _xImportError(x, where)
'''(INTERNAL) Exclusive-or C{x} and C{xs}. '''
'''(INTERNAL) Import C{scipy} and check required version ''' except ImportError as x: raise _xImportError(x, where)
'''(INTERNAL) Check super C{Class} of all C{name=value} pairs.
@arg Class: A class or type (C{class}). @kwarg name_value_pairs: One or more C{B{name}=value} pairs with the C{value} to be checked.
@raise TypeError: At least one of the B{C{name_value_pairs}} is not a sub-class of B{C{Class}}. ''' raise _TypesError(n, v, Class)
'''(INTERNAL) Check the C{package} version vs B{C{required}}. ''' t = _SPACE_(package.__name__, _version_, _DOT_(*t), 'below', _DOT_(*required), _required_, _by_, _xwhere(where, **name)) raise ImportError(t)
'''(INTERNAL) Get the fully qualified name. '''
# **) MIT License # # Copyright (C) 2016-2022 -- mrJean1 at Gmail -- All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. |