Coverage for pygeodesy/interns.py: 97%

451 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2024-05-06 16:50 -0400

1# -*- coding: utf-8 -*- 

2 

3u'''Single C{str}ing constants, C{intern}'ed across C{pygeodesy} 

4modules and function L{pygeodesy.machine}. 

5''' 

6import sys as _sys 

7try: 

8 _intern = intern # PYCHOK in .lazily 

9except NameError: # Python 3+ 

10 _intern = _sys.intern 

11 

12_COMMASPACE_ = ', ' # overriden below 

13_pf2List = [] # cached _platform2 list 

14_Py3List = [] # cached _pythonarchine list 

15 

16_sub_packages = 'auxilats', 'deprecated', 'geodesicx', 'rhumb' # PYCHOK in .lazily, 

17# ... make._dist, MANIFEST, setup.setup, test.bases, test.testModules 

18 

19 

20class _Dash(str): 

21 '''(INTERNAL) Extended C{str} for prefix_DASH_. 

22 ''' 

23 def __call__(self, *args): 

24 '''Join C{self} plus all B{C{args}} like C{'-'.join((self,) + B{args})}. 

25 ''' 

26 return _DASH_(self, *args) # re-callable 

27 

28 

29class _Int(int): 

30 '''(INTERNAL) Unique C{int}. 

31 ''' 

32 pass 

33 

34 

35class Str_(str): 

36 '''Extended, I{callable} C{str} class, not nameable. 

37 

38 @see: Nameable and callable class L{pygeodesy.Str}. 

39 ''' 

40 def join_(self, *args): 

41 '''Join all positional B{C{args}} like C{self.join(B{args})}. 

42 

43 @return: All B{C{args}} joined by this instance (L{Str_}). 

44 

45 @note: An other L{Str_} instance is returned to make the 

46 result re-callable. 

47 ''' 

48 return Str_(str.join(self, map(str, args))) # re-callable 

49 

50 __call__ = join_ 

51 

52NN = Str_('') # PYCHOK Nomen Nescio <https://Wiktionary.org/wiki/N.N.> 

53 

54 

55class _Prefix(Str_): 

56 '''(INTERNAL) Extended C{str} for prefix. 

57 ''' 

58 def __call__(self, *args): 

59 '''Join C{self} plus all B{C{args}} like C{" ".join((self,) + B{args})}. 

60 ''' 

61 return _SPACE_.join_(self, *args) # re-callable 

62 

63 

64class _PyPy__(str): # overwritten by singleton below 

65 '''(INTERNAL) Extended C{str} for C{"PyPy"} and version. 

66 ''' 

67 def __call__(self, version=NN): 

68 '''Return C{"PyPy <version>"} or C{NN}. 

69 ''' 

70 v = version or _sys.version 

71 if _PyPy__ in v: 

72 v = v.split(_PyPy__)[1].split(None, 1)[0] # == _DOT_.join(_sys.pypy_version_info[:3]) 

73 return NN(_PyPy__, v) 

74 else: 

75 return NN 

76 

77 

78class _Python_(str): # overwritten by singleton below 

79 '''(INTERNAL) Extended C{str} for C{"Python"} and version. 

80 ''' 

81 def __call__(self, version=NN): 

82 '''Return C{"Python <version>"}. 

83 ''' 

84 v = version or _sys.version 

85 return _SPACE_(self, v.split(None, 1)[0]) 

86 

87 

88class _Range(str): 

89 '''(INTERNAL) Extended C{str} for C{range} strings. 

90 ''' 

91 def __call__(self, lo, hi, lopen=False, ropen=False, 

92 prec=0, sep=_COMMASPACE_): 

93 '''Return the range as C{"(lo, hi)"}, C{"(lo, hi]"}, 

94 C{"[lo, hi)"} or C{"[lo, hi]"}. 

95 ''' 

96 from pygeodesy.streprs import Fmt 

97 r = NN(Fmt.f(lo, prec=prec), sep, 

98 Fmt.f(hi, prec=prec)) 

99 f = (Fmt.PAREN if ropen else Fmt.LOPEN) if lopen else \ 

100 (Fmt.ROPEN if ropen else Fmt.SQUARE) 

101 return f(r) 

102 

103 

104class _Slicer(str): 

105 '''(INTERNAL) String slicer C{.fromX} or C{.tillY}. 

106 ''' 

107 def __getattr__(self, name): # .fromX, .tillY 

108 n = len(name) - 4 

109 if n > 0: 

110 # assert len('till') == len(_from_) == 4 

111 if name.startswith('till'): 

112 i = self.find(name[4:]) 

113 return self if i < 0 else _Slicer(self[:i + n]) 

114 elif name.startswith(_from_): 

115 i = self.find(name[4:]) 

116 return self if i < 0 else _Slicer(self[i:]) 

117 return str.__getattr__(self, name) # PYCHOK no cover 

118 

119 

120class MISSING(object): 

121 '''(INTERNAL) Singleton C{str}. 

122 ''' 

123 def toRepr(self, **unused): 

124 return self.__class__.__name__ 

125 

126 __repr__ = __str__ = toStr = toRepr 

127 

128MISSING = MISSING() # PYCHOK singleton 

129MISSING.__name__ = str(MISSING) 

130 

131# __DUNDER__-style names would get mangled in classes 

132_0_ = '0' # PYCHOK 'zero' 

133_0to9_ = '0123456789' # PYCHOK OK 

134_1_ = '1' # PYCHOK OK 

135_2_ = '2' # PYCHOK OK 

136_3_ = '3' # PYCHOK OK 

137_4_ = '4' # PYCHOK OK 

138_a_ = 'a' # PYCHOK OK 

139_A_ = 'A' # PYCHOK OK 

140_a12_ = 'a12' # PYCHOK OK 

141_area_ = 'area' # PYCHOK OK 

142_Airy1830_ = 'Airy1830' # PYCHOK OK 

143_AiryModified_ = 'AiryModified' # PYCHOK OK 

144_ambiguous_ = 'ambiguous' # PYCHOK OK 

145_AMPERSAND_ = Str_('&') # PYCHOK OK 

146_an_ = 'an' # PYCHOK OK 

147_and_ = 'and' # PYCHOK OK 

148# _AND_ = _AMPERSAND_ # PYCHOK OK 

149_angle_ = 'angle' # PYCHOK OK 

150_antipodal_ = 'antipodal' # PYCHOK OK 

151_areaOf_ = 'areaOf' # PYCHOK OK 

152_arg_ = 'arg' # PYCHOK OK 

153# _ASTERISK_ = _STAR_ # PYCHOK OK 

154_AT_ = Str_('@') # PYCHOK OK 

155_AtoZnoIO_ = _Slicer('ABCDEFGHJKLMNPQRSTUVWXYZ') # PYCHOK in .gars, .mgrs and .wgrs 

156_attribute_ = 'attribute' # PYCHOK OK 

157_azi1_ = 'azi1' # PYCHOK OK 

158_azi12_ = 'azi12' # PYCHOK OK 

159_azi2_ = 'azi2' # PYCHOK OK 

160_azimuth_ = 'azimuth' # PYCHOK OK 

161_b_ = 'b' # PYCHOK OK 

162_B_ = 'B' # PYCHOK OK 

163_BACKSLASH_ = Str_('\\') # PYCHOK OK 

164_band_ = 'band' # PYCHOK OK 

165_BANG_ = Str_('!') # PYCHOK OK 

166_BAR_ = Str_('|') # PYCHOK OK 

167_bearing_ = 'bearing' # PYCHOK OK 

168_Bessel1841_ = 'Bessel1841' # PYCHOK OK 

169_beta_ = 'beta' # PYCHOK OK 

170_by_ = 'by' # PYCHOK OK 

171_c_ = 'c' # PYCHOK OK 

172_C_ = 'C' # PYCHOK OK 

173_cartesian_ = 'cartesian' # PYCHOK OK 

174_center_ = 'center' # PYCHOK OK 

175# _CIRCUMFLEX_ = Str_('^') # PYCHOK OK 

176_Clarke1866_ = 'Clarke1866' # PYCHOK OK 

177_Clarke1880IGN_ = 'Clarke1880IGN' # PYCHOK OK 

178_clip_ = 'clip' # PYCHOK OK 

179_clipid_ = 'clipid' # PYCHOK OK 

180_coincident_ = 'coincident' # PYCHOK OK 

181_colinear_ = 'colinear' # PYCHOK OK 

182_COLON_ = Str_(':') # PYCHOK OK 

183_COLONSPACE_ = Str_(': ') # PYCHOK OK 

184_COMMA_ = Str_(',') # PYCHOK OK 

185_COMMASPACE_ = Str_(_COMMASPACE_) # PYCHOK OK 

186_composite_ = 'composite' # PYCHOK OK 

187_concentric_ = 'concentric' # PYCHOK OK 

188_convergence_ = _Prefix('convergence') # PYCHOK OK 

189_conversion_ = 'conversion' # PYCHOK OK 

190_convex_ = 'convex' # PYCHOK OK 

191_cubic_ = 'cubic' # PYCHOK OK 

192_d_ = 'd' # PYCHOK OK 

193_D_ = 'D' # PYCHOK OK 

194_DASH_ = Str_('-') # PYCHOK == _MINUS_ 

195_datum_ = 'datum' # PYCHOK OK 

196_decode3_ = 'decode3' # PYCHOK OK 

197_deg_ = 'deg' # PYCHOK OK 

198_degrees_ = 'degrees' # PYCHOK OK 

199_degrees2_ = 'degrees2' # PYCHOK SQUARED 

200_delta_ = 'delta' # PYCHOK OK 

201_DEPRECATED_ = 'DEPRECATED' # PYCHOK OK 

202_DEQUALSPACED_ = Str_(' == ') # PYCHOK OK 

203_distance_ = 'distance' # PYCHOK OK 

204_distant_ = _Prefix('distant') # PYCHOK OK 

205_doesn_t_exist_ = "doesn't exist" # PYCHOK OK 

206_DOT_ = Str_('.') # PYCHOK OK 

207_down_ = 'down' # PYCHOK OK 

208_e_ = 'e' # PYCHOK OK 

209_E_ = 'E' # PYCHOK OK 

210_earth_ = 'earth' # PYCHOK OK 

211_east_ = 'east' # PYCHOK OK 

212_easting_ = 'easting' # PYCHOK OK 

213_ecef_ = 'ecef' # PYCHOK OK 

214_edge_ = 'edge' # PYCHOK OK 

215_elevation_ = 'elevation' # PYCHOK OK 

216_ELLIPSIS_ = Str_('...') # PYCHOK OK 

217_ELLIPSIS4_ = Str_('....') # PYCHOK OK 

218# _ELLIPSISPACED_ = Str_(' ... ') # PYCHOK <https://www.ThePunctuationGuide.com/ellipses.html> 

219_ellipsoid_ = 'ellipsoid' # PYCHOK OK 

220_ellipsoidal_ = 'ellipsoidal' # PYCHOK OK 

221_enabled_ = 'enabled' # PYCHOK OK 

222_encode_ = 'encode' # PYCHOK OK 

223_end_ = 'end' # PYCHOK OK 

224_epoch_ = 'epoch' # PYCHOK OK 

225_eps_ = 'eps' # PYCHOK OK 

226_EQUAL_ = Str_('=') # PYCHOK OK 

227_EQUALSPACED_ = Str_(' = ') # PYCHOK OK 

228_Error_ = 'Error' # PYCHOK OK 

229_exceed_PI_radians_ = 'exceed PI radians' # PYCHOK OK 

230_exceeds_ = _Prefix('exceeds') # PYCHOK OK 

231# _EXCLAMATION_ = _BANG_ # PYCHOK OK 

232_exists_ = 'exists' # PYCHOK OK 

233_f_ = 'f' # PYCHOK OK 

234_F_ = 'F' # PYCHOK OK 

235_feet_ = 'feet' # PYCHOK OK 

236_few_ = 'few' # PYCHOK OK 

237_fi_ = 'fi' # PYCHOK OK 

238_finite_ = 'finite' # PYCHOK OK 

239_from_ = 'from' # PYCHOK OK 

240_g_ = 'g' # PYCHOK OK 

241_gamma_ = 'gamma' # PYCHOK OK 

242_GRS80_ = 'GRS80' # PYCHOK OK 

243_h_ = 'h' # PYCHOK OK 

244_H_ = 'H' # PYCHOK OK 

245_HASH_ = '#' # PYCHOK OK 

246_height_ = 'height' # PYCHOK OK 

247_hemipole_ = 'hemipole' # PYCHOK OK 

248_i_ = 'i' # PYCHOK OK 

249_immutable_ = 'immutable' # PYCHOK OK 

250_in_ = 'in' # PYCHOK OK 

251_incompatible_ = 'incompatible' # PYCHOK OK 

252_INF_ = 'INF' # PYCHOK OK 

253_infinite_ = 'infinite' # PYCHOK _not_finite_ 

254_initial_ = 'initial' # PYCHOK OK 

255_inside_ = 'inside' # PYCHOK OK 

256_insufficient_ = 'insufficient' # PYCHOK OK 

257_intersection_ = 'intersection' # PYCHOK OK 

258_Intl1924_ = 'Intl1924' # PYCHOK OK 

259_invalid_ = 'invalid' # PYCHOK OK 

260_invokation_ = 'invokation' # PYCHOK OK 

261_isclockwise_ = 'isclockwise' # PYCHOK OK 

262_ispolar_ = 'ispolar' # PYCHOK OK 

263_j_ = 'j' # PYCHOK OK 

264_k0_ = 'k0' # PYCHOK OK 

265_kind_ = 'kind' # PYCHOK OK 

266_knots_ = 'knots' # PYCHOK OK 

267_Krassovski1940_ = 'Krassovski1940' # PYCHOK OK 

268_Krassowsky1940_ = 'Krassowsky1940' # PYCHOK OK 

269_LANGLE_ = '<' # PYCHOK OK 

270_lam_ = 'lam' # PYCHOK OK 

271_lat_ = 'lat' # PYCHOK OK 

272_lat0_ = 'lat0' # PYCHOK OK 

273_lat1_ = 'lat1' # PYCHOK OK 

274_lat2_ = 'lat2' # PYCHOK OK 

275_latlon_ = 'latlon' # PYCHOK OK 

276_LatLon_ = 'LatLon' # PYCHOK OK 

277_LCURLY_ = '{' # PYCHOK LBRACE 

278_len_ = 'len' # PYCHOK OK 

279_limit_ = 'limit' # PYCHOK OK 

280_line_ = 'line' # PYCHOK OK 

281_linear_ = 'linear' # PYCHOK OK 

282_LPAREN_ = '(' # PYCHOK OK 

283_lon_ = 'lon' # PYCHOK OK 

284_lon0_ = 'lon0' # PYCHOK OK 

285_lon1_ = 'lon1' # PYCHOK OK 

286_lon2_ = 'lon2' # PYCHOK OK 

287_low_ = 'low' # PYCHOK OK 

288_LSQUARE_ = '[' # PYCHOK LBRACK 

289_ltp_ = 'ltp' # PYCHOK OK 

290_m_ = 'm' # PYCHOK OK 

291_M_ = 'M' # PYCHOK OK 

292_m12_ = 'm12' # PYCHOK OK 

293_M12_ = 'M12' # PYCHOK OK 

294_M21_ = 'M21' # PYCHOK OK 

295_MANT_DIG_ = 'MANT_DIG' # PYCHOK OK 

296_MAX_ = 'MAX' # PYCHOK OK 

297_mean_ = 'mean' # PYCHOK OK 

298_meanOf_ = 'meanOf' # PYCHOK OK 

299_meridional_ = 'meridional' # PYCHOK OK 

300_meter_ = 'meter' # PYCHOK OK 

301_meter2_ = 'meter2' # PYCHOK SQUARED 

302_MGRS_ = 'MGRS' # PYCHOK OK 

303_MIN_ = 'MIN' # PYCHOK OK 

304_MINUS_ = _DASH_ # PYCHOK OK 

305_module_ = 'module' # PYCHOK OK 

306_n_ = 'n' # PYCHOK OK 

307_N_ = 'N' # PYCHOK OK 

308_n_a_ = 'n/a' # PYCHOK OK 

309_N_A_ = 'N/A' # PYCHOK OK 

310_NAD27_ = 'NAD27' # PYCHOK OK 

311_NAD83_ = 'NAD83' # PYCHOK OK 

312_name_ = 'name' # PYCHOK OK 

313_NAN_ = 'NAN' # PYCHOK OK 

314_near_ = _Dash('near') # PYCHOK OK 

315_nearestOn2_ = 'nearestOn2' # PYCHOK OK 

316_negative_ = 'negative' # PYCHOK OK 

317_NL_ = Str_('\n') # PYCHOK OK 

318_NLATvar_ = Str_(_NL_ + '@var ') # PYCHOK OK 

319_NLHASH_ = Str_(_NL_ + '# ') # PYCHOK OK 

320# _NLNL_ = _DNL_ # PYCHOK OK 

321_NN_ = 'NN' # PYCHOK OK 

322_no_ = _Prefix('no') # PYCHOK OK 

323_north_ = 'north' # PYCHOK OK 

324_northing_ = 'northing' # PYCHOK OK 

325_NorthPole_ = 'NorthPole' # PYCHOK OK 

326_not_ = _Prefix('not') # PYCHOK OK 

327_NOTEQUAL_ = _BANG_ + _EQUAL_ # PYCHOK OK 

328_not_finite_ = 'not finite' # PYCHOK _not_(_finite_), _infinite_ 

329_not_scalar_ = 'not scalar' # PYCHOK _not_(_scalar_) 

330_NTF_ = 'NTF' # PYCHOK OK 

331_null_ = 'null' # PYCHOK OK 

332_number_ = 'number' # PYCHOK OK 

333_numpy_ = 'numpy' # PYCHOK OK 

334_Nv00_ = 'Nv00' # PYCHOK OK 

335_of_ = 'of' # PYCHOK OK 

336_on_ = 'on' # PYCHOK OK 

337_opposite_ = 'opposite' # PYCHOK OK 

338_or_ = 'or' # PYCHOK OK 

339_other_ = 'other' # PYCHOK OK 

340_outside_ = 'outside' # PYCHOK OK 

341_overlap_ = 'overlap' # PYCHOK OK 

342_parallel_ = 'parallel' # PYCHOK OK 

343_PERCENT_ = '%' # PYCHOK OK 

344_PERCENTDOTSTAR_ = '%.*' # PYCHOK _DOT_(_PERCENT_, _STAR_) 

345_phi_ = 'phi' # PYCHOK OK 

346_PLUS_ = Str_('+') # PYCHOK OK 

347_PLUSMINUS_ = _PLUS_ + _MINUS_ # PYCHOK OK 

348_point_ = 'point' # PYCHOK OK 

349_points_ = 'points' # PYCHOK OK 

350_pole_ = 'pole' # PYCHOK OK 

351_precision_ = 'precision' # PYCHOK OK 

352_prime_vertical_ = 'prime_vertical' # PYCHOK OK 

353_pygeodesy_ = 'pygeodesy' # PYCHOK OK 

354_pygeodesy_abspath_ = 'pygeodesy_abspath' # PYCHOK OK 

355_PyPy__ = _PyPy__('PyPy ') # PYCHOK + _SPACE_ 

356_Python_ = _Python_('Python') # PYCHOK singleton 

357_python_ = 'python' # PYCHOK OK 

358_QUOTE1_ = "'" # PYCHOK OK 

359_QUOTE2_ = '"' # PYCHOK OK 

360# _QUOTE3_ = "'''" # PYCHOK OK 

361# _QUOTE6_ = '"""' # PYCHOK OK 

362_R_ = 'R' # PYCHOK OK 

363_radians_ = 'radians' # PYCHOK OK 

364_radians2_ = 'radians2' # PYCHOK SQUARED 

365_radius_ = 'radius' # PYCHOK OK 

366_radius1_ = 'radius1' # PYCHOK OK 

367_radius2_ = 'radius2' # PYCHOK OK 

368_range_ = _Range('range') # PYCHOK OK 

369_RANGLE_ = '>' # PYCHOK OK 

370_RCURLY_ = '}' # PYCHOK RBRACE 

371_reciprocal_ = 'reciprocal' # PYCHOK OK 

372_reframe_ = 'reframe' # PYCHOK OK 

373_resolution_ = 'resolution' # PYCHOK OK 

374_rIn_ = 'rIn' # PYCHOK OK 

375_RPAREN_ = ')' # PYCHOK OK 

376_RSQUARE_ = ']' # PYCHOK RBRACK 

377_s_ = 's' # PYCHOK OK 

378_S_ = 'S' # PYCHOK OK 

379_s12_ = 's12' # PYCHOK OK 

380_S12_ = 'S12' # PYCHOK OK 

381_scalar_ = 'scalar' # PYCHOK OK 

382_scale_ = 'scale' # PYCHOK OK 

383_scale0_ = 'scale0' # PYCHOK OK 

384_scipy_ = 'scipy' # PYCHOK OK 

385_semi_circular_ = 'semi-circular' # PYCHOK OK 

386_sep_ = 'sep' # PYCHOK OK 

387_singular_ = 'singular' # PYCHOK OK 

388_SLASH_ = Str_('/') # PYCHOK OK 

389_small_ = 'small' # PYCHOK OK 

390_Sphere_ = 'Sphere' # PYCHOK OK 

391_spherical_ = 'spherical' # PYCHOK OK 

392_SouthPole_ = 'SouthPole' # PYCHOK OK 

393_SPACE_ = Str_(' ') # PYCHOK OK 

394_specified_ = 'specified' # PYCHOK OK 

395_STAR_ = Str_('*') # PYCHOK OK 

396_start_ = 'start' # PYCHOK OK 

397_std_ = 'std' # PYCHOK OK 

398_stdev_ = 'stdev' # PYCHOK OK 

399_supported_ = 'supported' # PYCHOK OK 

400_tbd_ = 'tbd' # PYCHOK OK 

401_TILDE_ = '~' # PYCHOK OK 

402_to_ = 'to' # PYCHOK OK 

403_tolerance_ = _Prefix('tolerance') # PYCHOK OK 

404_too_ = _Prefix('too') # PYCHOK OK 

405_transform_ = 'transform' # PYCHOK OK 

406_UNDER_ = Str_('_') # PYCHOK OK 

407_units_ = 'units' # PYCHOK OK 

408_UNUSED_ = 'UNUSED' # PYCHOK OK 

409_up_ = 'up' # PYCHOK OK 

410_UPS_ = 'UPS' # PYCHOK OK 

411_utf_8_ = 'utf-8' # PYCHOK OK 

412_UTM_ = 'UTM' # PYCHOK OK 

413_V_ = 'V' # PYCHOK OK 

414_valid_ = 'valid' # PYCHOK OK 

415_value_ = 'value' # PYCHOK OK 

416_version_ = 'version' # PYCHOK OK 

417_vs_ = 'vs' # PYCHOK OK 

418_W_ = 'W' # PYCHOK OK 

419_WGS72_ = 'WGS72' # PYCHOK OK 

420_WGS84_ = 'WGS84' # PYCHOK OK 

421_width_ = 'width' # PYCHOK OK 

422_with_ = 'with' # PYCHOK OK 

423_x_ = 'x' # PYCHOK OK 

424_X_ = 'X' # PYCHOK OK 

425_xyz_ = 'xyz' # PYCHOK OK 

426_y_ = 'y' # PYCHOK OK 

427_Y_ = 'Y' # PYCHOK OK 

428_z_ = 'z' # PYCHOK OK 

429_Z_ = 'Z' # PYCHOK OK 

430_zone_ = 'zone' # PYCHOK OK 

431 

432_EW_ = _E_ + _W_ # PYCHOK common cardinals 

433_NE_ = _N_ + _E_ # PYCHOK positive ones 

434_NS_ = _N_ + _S_ # PYCHOK OK 

435_NSEW_ = _NS_ + _EW_ # PYCHOK OK 

436_NW_ = _N_ + _W_ # PYCHOK OK 

437_SE_ = _S_ + _E_ # PYCHOK OK 

438_SW_ = _S_ + _W_ # PYCHOK negative ones 

439# _NESW_ = _NE_ + _SW_ # PYCHOK clockwise 

440 

441_DDOT_ = Str_(_DOT_ * 2) # PYCHOK OK 

442# _DEQUAL_ = Str_(_EQUAL_ * 2) # PYCHOK OK 

443_DNL_ = Str_(_NL_ * 2) # PYCHOK OK 

444# _DSLASH_ = Str_(_SLASH_ * 2) # PYCHOK OK 

445# _DSTAR_ = Str_(_STAR_ * 2) # PYCHOK OK 

446_DUNDER_ = Str_(_UNDER_ * 2) # PYCHOK OK 

447 

448_LR_PAIRS = {_LANGLE_: _RANGLE_, 

449 _LCURLY_: _RCURLY_, 

450 _LPAREN_: _RPAREN_, 

451 _LSQUARE_: _RSQUARE_} # PYCHOK OK 

452 

453 

454def _dunder_nameof(inst, *dflt): 

455 '''(INTERNAL) Get the double_underscore __name__ attr. 

456 ''' 

457 try: 

458 return inst.__name__ 

459 except AttributeError: 

460 pass 

461 return dflt[0] if dflt else inst.__class__.__name__ 

462 

463 

464def _enquote(strs, quote=_QUOTE2_, white=NN): # in .basics, .solveBase 

465 '''(INTERNAL) Enquote a string containing whitespace or replace 

466 whitespace by C{white} if specified. 

467 ''' 

468 if strs: 

469 t = strs.split() 

470 if len(t) > 1: 

471 strs = white.join(t if white else (quote, strs, quote)) 

472 return strs 

473 

474 

475def _headof(name): 

476 '''(INTERNAL) Get the head name of qualified C{name} or the C{name}. 

477 ''' 

478 i = name.find(_DOT_) 

479 return name if i < 0 else name[:i] 

480 

481 

482def _is(a, b): # PYCHOK no cover 

483 '''(INTERNAL) C{a is b}? in C{PyPy} 

484 ''' 

485 return (a == b) if _isPyPy() else (a is b) 

486 

487 

488def _isPyPy(): 

489 '''(INTERNAL) Is this C{PyPy}? 

490 ''' 

491 # platform.python_implementation() == 'PyPy' 

492 return _pythonarchine()[0].startswith(_PyPy__) 

493 

494 

495def _load_lib(name): 

496 '''(INTERNAL) Load a C{dylib}, B{C{name}} must startwith('lib'). 

497 ''' 

498 # macOS 11+ (aka 10.16) no longer provides direct loading of 

499 # system libraries. As a result, C{ctypes.util.find_library} 

500 # will not find any library, unless previously installed by a 

501 # low-level dlopen(name) call (with the library base C{name}). 

502 from ctypes import CDLL 

503 from ctypes.util import find_library 

504 

505 ns = find_library(name), name 

506 if _sys.platform[:6] == 'darwin': # and os.name == 'posix' 

507 from ctypes import _dlopen, DEFAULT_MODE 

508 from os.path import join 

509 ns += (_DOT_(name, 'dylib'), 

510 _DOT_(name, 'framework'), join( 

511 _DOT_(name, 'framework'), name)) 

512 else: # non-macOS 

513 DEFAULT_MODE = 0 

514 

515 def _dlopen(*unused): 

516 return True 

517 

518 for n in ns: 

519 try: 

520 if n and _dlopen(n, DEFAULT_MODE): # pre-load handle 

521 lib = CDLL(n) # == ctypes.cdll.LoadLibrary(n) 

522 if lib._name: # has a qualified name 

523 return lib 

524 except (AttributeError, OSError): 

525 pass 

526 

527 return None # raise OSError 

528 

529 

530def machine(): 

531 '''Return standard C{platform.machine}, but distinguishing Intel I{native} 

532 from Intel I{emulation} on Apple Silicon (on macOS only). 

533 

534 @return: Machine C{'arm64'} for Apple Silicon I{native}, C{'x86_64'} 

535 for Intel I{native}, C{"arm64_x86_64"} for Intel I{emulation}, 

536 etc. (C{str} with C{comma}s replaced by C{underscore}s). 

537 ''' 

538 return _platform2()[1] 

539 

540 

541def _platform2(sep=NN): 

542 '''(INTERNAL) Get platform architecture and machine as C{2-list} or C{str}. 

543 ''' 

544 L = _pf2List 

545 if not L: 

546 import platform 

547 m = platform.machine() # ARM64, arm64, x86_64, iPhone13,2, etc. 

548 m = m.replace(_COMMA_, _UNDER_) 

549 if m.lower() == 'x86_64': # on Intel or Rosetta2 ... 

550 v = platform.mac_ver() # ... and only on macOS ... 

551 if v and _version2(v[0]) > (10, 15): # ... 11+ aka 10.16 

552 # <https://Developer.Apple.com/forums/thread/659846> 

553 if _sysctl_uint('sysctl.proc_translated') == 1: # and \ 

554# _sysctl_uint('hw.optional.arm64') == 1: # PYCHOK indent 

555 m = _UNDER_('arm64', m) # Apple Si emulating Intel x86-64 

556 L[:] = [platform.architecture()[0], # bits 

557 m] # arm64, arm64_x86_64, x86_64, etc. 

558 return sep.join(L) if sep else L # 2-list() 

559 

560 

561def _pythonarchine(sep=NN): # in test/bases.py versions 

562 '''(INTERNAL) Get PyPy and Python versions and C{_platform2} as C{3- or 4-list} or C{str}. 

563 ''' 

564 L = _Py3List 

565 if not L: 

566 v = _sys.version 

567 L[:] = [_Python_(v)] + _platform2() 

568 pypy = _PyPy__(v) 

569 if pypy: 

570 L.insert(0, pypy) 

571 return sep.join(L) if sep else L # 3- or 4-list 

572 

573 

574def _sysctl_uint(name): 

575 '''(INTERNAL) Get an unsigned int sysctl item by name, use on macOS ONLY! 

576 ''' 

577 libc = _load_lib('libc') 

578 if libc: # <https://StackOverflow.com/questions/759892/python-ctypes-and-sysctl> 

579 from ctypes import byref, c_char_p, c_size_t, c_uint, sizeof # get_errno 

580 n = name if str is bytes else bytes(name, _utf_8_) # PYCHOK isPython2 = str is bytes 

581 u = c_uint(0) 

582 z = c_size_t(sizeof(u)) 

583 r = libc.sysctlbyname(c_char_p(n), byref(u), byref(z), None, c_size_t(0)) 

584 else: # could find or load 'libc' 

585 r = -2 

586 return int(r if r else u.value) # -1 ENOENT error, -2 no libc 

587 

588 

589def _tailof(name): 

590 '''(INTERNAL) Get the base name of qualified C{name} or the C{name}. 

591 ''' 

592 i = name.rfind(_DOT_) + 1 

593 return name[i:] if i > 0 else name 

594 

595 

596def _under(name): # PYCHOK in .datums, .auxilats, .ups, .utm, .utmupsBase, ... 

597 '''(INTERNAL) Prefix C{name} with I{underscore}. 

598 ''' 

599 return name if name.startswith(_UNDER_) else NN(_UNDER_, name) 

600 

601 

602def _usage(file_py, *args): # in .etm 

603 '''(INTERNAL) Build "usage: python -m ..." cmd line for module B{C{file_py}}. 

604 ''' 

605 import os 

606 m = os.path.dirname(file_py).replace(os.getcwd(), _ELLIPSIS_) \ 

607 .replace(os.sep, _DOT_).strip() 

608 b, x = os.path.splitext(os.path.basename(file_py)) 

609 if x == '.py' and b != '__main__': 

610 m = _DOT_(m or _pygeodesy_, b) 

611 p = NN(_python_, _sys.version_info[0]) 

612 return NN('usage', _SPACE_(_COLON_, p, '-m', _enquote(m), *args)) 

613 

614 

615def _version2(version, n=2): 

616 '''(INTERNAL) Split C{B{version} str} into a C{1-, 2- or 3-tuple} of C{int}s. 

617 ''' 

618 t = _version_ints(version.split(_DOT_, 2)) 

619 if len(t) < n: 

620 t += (0,) * n 

621 return t[:n] 

622 

623 

624def _version_info(package): # in .Base.karney, .basics 

625 '''(INTERNAL) Get the C{package.__version_info__} as a 2- or 

626 3-tuple C{(major, minor, revision)} if C{int}s. 

627 ''' 

628 try: 

629 return _version_ints(package.__version_info__) 

630 except AttributeError: 

631 return _version2(package.__version__.strip(), n=3) 

632 

633 

634def _version_ints(vs): 

635 # helper for _version2 and _version_info above 

636 

637 def _ints(vs): 

638 for v in vs: 

639 try: 

640 yield int(v.strip()) 

641 except (TypeError, ValueError): 

642 pass 

643 

644 return tuple(_ints(vs)) 

645 

646 

647__all__ = (_NN_, # not MISSING! 

648 Str_.__name__, # classes 

649 machine.__name__) # in .lazily 

650__version__ = '24.05.06' 

651 

652if __name__ == '__main__': 

653 

654 from pygeodesy import itemsorted, printf 

655 

656 t = b = 0 

657 for n, v in itemsorted(locals(), asorted=False, reverse=True): 

658 if n.endswith(_UNDER_) and n.startswith(_UNDER_) and \ 

659 not n.startswith(_DUNDER_): 

660 t += 1 

661 b += len(v) 

662 m = n[1:-1] 

663 if m != v and m.replace(_UNDER_, _SPACE_) != v: 

664 printf('%4d: %s = %r', t, n, v) 

665 n = len(locals()) 

666 printf('%4d (%d) names, %s chars total, %.2f chars avg', t, n, b, float(b) / t, nl=1) 

667 

668# **) MIT License 

669# 

670# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved. 

671# 

672# Permission is hereby granted, free of charge, to any person obtaining a 

673# copy of this software and associated documentation files (the "Software"), 

674# to deal in the Software without restriction, including without limitation 

675# the rights to use, copy, modify, merge, publish, distribute, sublicense, 

676# and/or sell copies of the Software, and to permit persons to whom the 

677# Software is furnished to do so, subject to the following conditions: 

678# 

679# The above copyright notice and this permission notice shall be included 

680# in all copies or substantial portions of the Software. 

681# 

682# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 

683# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

684# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 

685# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 

686# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 

687# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 

688# OTHER DEALINGS IN THE SOFTWARE.