# Coverage for pygeodesy/interns.py : 95%

## 423 statements 403 run 20 missing 20 excluded

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

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 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | # -*- coding: utf-8 -*- u'''Single C{str}ing constants, C{intern}'ed across C{pygeodesy} modules and function L{pygeodesy.machine}. ''' _COMMASPACE_ = ', ' # overriden below _pl2List = None # cached _platform2 lists _Py3List = None # cached _pythonarchine lists class _Dash(str): '''(INTERNAL) Extended C{str} for prefix_DASH_. ''' def __call__(self, *args): '''Join C{self} plus all B{C{args}} like C{'-'.join((self,) + B{args})}. ''' return _DASH_(self, *args) # re-callable class _Int(int): '''(INTERNAL) Unique C{int}. ''' pass class Str_(str): '''Extended, I{callable} C{str} class, not nameable. @see: Nameable and callable class L{pygeodesy.Str}. ''' def join_(self, *args): '''Join all positional B{C{args}} like C{self.join(B{args})}. @return: All B{C{args}} joined by this instance (L{Str_}). @note: An other L{Str_} instance is returned to make the result re-callable. ''' return Str_(str.join(self, map(str, args))) # re-callable __call__ = join_ class _Prefix(Str_): '''(INTERNAL) Extended C{str} for prefix. ''' def __call__(self, *args): '''Join C{self} plus all B{C{args}} like C{" ".join((self,) + B{args})}. ''' return _SPACE_.join_(self, *args) # re-callable class _Python_(str): # overwritten by singleton below '''(INTERNAL) Extended C{str} for C{"Python"} and version. ''' def __call__(self, version=None): '''Return C{"Python <version>"}. ''' if not version: from sys import version return _SPACE_(self, version.split(None, 1)[0]) class _Range(str): '''(INTERNAL) Extended C{str} for C{range} strings. ''' def __call__(self, lo, hi, lopen=False, ropen=False, prec=0, sep=_COMMASPACE_): '''Return the range as C{"(lo, hi)"}, C{"(lo, hi]"}, C{"[lo, hi)"} or C{"[lo, hi]"}. ''' from pygeodesy.streprs import Fmt r = NN(Fmt.f(lo, prec=prec), sep, Fmt.f(hi, prec=prec)) if lopen: r = Fmt.PAREN(r) if ropen else Fmt.LOPEN(r) else: r = Fmt.ROPEN(r) if ropen else Fmt.SQUARE(r) return r class _Slicer(str): '''(INTERNAL) String slicer C{.fromX} or C{.tillY}. ''' def __getattr__(self, name): # .fromX, .tillY if name.startswith(_till_): i = self.find(name[len(_till_):]) if 0 < i < len(self): return _Slicer(self[:i + 1]) elif name.startswith(_from_): i = self.find(name[len(_from_):]) if 0 < (i + 1) < len(self): return _Slicer(self[i:]) else: return getattr(str, name) return self class MISSING(object): '''(INTERNAL) Singleton C{str}. ''' def toRepr(self, **unused): return self.__class__.__name__ __repr__ = toRepr __str__ = toRepr toStr = toRepr MISSING = MISSING() # PYCHOK singleton MISSING.__name__ = str(MISSING) NN = Str_('') # Nomen Nescio <https://Wiktionary.org/wiki/N.N.> # __DUNDER__-style names would get mangled in classes _0_ = '0' # PYCHOK 'zero' _0to9_ = '0123456789' # PYCHOK OK _1_ = '1' # PYCHOK OK _2_ = '2' # PYCHOK OK _3_ = '3' # PYCHOK OK _4_ = '4' # PYCHOK OK _a_ = 'a' # PYCHOK OK _A_ = 'A' # PYCHOK OK _a12_ = 'a12' # PYCHOK OK _area_ = 'area' # PYCHOK OK _Airy1830_ = 'Airy1830' # PYCHOK OK _AiryModified_ = 'AiryModified' # PYCHOK OK _ambiguous_ = 'ambiguous' # PYCHOK OK _AMPERSAND_ = Str_('&') # PYCHOK OK _an_ = 'an' # PYCHOK OK _and_ = 'and' # PYCHOK OK # _AND_ = _AMPERSAND_ # PYCHOK OK _angle_ = 'angle' # PYCHOK OK _antipodal_ = 'antipodal' # PYCHOK OK _areaOf_ = 'areaOf' # PYCHOK OK _arg_ = 'arg' # PYCHOK OK _at_ = 'at' # PYCHOK OK _AT_ = Str_('@') # PYCHOK OK _AtoZnoIO_ = _Slicer('ABCDEFGHJKLMNPQRSTUVWXYZ') # PYCHOK in C{gars}, C{mgrs} and C{wgrs} _attribute_ = 'attribute' # PYCHOK OK _azi1_ = 'azi1' # PYCHOK OK _azi12_ = 'azi12' # PYCHOK OK _azi2_ = 'azi2' # PYCHOK OK _azimuth_ = 'azimuth' # PYCHOK OK _b_ = 'b' # PYCHOK OK _B_ = 'B' # PYCHOK OK _BACKSLASH_ = Str_('\\') # PYCHOK OK _band_ = 'band' # PYCHOK OK _BANG_ = Str_('!') # PYCHOK OK _BAR_ = Str_('|') # PYCHOK OK _bearing_ = 'bearing' # PYCHOK OK _Bessel1841_ = 'Bessel1841' # PYCHOK OK _by_ = 'by' # PYCHOK OK _c_ = 'c' # PYCHOK OK _C_ = 'C' # PYCHOK OK _cartesian_ = 'cartesian' # PYCHOK OK _center_ = 'center' # PYCHOK OK # _CIRCUMFLEX_ = '^' # PYCHOK OK _Clarke1866_ = 'Clarke1866' # PYCHOK OK _Clarke1880IGN_ = 'Clarke1880IGN' # PYCHOK OK _coincident_ = 'coincident' # PYCHOK OK _colinear_ = 'colinear' # PYCHOK OK _COLON_ = Str_(':') # PYCHOK OK _COLONSPACE_ = Str_(': ') # PYCHOK OK _COMMA_ = Str_(',') # PYCHOK OK _COMMASPACE_ = Str_(_COMMASPACE_) # PYCHOK OK _concentric_ = 'concentric' # PYCHOK OK _convergence_ = _Prefix('convergence') # PYCHOK OK _conversion_ = 'conversion' # PYCHOK OK _convex_ = 'convex' # PYCHOK OK _cubic_ = 'cubic' # PYCHOK OK _d_ = 'd' # PYCHOK OK _D_ = 'D' # PYCHOK OK _DASH_ = Str_('-') # PYCHOK == _MINUS_ _datum_ = 'datum' # PYCHOK OK _decode3_ = 'decode3' # PYCHOK OK _deg_ = 'deg' # PYCHOK OK _degrees_ = 'degrees' # PYCHOK OK _degrees2_ = 'degrees2' # PYCHOK SQUARED _DEPRECATED_ = 'DEPRECATED' # PYCHOK OK _DEQUALSPACED_ = Str_(' == ') # PYCHOK OK _distance_ = 'distance' # PYCHOK OK _distanceTo_ = 'distanceTo' # PYCHOK OK _distant_ = _Prefix('distant') # PYCHOK OK _doesn_t_exist_ = "doesn't exist" # PYCHOK OK _DOT_ = Str_('.') # PYCHOK OK _down_ = 'down' # PYCHOK OK _e_ = 'e' # PYCHOK OK _E_ = 'E' # PYCHOK OK _east_ = 'east' # PYCHOK OK _easting_ = 'easting' # PYCHOK OK _ecef_ = 'ecef' # PYCHOK OK _edge_ = 'edge' # PYCHOK OK _elevation_ = 'elevation' # PYCHOK OK _ELLIPSIS_ = Str_('...') # PYCHOK OK _ELLIPSIS4_ = Str_('....') # PYCHOK OK # _ELLIPSISPACED_ = Str_(' ... ') # PYCHOK <https://www.ThePunctuationGuide.com/ellipses.html> _ellipsoid_ = 'ellipsoid' # PYCHOK OK _ellipsoidal_ = 'ellipsoidal' # PYCHOK OK _enabled_ = 'enabled' # PYCHOK OK _encode_ = 'encode' # PYCHOK OK _end_ = 'end' # PYCHOK OK _epoch_ = 'epoch' # PYCHOK OK _EQUAL_ = Str_('=') # PYCHOK OK _EQUALSPACED_ = Str_(' = ') # PYCHOK OK _Error_ = 'Error' # PYCHOK OK _exceed_PI_radians_ = 'exceed PI radians' # PYCHOK OK _exceeds_ = _Prefix('exceeds') # PYCHOK OK # _EXCLAMATION_ = _BANG_ # PYCHOK OK _exists_ = 'exists' # PYCHOK OK _f_ = 'f' # PYCHOK OK _F_ = 'F' # PYCHOK OK _feet_ = 'feet' # PYCHOK OK _few_ = 'few' # PYCHOK OK _fi_ = 'fi' # PYCHOK OK _finite_ = 'finite' # PYCHOK OK _from_ = 'from' # PYCHOK OK _g_ = 'g' # PYCHOK OK _gamma_ = 'gamma' # PYCHOK OK _GRS80_ = 'GRS80' # PYCHOK OK _h_ = 'h' # PYCHOK OK _H_ = 'H' # PYCHOK OK _height_ = 'height' # PYCHOK OK _hemipole_ = 'hemipole' # PYCHOK OK _i_ = 'i' # PYCHOK OK _I_ = 'I' # PYCHOK OK _iadd_ = '+=' # PYCHOK OK _immutable_ = 'immutable' # PYCHOK OK _in_ = 'in' # PYCHOK OK _incompatible_ = 'incompatible' # PYCHOK OK _INF_ = 'INF' # PYCHOK OK _infinite_ = 'infinite' # PYCHOK _not_finite_ _initial_ = 'initial' # PYCHOK OK _inside_ = 'inside' # PYCHOK OK _intersection_ = 'intersection' # PYCHOK OK _Intl1924_ = 'Intl1924' # PYCHOK OK _invalid_ = 'invalid' # PYCHOK OK _isclockwise_ = 'isclockwise' # PYCHOK OK _ispolar_ = 'ispolar' # PYCHOK OK _j_ = 'j' # PYCHOK OK _k0_ = 'k0' # PYCHOK OK _kind_ = 'kind' # PYCHOK OK _knots_ = 'knots' # PYCHOK OK _Krassovski1940_ = 'Krassovski1940' # PYCHOK OK _Krassowsky1940_ = 'Krassowsky1940' # PYCHOK OK _LANGLE_ = '<' # PYCHOK OK _lam_ = 'lam' # PYCHOK OK _lat_ = 'lat' # PYCHOK OK _lat0_ = 'lat0' # PYCHOK OK _lat1_ = 'lat1' # PYCHOK OK _lat2_ = 'lat2' # PYCHOK OK _latlon_ = 'latlon' # PYCHOK OK _LatLon_ = 'LatLon' # PYCHOK OK _LCURLY_ = '{' # PYCHOK LBRACE _len_ = 'len' # PYCHOK OK _linear_ = 'linear' # PYCHOK OK #_LPAREN_ = '(' # PYCHOK OK _lon_ = 'lon' # PYCHOK OK _lon0_ = 'lon0' # PYCHOK OK _lon1_ = 'lon1' # PYCHOK OK _lon2_ = 'lon2' # PYCHOK OK #_LSQUARE_ = '[' # PYCHOK LBRACK _ltp_ = 'ltp' # PYCHOK OK _m_ = 'm' # PYCHOK OK _M_ = 'M' # PYCHOK OK _m12_ = 'm12' # PYCHOK OK _M12_ = 'M12' # PYCHOK OK _M21_ = 'M21' # PYCHOK OK _MANT_DIG_ = 'MANT_DIG' # PYCHOK OK _MAX_ = 'MAX' # PYCHOK OK _mean_ = 'mean' # PYCHOK OK _meanOf_ = 'meanOf' # PYCHOK OK _meridional_ = 'meridional' # PYCHOK OK _meter_ = 'meter' # PYCHOK OK _meter2_ = 'meter2' # PYCHOK SQUARED _MGRS_ = 'MGRS' # PYCHOK OK _MIN_ = 'MIN' # PYCHOK OK _MINUS_ = _DASH_ # PYCHOK OK _module_ = 'module' # PYCHOK OK _n_ = 'n' # PYCHOK OK _N_ = 'N' # PYCHOK OK _n_a_ = 'n/a' # PYCHOK OK _N_A_ = 'N/A' # PYCHOK OK _NAD27_ = 'NAD27' # PYCHOK OK _NAD83_ = 'NAD83' # PYCHOK OK _name_ = 'name' # PYCHOK OK _NAN_ = 'NAN' # PYCHOK OK _near_ = _Dash('near') # PYCHOK OK _nearestOn2_ = 'nearestOn2' # PYCHOK OK _negative_ = 'negative' # PYCHOK OK _NL_ = Str_('\n') # PYCHOK OK _NLATvar_ = Str_(_NL_ + '@var ') # PYCHOK OK _NLHASH_ = Str_(_NL_ + '# ') # PYCHOK OK # _NLNL_ = _DNL_ # PYCHOK OK _NN_ = 'NN' # PYCHOK OK _no_ = _Prefix('no') # PYCHOK OK _north_ = 'north' # PYCHOK OK _northing_ = 'northing' # PYCHOK OK _NorthPole_ = 'NorthPole' # PYCHOK OK _not_ = _Prefix('not') # PYCHOK OK _NOTEQUAL_ = _BANG_ + _EQUAL_ # PYCHOK OK _not_finite_ = 'not finite' # PYCHOK _not_(_finite_), _infinite_ _not_scalar_ = 'not scalar' # PYCHOK _not_(_scalar_) _NTF_ = 'NTF' # PYCHOK OK _null_ = 'null' # PYCHOK OK _number_ = 'number' # PYCHOK OK _numpy_ = 'numpy' # PYCHOK OK _Nv00_ = 'Nv00' # PYCHOK OK _O_ = 'O' # PYCHOK letter "Oh", not zero _on_ = 'on' # PYCHOK OK _opposite_ = 'opposite' # PYCHOK OK _or_ = 'or' # PYCHOK OK _other_ = 'other' # PYCHOK OK _outside_ = 'outside' # PYCHOK OK _overlap_ = 'overlap' # PYCHOK OK _PERCENT_ = '%' # PYCHOK OK _PERCENTDOTSTAR_ = '%.*' # PYCHOK _DOT_(_PERCENT_, _STAR_) _perimeterOf_ = 'perimeterOf' # PYCHOK OK _phi_ = 'phi' # PYCHOK OK _PLUS_ = Str_('+') # PYCHOK OK _PLUSMINUS_ = _PLUS_ + _MINUS_ # PYCHOK OK _point_ = 'point' # PYCHOK OK _points_ = 'points' # PYCHOK OK _pole_ = 'pole' # PYCHOK OK _precision_ = 'precision' # PYCHOK OK _prime_vertical_ = 'prime_vertical' # PYCHOK OK _pygeodesy_abspath_ = 'pygeodesy_abspath' # PYCHOK OK _PyPy__ = 'PyPy ' # PYCHOK + _SPACE_ _Python_ = _Python_('Python') # PYCHOK singleton _python_ = 'python' # PYCHOK OK _QUOTE1_ = "'" # PYCHOK OK _QUOTE2_ = '"' # PYCHOK OK # _QUOTE3_ = "'''" # PYCHOK OK # _QUOTE6_ = '"""' # PYCHOK OK _R_ = 'R' # PYCHOK OK _radians_ = 'radians' # PYCHOK OK _radians2_ = 'radians2' # PYCHOK SQUARED _radius_ = 'radius' # PYCHOK OK _radius1_ = 'radius1' # PYCHOK OK _radius2_ = 'radius2' # PYCHOK OK _range_ = _Range('range') # PYCHOK OK _RANGLE_ = '>' # PYCHOK OK _RCURLY_ = '}' # PYCHOK RBRACE _reciprocal_ = 'reciprocal' # PYCHOK OK _reframe_ = 'reframe' # PYCHOK OK _resolution_ = 'resolution' # PYCHOK OK _rIn_ = 'rIn' # PYCHOK OK #_RPAREN_ = ')' # PYCHOK OK #_RSQUARE_ = ']' # PYCHOK RBRACK _s_ = 's' # PYCHOK OK _S_ = 'S' # PYCHOK OK _s12_ = 's12' # PYCHOK OK _S12_ = 'S12' # PYCHOK OK _scalar_ = 'scalar' # PYCHOK OK _scale_ = 'scale' # PYCHOK OK _scale0_ = 'scale0' # PYCHOK OK _scipy_ = 'scipy' # PYCHOK OK _semi_circular_ = 'semi-circular' # PYCHOK OK _sep_ = 'sep' # PYCHOK OK _sets_ = 'sets' # PYCHOK OK _singular_ = 'singular' # PYCHOK OK _SLASH_ = Str_('/') # PYCHOK OK _small_ = 'small' # PYCHOK OK _Sphere_ = 'Sphere' # PYCHOK OK _spherical_ = 'spherical' # PYCHOK OK _SouthPole_ = 'SouthPole' # PYCHOK OK _SPACE_ = Str_(' ') # PYCHOK OK _specified_ = 'specified' # PYCHOK OK _STAR_ = Str_('*') # PYCHOK OK _start_ = 'start' # PYCHOK OK _std_ = 'std' # PYCHOK OK _stdev_ = 'stdev' # PYCHOK OK _supported_ = 'supported' # PYCHOK OK _sx_ = 'sx' # PYCHOK OK _sy_ = 'sy' # PYCHOK OK _sz_ = 'sz' # PYCHOK OK _tbd_ = 'tbd' # PYCHOK OK _TILDE_ = '~' # PYCHOK OK _till_ = 'till' # PYCHOK OK _to_ = 'to' # PYCHOK OK _tolerance_ = _Prefix('tolerance') # PYCHOK OK _too_ = _Prefix('too') # PYCHOK OK _transform_ = 'transform' # PYCHOK OK _tx_ = 'tx' # PYCHOK OK _ty_ = 'ty' # PYCHOK OK _tz_ = 'tz' # PYCHOK OK _UNDER_ = Str_('_') # PYCHOK OK def _UNDER(name): # PYCHOK in .datums, .rhumbx, .ups, .utm, .utmupsBase '''(INTERNAL) Prefix C{name} with I{underscore}. ''' return name if name.startswith(_UNDER_) else NN(_UNDER_, name) _units_ = 'units' # PYCHOK OK _up_ = 'up' # PYCHOK OK _UPS_ = 'UPS' # PYCHOK OK _utf_8_ = 'utf-8' # PYCHOK OK _UTM_ = 'UTM' # PYCHOK OK _V_ = 'V' # PYCHOK OK _valid_ = 'valid' # PYCHOK OK _value_ = 'value' # PYCHOK OK _version_ = 'version' # PYCHOK OK _vs_ = 'vs' # PYCHOK OK _W_ = 'W' # PYCHOK OK _WGS72_ = 'WGS72' # PYCHOK OK _WGS84_ = 'WGS84' # PYCHOK OK _width_ = 'width' # PYCHOK OK _with_ = 'with' # PYCHOK OK _x_ = 'x' # PYCHOK OK _X_ = 'X' # PYCHOK OK _xyz_ = 'xyz' # PYCHOK OK _y_ = 'y' # PYCHOK OK _Y_ = 'Y' # PYCHOK OK _z_ = 'z' # PYCHOK OK _Z_ = 'Z' # PYCHOK OK _zone_ = 'zone' # PYCHOK OK _EW_ = _E_ + _W_ # PYCHOK common cardinals _NE_ = _N_ + _E_ # PYCHOK positive ones _NS_ = _N_ + _S_ # PYCHOK OK _NSEW_ = _NS_ + _EW_ # PYCHOK OK _NW_ = _N_ + _W_ # PYCHOK OK _SE_ = _S_ + _E_ # PYCHOK OK _SW_ = _S_ + _W_ # PYCHOK negative ones # _NESW_ = _NE_ + _SW_ # PYCHOK clockwise _DDOT_ = Str_(_DOT_ * 2) # PYCHOK OK # _DEQUAL_ = Str_(_EQUAL_ * 2) # PYCHOK OK _DNL_ = Str_(_NL_ * 2) # PYCHOK OK # _DSLASH_ = Str_(_SLASH_ * 2) # PYCHOK OK # _DSTAR_ = Str_(_STAR_ * 2) # PYCHOK OK _DUNDER_ = Str_(_UNDER_ * 2) # PYCHOK OK def _dunder_nameof(inst, *dflt): '''(INTERNAL) Get the double_underscore __name__ attr. ''' try: return inst.__name__ except AttributeError: pass return dflt[0] if dflt else inst.__class__.__name__ def _enquote(strs, quote=_QUOTE2_): # in .basics '''(INTERNAL) Enquote a string containing whitespace. ''' if len(strs.split()) > 1: strs = NN(quote, strs, quote) return strs def _load_lib(name): '''(INTERNAL) Load a C{dylib}, B{C{name}} must startwith('lib'). ''' # macOS 11+ (aka 10.16) no longer provides direct loading of # system libraries, instead it installs the library after a # low-level dlopen(name) call where name is the library base # name. As a result, ctypes.util.find_library can not find # any library not previously dlopen'ed. from ctypes import CDLL from ctypes.util import find_library from sys import platform ns = find_library(name), name if platform[:6] == 'darwin': # and os.name == 'posix' from ctypes import _dlopen from os.path import join ns += (_DOT_(name, 'dylib'), _DOT_(name, 'framework'), join( _DOT_(name, 'framework'), name)) else: # non-macOS def _dlopen(unused): return True for n in ns: try: if n and _dlopen(n): # handle lib = CDLL(n) # == ctypes.cdll.LoadLibrary(n) if lib._name: # has a qualified name return lib except (AttributeError, OSError): pass return None # raise OSError def machine(): '''Return standard C{platform.machine}, but distinguishing Intel I{native} from Intel I{emulation} on Apple Silicon (on macOS only). @return: Machine C{'arm64'} for Apple Silicon I{native}, C{'x86_64'} for Intel I{native}, C{"arm64_x86_64"} for Intel I{emulation}, etc. (C{str} with C{comma}s replaced by C{underscore}s). ''' return _platform2()[1] def _platform2(sep=NN): '''(INTERNAL) Get platform architecture and machine as C{2-list} or C{str}. ''' global _pl2List if _pl2List is None: import platform m = platform.machine() # ARM64, arm64, x86_64, iPhone13,2, etc. m = m.replace(_COMMA_, _UNDER_) if m.lower() == 'x86_64': # on Intel or Rosetta2 ... v = platform.mac_ver() # ... and only on macOS ... if v and _version2(v[0]) > (10, 15): # ... 11+ aka 10.16 # <https://Developer.Apple.com/forums/thread/659846> if _sysctl_uint('sysctl.proc_translated') == 1: # and \ \ # _sysctl_uint('hw.optional.arm64') == 1: # PYCHOK indent m = _UNDER_('arm64', m) # Apple Si emulating Intel x86-64 _pl2List = [platform.architecture()[0], # bits m] # arm64, arm64_x86_64, x86_64, etc. return sep.join(_pl2List) if sep else _pl2List # 2-list() def _pythonarchine(sep=NN): # in test/base.py versions '''(INTERNAL) Get PyPy and Python versions and C{_platform2} as C{3-} or C{4-list} or C{str}. ''' global _Py3List if _Py3List is None: from sys import version # XXX shadows? _Py3List = [_Python_(version)] + _platform2() if _PyPy__ in version: # see test/base.py v = version.split(_PyPy__)[1].split(None, 1)[0] _Py3List.insert(0, NN(_PyPy__, v)) return sep.join(_Py3List) if sep else _Py3List # 3- or 4-list def _splituple(strs, *sep_splits): # in .basics, .mgrs '''(INTERNAL) Split a C{comma}- or C{whitespace}-separated string into a C{tuple} of stripped strings. ''' t = (strs.split(*sep_splits) if sep_splits else strs.replace(_COMMA_, _SPACE_).split()) if strs else () return tuple(s.strip() for s in t if s) def _sysctl_uint(name): '''(INTERNAL) Get an unsigned int sysctl item by name, use on macOS ONLY! ''' libc = _load_lib('libc') if libc: # <https://StackOverflow.com/questions/759892/python-ctypes-and-sysctl> from ctypes import byref, c_char_p, c_size_t, c_uint, sizeof # get_errno n = name if str is bytes else bytes(name, _utf_8_) # PYCHOK isPython2 = str is bytes u = c_uint(0) z = c_size_t(sizeof(u)) r = libc.sysctlbyname(c_char_p(n), byref(u), byref(z), None, c_size_t(0)) else: # could find or load 'libc' r = -2 return int(r if r else u.value) # -1 ENOENT error, -2 no libc def _usage(file_py, *args): # in .etm '''(INTERNAL) Build "usage: python -m ..." cmd line for module B{C{file_py}}. ''' import os, sys # PYCHOK imports p = NN(_python_, sys.version_info[0]) m = os.path.dirname(file_py).replace(os.getcwd(), _ELLIPSIS_) \ .replace(os.sep, _DOT_).strip() b, x = os.path.splitext(os.path.basename(file_py)) if x == '.py' and b != '__main__': m = _DOT_(m, b) return NN('usage', _SPACE_(_COLON_, p, '-m', _enquote(m), *args)) def _version2(version, n=2): '''(INTERNAL) Split C{B{version} str} into 1-, 2- or 3-tuple of C{int}s. ''' def _int(*vs): for v in vs: try: yield int(v) except (TypeError, ValueError): pass t = tuple(_int(*_splituple(version, _DOT_, 2))) + (0,) * n return t[:n] __all__ = (_NN_, # not MISSING! Str_.__name__, # classes machine.__name__) # in .lazily __version__ = '22.10.05' if __name__ == '__main__': from pygeodesy.errors import itemsorted from pygeodesy.lazily import printf t = b = 0 for n, v in itemsorted(locals(), asorted=False, reverse=True): if n.startswith(_UNDER_) and n.endswith(_UNDER_) and \ not n.startswith(_DUNDER_): t += 1 b += len(v) m = n[1:-1] if m != v and m.replace(_UNDER_, _SPACE_) != v: printf('%4d: %s = %r', t, n, v) n = len(locals()) printf('%4d (%d) names, %s chars total, %.2f chars avg', t, n, b, float(b) / t, nl=1) # **) 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.