pygeodesy 24.5.8__py2.py3-none-any.whl → 24.5.24__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.5.24.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +16 -12
  4. pygeodesy/__main__.py +9 -10
  5. pygeodesy/albers.py +42 -42
  6. pygeodesy/auxilats/__init__.py +1 -1
  7. pygeodesy/auxilats/__main__.py +7 -10
  8. pygeodesy/auxilats/auxAngle.py +32 -31
  9. pygeodesy/auxilats/auxLat.py +81 -51
  10. pygeodesy/azimuthal.py +123 -124
  11. pygeodesy/basics.py +165 -176
  12. pygeodesy/booleans.py +14 -15
  13. pygeodesy/cartesianBase.py +25 -23
  14. pygeodesy/clipy.py +3 -3
  15. pygeodesy/constants.py +8 -6
  16. pygeodesy/css.py +50 -42
  17. pygeodesy/datums.py +50 -48
  18. pygeodesy/dms.py +6 -6
  19. pygeodesy/ecef.py +27 -27
  20. pygeodesy/elevations.py +2 -2
  21. pygeodesy/ellipsoidalBase.py +28 -27
  22. pygeodesy/ellipsoidalBaseDI.py +8 -7
  23. pygeodesy/ellipsoidalNvector.py +11 -12
  24. pygeodesy/ellipsoids.py +41 -35
  25. pygeodesy/elliptic.py +12 -10
  26. pygeodesy/epsg.py +4 -3
  27. pygeodesy/errors.py +35 -13
  28. pygeodesy/etm.py +62 -53
  29. pygeodesy/fmath.py +48 -41
  30. pygeodesy/formy.py +93 -65
  31. pygeodesy/frechet.py +117 -102
  32. pygeodesy/fstats.py +52 -46
  33. pygeodesy/fsums.py +169 -145
  34. pygeodesy/gars.py +10 -9
  35. pygeodesy/geodesicw.py +32 -30
  36. pygeodesy/geodesicx/__init__.py +1 -1
  37. pygeodesy/geodesicx/__main__.py +4 -4
  38. pygeodesy/geodesicx/gx.py +40 -32
  39. pygeodesy/geodesicx/gxarea.py +15 -12
  40. pygeodesy/geodesicx/gxbases.py +3 -4
  41. pygeodesy/geodesicx/gxline.py +6 -8
  42. pygeodesy/geodsolve.py +28 -26
  43. pygeodesy/geohash.py +47 -44
  44. pygeodesy/geoids.py +37 -35
  45. pygeodesy/hausdorff.py +112 -99
  46. pygeodesy/heights.py +136 -129
  47. pygeodesy/internals.py +576 -0
  48. pygeodesy/interns.py +6 -207
  49. pygeodesy/iters.py +22 -19
  50. pygeodesy/karney.py +18 -15
  51. pygeodesy/ktm.py +31 -24
  52. pygeodesy/latlonBase.py +12 -11
  53. pygeodesy/lazily.py +140 -218
  54. pygeodesy/lcc.py +24 -25
  55. pygeodesy/ltp.py +83 -71
  56. pygeodesy/ltpTuples.py +7 -5
  57. pygeodesy/mgrs.py +5 -4
  58. pygeodesy/named.py +136 -49
  59. pygeodesy/namedTuples.py +33 -25
  60. pygeodesy/nvectorBase.py +10 -9
  61. pygeodesy/osgr.py +14 -12
  62. pygeodesy/points.py +13 -13
  63. pygeodesy/props.py +7 -7
  64. pygeodesy/rhumb/__init__.py +1 -1
  65. pygeodesy/rhumb/bases.py +3 -2
  66. pygeodesy/rhumb/solve.py +2 -2
  67. pygeodesy/solveBase.py +8 -7
  68. pygeodesy/sphericalTrigonometry.py +5 -5
  69. pygeodesy/streprs.py +8 -7
  70. pygeodesy/trf.py +8 -8
  71. pygeodesy/triaxials.py +67 -63
  72. pygeodesy/units.py +48 -50
  73. pygeodesy/unitsBase.py +24 -11
  74. pygeodesy/ups.py +7 -6
  75. pygeodesy/utily.py +4 -4
  76. pygeodesy/utm.py +53 -52
  77. pygeodesy/utmupsBase.py +11 -8
  78. pygeodesy/vector2d.py +6 -7
  79. pygeodesy/vector3d.py +16 -17
  80. pygeodesy/vector3dBase.py +5 -5
  81. PyGeodesy-24.5.8.dist-info/RECORD +0 -115
  82. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
  83. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/top_level.txt +0 -0
pygeodesy/lcc.py CHANGED
@@ -30,26 +30,25 @@ from pygeodesy.constants import EPS, EPS02, PI_2, _float as _F, _0_0, _0_5, \
30
30
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
31
31
  from pygeodesy.datums import Datums, _ellipsoidal_datum
32
32
  from pygeodesy.errors import _IsnotError, _ValueError
33
- from pygeodesy.fmath import _ALL_LAZY, hypot
33
+ from pygeodesy.fmath import hypot, _ALL_LAZY
34
34
  from pygeodesy.interns import NN, _COMMASPACE_, _ellipsoidal_, _GRS80_, _k0_, \
35
- _lat0_, _lon0_, _m_, _NAD83_, _NTF_, _SPACE_, _WGS84_, \
36
- _C_ # PYCHOK used!
35
+ _lat0_, _lon0_, _m_, _NAD83_, _NTF_, _SPACE_, \
36
+ _WGS84_, _C_ # PYCHOK used!
37
37
  # from pygeodesy.lazily import _ALL_LAZY # from .fmath
38
- from pygeodesy.named import _lazyNamedEnumItem as _lazy, _NamedBase, \
39
- _NamedEnum, _NamedEnumItem, nameof, _xnamed
38
+ from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name2__, _NamedBase, \
39
+ _NamedEnum, _NamedEnumItem, _xnamed
40
40
  from pygeodesy.namedTuples import EasNor3Tuple, LatLonDatum3Tuple, \
41
41
  LatLon2Tuple, _LL4Tuple, PhiLam2Tuple
42
- from pygeodesy.props import deprecated_method, Property, Property_RO, \
43
- _update_all
42
+ from pygeodesy.props import deprecated_method, Property, Property_RO, _update_all
44
43
  from pygeodesy.streprs import Fmt, _fstrENH2, _xzipairs
45
- from pygeodesy.units import Easting, Height, _heigHt, Lam_, Northing, \
46
- Phi_, Scalar_
44
+ from pygeodesy.units import Easting, Height, _heigHt, Lam_, Northing, Phi_, \
45
+ Scalar_
47
46
  from pygeodesy.utily import atan1, degrees90, degrees180, sincos2, tanPI_2_2
48
47
 
49
48
  from math import atan, fabs, log, radians, sin, sqrt
50
49
 
51
50
  __all__ = _ALL_LAZY.lcc
52
- __version__ = '23.12.03'
51
+ __version__ = '24.05.24'
53
52
 
54
53
  _E0_ = 'E0'
55
54
  _N0_ = 'N0'
@@ -83,7 +82,7 @@ class Conic(_NamedEnumItem):
83
82
  _r0 = _0_0 # precomputed rho0 (C{float})
84
83
 
85
84
  def __init__(self, latlon0, par1, par2=None, E0=0, N0=0,
86
- k0=1, opt3=0, name=NN, auth=NN):
85
+ k0=1, opt3=0, auth=NN, **name):
87
86
  '''New Lambert conformal conic projection.
88
87
 
89
88
  @arg latlon0: Origin with (ellipsoidal) datum (C{LatLon}).
@@ -93,8 +92,8 @@ class Conic(_NamedEnumItem):
93
92
  @kwarg N0: Optional, false northing (C{meter}).
94
93
  @kwarg k0: Optional scale factor (C{scalar}).
95
94
  @kwarg opt3: Optional meridian (C{degrees180}).
96
- @kwarg name: Optional name of the conic (C{str}).
97
95
  @kwarg auth: Optional authentication authority (C{str}).
96
+ @kwarg name: Optional C{B{name}=NN} for the conic (C{str}).
98
97
 
99
98
  @return: A Lambert projection (L{Conic}).
100
99
 
@@ -283,7 +282,7 @@ class Conic(_NamedEnumItem):
283
282
  '''Return this conic as a string.
284
283
 
285
284
  @kwarg prec: Number of (decimal) digits, unstripped (C{int}).
286
- @kwarg name: Override name (C{str}) or C{None} to exclude
285
+ @kwarg name: Overriding name (C{str}) or C{None} to exclude
287
286
  this conic's name.
288
287
 
289
288
  @return: Conic attributes (C{str}).
@@ -400,14 +399,14 @@ class Lcc(_NamedBase):
400
399
  _height = 0 # height (C{meter})
401
400
  _northing = _0_0 # Northing (C{float})
402
401
 
403
- def __init__(self, e, n, h=0, conic=Conics.WRF_Lb, name=NN):
402
+ def __init__(self, e, n, h=0, conic=Conics.WRF_Lb, **name):
404
403
  '''New L{Lcc} Lamber conformal conic position.
405
404
 
406
405
  @arg e: Easting (C{meter}).
407
406
  @arg n: Northing (C{meter}).
408
407
  @kwarg h: Optional height (C{meter}).
409
408
  @kwarg conic: Optional, the conic projection (L{Conic}).
410
- @kwarg name: Optional name (C{str}).
409
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
411
410
 
412
411
  @return: The Lambert location (L{Lcc}).
413
412
 
@@ -614,27 +613,27 @@ class Lcc(_NamedBase):
614
613
  return t if sep is None else sep.join(t)
615
614
 
616
615
 
617
- def toLcc(latlon, conic=Conics.WRF_Lb, height=None, Lcc=Lcc, name=NN,
618
- **Lcc_kwds):
616
+ def toLcc(latlon, conic=Conics.WRF_Lb, height=None, Lcc=Lcc,
617
+ **name_Lcc_kwds):
619
618
  '''Convert an (ellipsoidal) geodetic point to a I{Lambert} location.
620
619
 
621
620
  @arg latlon: Ellipsoidal point (C{LatLon}).
622
621
  @kwarg conic: Optional Lambert projection to use (L{Conic}).
623
622
  @kwarg height: Optional height for the point, overriding the
624
623
  default height (C{meter}).
625
- @kwarg Lcc: Optional class to return the I{Lambert} location
626
- (L{Lcc}).
627
- @kwarg name: Optional B{C{Lcc}} name (C{str}).
628
- @kwarg Lcc_kwds: Optional, additional B{C{Lcc}} keyword
629
- arguments, ignored if B{C{Lcc}} is C{None}.
624
+ @kwarg Lcc: Class to return the I{Lambert} location (L{Lcc}).
625
+ @kwarg name_Lcc_kwds: Optional C{B{name}=NN} (C{str}) for the
626
+ location and optional, additional B{C{Lcc}} keyword
627
+ arguments, ignored if B{C{Lcc}} is C{None}.
630
628
 
631
629
  @return: The I{Lambert} location (L{Lcc}) or an
632
- L{EasNor3Tuple}C{(easting, northing, height)}
633
- if C{B{Lcc} is None}.
630
+ L{EasNor3Tuple}C{(easting, northing, height)} if
631
+ C{B{Lcc} is None}.
634
632
 
635
633
  @raise TypeError: If B{C{latlon}} is not ellipsoidal.
636
634
  '''
637
635
  _xinstanceof(_LLEB, latlon=latlon)
636
+ name, Lcc_kwds = _name2__(name_Lcc_kwds)
638
637
 
639
638
  a, b = latlon.philam
640
639
  c = conic.toDatum(latlon.datum)
@@ -649,7 +648,7 @@ def toLcc(latlon, conic=Conics.WRF_Lb, height=None, Lcc=Lcc, name=NN,
649
648
  h = _heigHt(latlon, height)
650
649
  r = EasNor3Tuple(e, n, h) if Lcc is None else \
651
650
  Lcc(e, n, h=h, conic=c, **Lcc_kwds)
652
- return _xnamed(r, name or nameof(latlon))
651
+ return _xnamed(r, name) if name else r
653
652
 
654
653
 
655
654
  if __name__ == '__main__':
pygeodesy/ltp.py CHANGED
@@ -20,16 +20,16 @@ from pygeodesy.constants import EPS, INT0, _umod_360, _0_0, _0_01, _0_5, _1_0, \
20
20
  from pygeodesy.datums import _WGS84, _xinstanceof
21
21
  from pygeodesy.ecef import _EcefBase, EcefKarney, _llhn4, _xyzn4
22
22
  from pygeodesy.errors import _NotImplementedError, _TypesError, _ValueError, \
23
- _xattr, _xkwds, _xkwds_get
23
+ _xattr, _xkwds, _xkwds_get, _xkwds_pop2
24
24
  from pygeodesy.fmath import fabs, fdot, Fhorner
25
25
  from pygeodesy.fsums import _floor, _Fsumf_, fsumf_, fsum1f_
26
- from pygeodesy.interns import NN, _0_, _COMMASPACE_, _DOT_, _ecef_, _height_, \
27
- _invalid_, _lat0_, _lon0_, _ltp_, _M_, _name_, _too_
26
+ from pygeodesy.interns import _0_, _COMMASPACE_, _DOT_, _ecef_, _height_, _M_, \
27
+ _invalid_, _lat0_, _lon0_, _ltp_, _name_, _too_
28
28
  # from pygeodesy.lazily import _ALL_LAZY # from vector3d
29
29
  from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
30
30
  ChLVYX2Tuple, Footprint5Tuple, Local9Tuple, \
31
31
  ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
32
- from pygeodesy.named import _NamedBase, notOverloaded
32
+ from pygeodesy.named import _name__, _NamedBase, notOverloaded
33
33
  from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
34
34
  from pygeodesy.props import Property, Property_RO, property_doc_, property_RO, \
35
35
  _update_all
@@ -42,7 +42,7 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
42
42
  # from math import fabs, floor as _floor # from .fmath, .fsums
43
43
 
44
44
  __all__ = _ALL_LAZY.ltp
45
- __version__ = '24.04.14'
45
+ __version__ = '24.04.23'
46
46
 
47
47
  _height0_ = _height_ + _0_
48
48
  _narrow_ = 'narrow'
@@ -67,7 +67,7 @@ class Attitude(_NamedBase):
67
67
  _tilt = Degrees(tilt=_0_0)
68
68
  _yaw = Bearing(yaw =_0_0)
69
69
 
70
- def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, name=NN):
70
+ def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, **name):
71
71
  '''New L{Attitude}.
72
72
 
73
73
  @kwarg alt_attitude: An altitude (C{meter}) above earth or an attitude
@@ -79,7 +79,7 @@ class Attitude(_NamedBase):
79
79
  (counter-clockwise rotation along and around the z- or Up axis).
80
80
  @kwarg roll: Roll, bank (C{degrees180}), positive to the right and down
81
81
  (clockwise rotation along and around the y- or North axis).
82
- @kwarg name: Optional name C{str}).
82
+ @kwarg name: Optional C{B{name}=NN} C{str}).
83
83
 
84
84
  @raise AttitudeError: Invalid B{C{alt_attitude}}, B{C{tilt}}, B{C{yaw}} or
85
85
  B{C{roll}}.
@@ -97,7 +97,7 @@ class Attitude(_NamedBase):
97
97
  for n, v in t.items():
98
98
  if v:
99
99
  setattr(self, n, v)
100
- n = name or t.name
100
+ n = _name__(name, _or_nameof=t)
101
101
  if n:
102
102
  self.name = n
103
103
 
@@ -214,7 +214,7 @@ class Attitude(_NamedBase):
214
214
  def _r2d(r):
215
215
  return fsumf_(_N_1_0, *r)
216
216
 
217
- return Vector3d(*map(_r2d, self.matrix), name=tyr3d.__name__)
217
+ return Vector3d(*map(_r2d, self.matrix), name__=tyr3d)
218
218
 
219
219
  @property_doc_(' yaw/bearing/heading in compass C{degrees360}, clockwise from North.')
220
220
  def yaw(self):
@@ -247,12 +247,13 @@ class Frustum(_NamedBase):
247
247
  _tan_h_2 = _0_0 # tan(_h_2)
248
248
  _v_2 = _0_0 # half vfov in degrees
249
249
 
250
- def __init__(self, hfov, vfov, ltp=None):
250
+ def __init__(self, hfov, vfov, ltp=None, **name):
251
251
  '''New L{Frustum}.
252
252
 
253
253
  @arg hfov: Horizontal field-of-view (C{degrees180}).
254
254
  @arg vfov: Vertical field-of-view (C{degrees180}).
255
255
  @kwarg ltp: Optional I{local tangent plane} (L{Ltp}).
256
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
256
257
 
257
258
  @raise LocalError: Invalid B{C{hfov}} or B{C{vfov}}.
258
259
  '''
@@ -263,8 +264,10 @@ class Frustum(_NamedBase):
263
264
 
264
265
  if ltp:
265
266
  self._ltp = _xLtp(ltp)
267
+ if name:
268
+ self.name # PYCHOK effect
266
269
 
267
- def footprint5(self, alt_attitude, tilt=0, yaw=0, roll=0, z=_0_0, ltp=None): # MCCABE 15
270
+ def footprint5(self, alt_attitude, tilt=0, yaw=0, roll=0, z=_0_0, ltp=None, **name): # MCCABE 15
268
271
  '''Compute the center and corners of the intersection with (or projection
269
272
  to) the I{local tangent plane} (LTP).
270
273
 
@@ -280,6 +283,7 @@ class Frustum(_NamedBase):
280
283
  @kwarg z: Optional height of the footprint (C{meter}) above I{local tangent plane}.
281
284
  @kwarg ltp: The I{local tangent plane} (L{Ltp}), overriding this
282
285
  frustum's C{ltp}.
286
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
283
287
 
284
288
  @return: A L{Footprint5Tuple}C{(center, upperleft, upperight, loweright,
285
289
  lowerleft)} with the C{center} and 4 corners, each an L{Xyz4Tuple}.
@@ -350,7 +354,7 @@ class Frustum(_NamedBase):
350
354
  + _xy2(a, e + v, -h, -t, r) # swapped
351
355
  # turn center and corners by yaw, clockwise
352
356
  p = self.ltp if ltp is None else ltp # None OK
353
- return Footprint5Tuple(_xyz5(b, xy5, z, p)) # *_xyz5
357
+ return Footprint5Tuple(_xyz5(b, xy5, z, p), **name) # *_xyz5
354
358
 
355
359
  @Property_RO
356
360
  def hfov(self):
@@ -413,7 +417,7 @@ class LocalCartesian(_NamedBase):
413
417
  _t0 = None # origin (..., lat0, lon0, height0, ...) L{Ecef9Tuple}
414
418
  _9Tuple = Local9Tuple
415
419
 
416
- def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, name=NN, **lon00):
420
+ def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
417
421
  '''New L{LocalCartesian} converter.
418
422
 
419
423
  @kwarg latlonh0: The (geodetic) origin (C{LatLon}, L{LatLon4Tuple}, L{Ltp}
@@ -426,9 +430,10 @@ class LocalCartesian(_NamedBase):
426
430
  surface and for C{scalar} B{C{latlonh0}}, ignored otherwise.
427
431
  @kwarg ecef: An ECEF converter (L{EcefKarney} I{only}) for C{scalar}
428
432
  B{C{latlonh0}}, ignored otherwise.
429
- @kwarg name: Optional name (C{str}).
430
- @kwarg lon00: An arbitrary, I{polar} longitude (C{degrees}), overriding
431
- the default C{B{lon00}=B{lon0}}, see method C{reverse}.
433
+ @kwarg lon00_name: Optional C{B{name}=NN} (C{str}) and keyword argument
434
+ C{B{lon00}=B{lon0}} for the arbitrary I{polar} longitude
435
+ (C{degrees}), see method C{reverse} and property C{lon00}
436
+ for further details.
432
437
 
433
438
  @raise LocalError: If B{C{latlonh0}} not C{LatLon}, L{LatLon4Tuple}, L{Ltp},
434
439
  L{LocalCartesian} or L{Ecef9Tuple} or B{C{latlonh0}},
@@ -439,7 +444,7 @@ class LocalCartesian(_NamedBase):
439
444
  @note: If BC{latlonh0} is an L{Ltp} or L{LocalCartesian}, only C{lat0}, C{lon0},
440
445
  C{height0} and I{polar} C{lon00} are copied, I{not} the ECEF converter.
441
446
  '''
442
- self.reset(latlonh0, lon0=lon0, height0=height0, ecef=ecef, name=name, **lon00)
447
+ self.reset(latlonh0, lon0=lon0, height0=height0, ecef=ecef, **lon00_name)
443
448
 
444
449
  def __eq__(self, other):
445
450
  '''Compare this and an other instance.
@@ -495,7 +500,7 @@ class LocalCartesian(_NamedBase):
495
500
  '''
496
501
  return self.ecef.datum.ellipsoid
497
502
 
498
- def forward(self, latlonh, lon=None, height=0, M=False, name=NN):
503
+ def forward(self, latlonh, lon=None, height=0, M=False, **name):
499
504
  '''Convert I{geodetic} C{(lat, lon, height)} to I{local} cartesian
500
505
  C{(x, y, z)}.
501
506
 
@@ -507,7 +512,7 @@ class LocalCartesian(_NamedBase):
507
512
  to and above (or below) the ellipsoid's surface.
508
513
  @kwarg M: Optionally, return the I{concatenated} rotation L{EcefMatrix},
509
514
  iff available (C{bool}).
510
- @kwarg name: Optional name (C{str}).
515
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
511
516
 
512
517
  @return: A L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp, ecef, M)}
513
518
  with I{local} C{x}, C{y}, C{z}, I{geodetic} C{(lat}, C{lon},
@@ -521,7 +526,7 @@ class LocalCartesian(_NamedBase):
521
526
  C{scalar} for C{scalar} B{C{latlonh}} or invalid
522
527
  or if B{C{height}} invalid.
523
528
  '''
524
- lat, lon, h, n = _llhn4(latlonh, lon, height, Error=LocalError, name=name)
529
+ lat, lon, h, n = _llhn4(latlonh, lon, height, Error=LocalError, **name)
525
530
  t = self.ecef._forward(lat, lon, h, n, M=M)
526
531
  x, y, z = self.M.rotate(t.xyz, *self._t0_xyz)
527
532
  m = self.M.multiply(t.M) if M else None
@@ -586,19 +591,21 @@ class LocalCartesian(_NamedBase):
586
591
  '''
587
592
  return self._t0.M
588
593
 
589
- def reset(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, name=NN, **lon00):
590
- '''Reset this converter, see L{LocalCartesian.__init__} and L{Ltp.__init__} for more details.
594
+ def reset(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
595
+ '''Reset this converter, see L{LocalCartesian.__init__} for more details.
591
596
  '''
597
+ _, name = _xkwds_pop2(lon00_name, lon00=None) # PYCHOK get **name
592
598
  if isinstance(latlonh0, LocalCartesian):
593
599
  if self._t0:
594
600
  _update_all(self)
595
- self._ecef = latlonh0.ecef
596
- self._lon00 = latlonh0.lon00
597
- self._t0 = latlonh0._t0
598
- n = name or latlonh0.name
601
+ self._ecef = latlonh0.ecef
602
+ self._lon00 = latlonh0.lon00
603
+ self._t0 = latlonh0._t0
604
+ n = _name__(name, _or_nameof=latlonh0)
599
605
  else:
606
+ n = _name__(name, _or_nameof=self)
600
607
  lat0, lon0, height0, n = _llhn4(latlonh0, lon0, height0, suffix=_0_,
601
- Error=LocalError, name=name or self.name)
608
+ Error=LocalError, name=n)
602
609
  if ecef: # PYCHOK no cover
603
610
  _xinstanceof(self._Ecef, ecef=ecef)
604
611
  _update_all(self)
@@ -606,11 +613,11 @@ class LocalCartesian(_NamedBase):
606
613
  elif self._t0:
607
614
  _update_all(self)
608
615
  self._t0 = self.ecef._forward(lat0, lon0, height0, n, M=True)
609
- self.lon00 = _xattr(latlonh0, lon00=_xkwds_get(lon00, lon00=lon0))
616
+ self.lon00 = _xattr(latlonh0, lon00=_xkwds_get(lon00_name, lon00=lon0))
610
617
  if n:
611
618
  self.rename(n)
612
619
 
613
- def reverse(self, xyz, y=None, z=None, M=False, name=NN, **lon00):
620
+ def reverse(self, xyz, y=None, z=None, M=False, **lon00_name):
614
621
  '''Convert I{local} C{(x, y, z)} to I{geodetic} C{(lat, lon, height)}.
615
622
 
616
623
  @arg xyz: A I{local} (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer}, L{Local9Tuple}) or
@@ -619,10 +626,12 @@ class LocalCartesian(_NamedBase):
619
626
  @kwarg z: Local C{z} coordinate for C{scalar} B{C{xyz}} and B{C{y}} (C{meter}).
620
627
  @kwarg M: Optionally, return the I{concatenated} rotation L{EcefMatrix}, iff
621
628
  available (C{bool}).
622
- @kwarg name: Optional name (C{str}).
623
- @kwarg lon00: An arbitrary, I{polar} longitude (C{degrees}), returned for local
624
- C{B{x}=0} and C{B{y}=0} at I{polar} latitudes C{abs(B{lat0}) == 90},
625
- overriding property C{lon00} and default C{B{lon00}=B{lon0}}.
629
+ @kwarg lon00_name: Optional C{B{name}=NN} (C{str}) and keyword argument
630
+ C{B{lon00}=B{lon0}} for the arbitrary I{polar} longitude
631
+ (C{degrees}), overriding see the property C{B{lon00}=B{lon0}}
632
+ value. The I{polar} longitude (C{degrees}) is returned with
633
+ I{polar} latitudes C{abs(B{lat0}) == 90} for local C{B{x}=0}
634
+ and C{B{y}=0} locations.
626
635
 
627
636
  @return: An L{Local9Tuple}C{(x, y, z, lat, lon, height, ltp, ecef, M)} with
628
637
  I{local} C{x}, C{y}, C{z}, I{geodetic} C{lat}, C{lon}, C{height},
@@ -633,9 +642,10 @@ class LocalCartesian(_NamedBase):
633
642
  @raise LocalError: Invalid B{C{xyz}} or C{scalar} C{x} or B{C{y}} and/or B{C{z}}
634
643
  not C{scalar} for C{scalar} B{C{xyz}}.
635
644
  '''
645
+ lon00, name =_xkwds_pop2(lon00_name, lon00=self.lon00)
636
646
  x, y, z, n = _xyzn4(xyz, y, z, _XyzLocals5, Error=LocalError, name=name)
637
647
  c = self.M.unrotate((x, y, z), *self._t0_xyz)
638
- t = self.ecef.reverse(*c, M=M, lon00=_xkwds_get(lon00, lon00=self.lon00))
648
+ t = self.ecef.reverse(*c, M=M, lon00=lon00)
639
649
  m = self.M.multiply(t.M) if M else None
640
650
  return self._9Tuple(x, y, z, t.lat, t.lon, t.height, self, t, m, name=n or self.name)
641
651
 
@@ -661,7 +671,7 @@ class Ltp(LocalCartesian):
661
671
  '''
662
672
  _Ecef = _EcefBase
663
673
 
664
- def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, name=NN, **lon00):
674
+ def __init__(self, latlonh0=INT0, lon0=INT0, height0=INT0, ecef=None, **lon00_name):
665
675
  '''New C{Ltp}, see L{LocalCartesian.__init__} for more details.
666
676
 
667
677
  @kwarg ecef: Optional ECEF converter (L{EcefKarney}, L{EcefFarrell21},
@@ -669,10 +679,12 @@ class Ltp(LocalCartesian):
669
679
  L{EcefYou} I{instance}), overriding the default
670
680
  L{EcefKarney}C{(datum=Datums.WGS84)} for C{scalar}.
671
681
 
682
+ @see: Class L{LocalCartesian<LocalCartesian.__init__>} for further details.
683
+
672
684
  @raise TypeError: Invalid B{C{ecef}}.
673
685
  '''
674
686
  LocalCartesian.reset(self, latlonh0, lon0=lon0, height0=height0,
675
- ecef=ecef, name=name, **lon00)
687
+ ecef=ecef, **lon00_name)
676
688
 
677
689
  @Property
678
690
  def ecef(self):
@@ -719,7 +731,7 @@ class _ChLV(object):
719
731
  # assert _args_kwds_names(ChLVe.reverse)[1:4] == t
720
732
  return t
721
733
 
722
- def forward(self, latlonh, lon=None, height=0, M=None, name=NN): # PYCHOK no cover
734
+ def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK no cover
723
735
  '''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
724
736
 
725
737
  @arg latlonh: Either a C{LatLon}, L{Ltp} or C{scalar} (geodetic) latitude (C{degrees}).
@@ -728,7 +740,7 @@ class _ChLV(object):
728
740
  (C{meter}) for C{scalar} B{C{latlonh}} and B{C{lon}}.
729
741
  @kwarg M: If C{True}, return the I{concatenated} rotation L{EcefMatrix} iff available
730
742
  for C{ChLV} only, C{None} otherwise (C{bool}).
731
- @kwarg name: Optional name (C{str}).
743
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
732
744
 
733
745
  @return: A L{ChLV9Tuple}C{(Y, X, h_, lat, lon, height, ltp, ecef, M)} with the unfalsed
734
746
  I{Swiss Y, X} coordinates, I{Swiss h_} height, the given I{geodetic} C{lat},
@@ -738,7 +750,7 @@ class _ChLV(object):
738
750
 
739
751
  @raise LocalError: Invalid or non-C{scalar} B{C{latlonh}}, B{C{lon}} or B{C{height}}.
740
752
  '''
741
- notOverloaded(self, latlonh, lon=lon, height=height, M=M, name=name)
753
+ notOverloaded(self, latlonh, lon=lon, height=height, M=M, **name)
742
754
 
743
755
  def reverse(self, enh_, n=None, h_=0, M=None, **name): # PYCHOK no cover
744
756
  '''Convert I{Swiss} projection to WGS84 geodetic coordinates.
@@ -750,7 +762,7 @@ class _ChLV(object):
750
762
  @kwarg h_: I{Swiss h'} height for C{scalar} B{C{enh_}} and B{C{n}} (C{meter}).
751
763
  @kwarg M: If C{True}, return the I{concatenated} rotation L{EcefMatrix} iff available
752
764
  for C{ChLV} only, C{None} otherwise (C{bool}).
753
- @kwarg name: Optional name (C{str}).
765
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
754
766
 
755
767
  @return: A L{ChLV9Tuple}C{(Y, X, h_, lat, lon, height, ltp, ecef, M)} with the unfalsed
756
768
  I{Swiss Y, X} coordinates, I{Swiss h_} height, the given I{geodetic} C{lat},
@@ -848,24 +860,24 @@ class ChLV(_ChLV, Ltp):
848
860
  '''
849
861
  Ltp.__init__(self, latlonh0, **_xkwds(other_Ltp_kwds, ecef=None, name=ChLV.Bern.name))
850
862
 
851
- def forward(self, latlonh, lon=None, height=0, M=None, name=NN): # PYCHOK unused M
863
+ def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK unused M
852
864
  # overloaded for the _ChLV.forward.__doc__
853
- return Ltp.forward(self, latlonh, lon=lon, height=height, M=M, name=name)
865
+ return Ltp.forward(self, latlonh, lon=lon, height=height, M=M, **name)
854
866
 
855
867
  def reverse(self, enh_, n=None, h_=0, M=None, **name): # PYCHOK signature
856
868
  # overloaded for the _ChLV.reverse.__doc__
857
- Y, X, h_, name = self._YXh_n4(enh_, n, h_, **name)
858
- return Ltp.reverse(self, Y, X, h_, M=M, name=name)
869
+ Y, X, h_, n = self._YXh_n4(enh_, n, h_, **name)
870
+ return Ltp.reverse(self, Y, X, h_, M=M, name=n)
859
871
 
860
872
  @staticmethod
861
- def false2(Y, X, LV95=True, name=NN):
873
+ def false2(Y, X, LV95=True, **name):
862
874
  '''Add the I{Swiss LV95} or I{LV03} falsing.
863
875
 
864
876
  @arg Y: Unfalsed I{Swiss Y} easting (C{meter}).
865
877
  @arg X: Unfalsed I{Swiss X} northing (C{meter}).
866
878
  @kwarg LV95: If C{True} add C{LV95} falsing, if C{False} add
867
879
  C{LV03} falsing, otherwise leave unfalsed.
868
- @kwarg name: Optional name (C{str}).
880
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
869
881
 
870
882
  @return: A L{ChLVEN2Tuple}C{(E_LV95, N_LV95)} or a
871
883
  L{ChLVyx2Tuple}C{(y_LV03, x_LV03)} with falsed B{C{Y}}
@@ -873,7 +885,7 @@ class ChLV(_ChLV, Ltp):
873
885
  with B{C{Y}} and B{C{X}} as-is.
874
886
  '''
875
887
  e, n = t = _ChLV._falsing2(LV95)
876
- return t.classof(e + Y, n + X, name=name)
888
+ return t.classof(e + Y, n + X, **name)
877
889
 
878
890
  @staticmethod
879
891
  def isLV03(e, n):
@@ -910,7 +922,7 @@ class ChLV(_ChLV, Ltp):
910
922
  return None
911
923
 
912
924
  @staticmethod
913
- def unfalse2(e, n, LV95=None, name=NN):
925
+ def unfalse2(e, n, LV95=None, **name):
914
926
  '''Remove the I{Swiss LV95} or I{LV03} falsing.
915
927
 
916
928
  @arg e: Falsed I{Swiss E_LV95} or I{y_LV03} easting (C{meter}).
@@ -918,13 +930,13 @@ class ChLV(_ChLV, Ltp):
918
930
  @kwarg LV95: If C{True} remove I{LV95} falsing, if C{False} remove
919
931
  I{LV03} falsing, otherwise use method C{isLV95(B{e},
920
932
  B{n})}.
921
- @kwarg name: Optional name (C{str}).
933
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
922
934
 
923
935
  @return: A L{ChLVYX2Tuple}C{(Y, X)} with the unfalsed B{C{e}}
924
936
  respectively B{C{n}}.
925
937
  '''
926
938
  Y, X = _ChLV._falsing2(ChLV.isLV95(e, n) if LV95 is None else LV95)
927
- return ChLVYX2Tuple(e - Y, n - X, name=name)
939
+ return ChLVYX2Tuple(e - Y, n - X, **name)
928
940
 
929
941
 
930
942
  class ChLVa(_ChLV, LocalCartesian):
@@ -937,15 +949,15 @@ class ChLVa(_ChLV, LocalCartesian):
937
949
  def __init__(self, name=ChLV.Bern.name):
938
950
  '''New I{Approximate WGS84-Swiss} L{ChLVa} converter, centered at I{Bern, Ch}.
939
951
 
940
- @kwarg name: Optional name (C{str}), overriding C{Bern.name}.
952
+ @kwarg name: Optional C{B{name}=Bern.name} (C{str}).
941
953
  '''
942
954
  LocalCartesian.__init__(self, latlonh0=ChLV.Bern, name=name)
943
955
 
944
- def forward(self, latlonh, lon=None, height=0, M=None, name=NN):
956
+ def forward(self, latlonh, lon=None, height=0, M=None, **name):
945
957
  # overloaded for the _ChLV.forward.__doc__
946
- lat, lon, h, name = _llhn4(latlonh, lon, height, name=name)
947
- a, b, h_ = _ChLV._llh2abh_3(lat, lon, h)
948
- a2, b2 = a**2, b**2
958
+ lat, lon, h, n = _llhn4(latlonh, lon, height, **name)
959
+ a, b, h_ = _ChLV._llh2abh_3(lat, lon, h)
960
+ a2, b2 = a**2, b**2
949
961
 
950
962
  Y = fsumf_( 72.37, 211455.93 * b,
951
963
  -10938.51 * b * a,
@@ -956,13 +968,13 @@ class ChLVa(_ChLV, LocalCartesian):
956
968
  76.63 * a2,
957
969
  -194.56 * b2 * a,
958
970
  119.79 * a2 * a) # + 200_000
959
- return self._ChLV9Tuple(True, M, name, Y, X, h_, lat, lon, h)
971
+ return self._ChLV9Tuple(True, M, n, Y, X, h_, lat, lon, h)
960
972
 
961
973
  def reverse(self, enh_, n=None, h_=0, M=None, **name): # PYCHOK signature
962
974
  # overloaded for the _ChLV.reverse.__doc__
963
- Y, X, h_, name = self._YXh_n4(enh_, n, h_, **name)
964
- a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
965
- ab_d, a2, b2 = ChLV._ab_d, a**2, b**2
975
+ Y, X, h_, n = self._YXh_n4(enh_, n, h_, **name)
976
+ a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
977
+ ab_d, a2, b2 = ChLV._ab_d, a**2, b**2
966
978
 
967
979
  lat = _Fsumf_(16.9023892, 3.238272 * b,
968
980
  -0.270978 * a2,
@@ -973,7 +985,7 @@ class ChLVa(_ChLV, LocalCartesian):
973
985
  0.791484 * a * b,
974
986
  0.1306 * a * b2,
975
987
  -0.0436 * a * a2).fover(ab_d)
976
- return self._ChLV9Tuple(False, M, name, Y, X, h_, lat, lon, h)
988
+ return self._ChLV9Tuple(False, M, n, Y, X, h_, lat, lon, h)
977
989
 
978
990
 
979
991
  class ChLVe(_ChLV, LocalCartesian):
@@ -995,15 +1007,15 @@ class ChLVe(_ChLV, LocalCartesian):
995
1007
  def __init__(self, name=ChLV.Bern.name):
996
1008
  '''New I{Approximate WGS84-Swiss} L{ChLVe} converter, centered at I{Bern, Ch}.
997
1009
 
998
- @kwarg name: Optional name (C{str}), overriding C{Bern.name}.
1010
+ @kwarg name: Optional C{B{name}=Bern.name} (C{str}).
999
1011
  '''
1000
1012
  LocalCartesian.__init__(self, latlonh0=ChLV.Bern, name=name)
1001
1013
 
1002
- def forward(self, latlonh, lon=None, height=0, M=None, name=NN, gamma=False): # PYCHOK gamma
1014
+ def forward(self, latlonh, lon=None, height=0, M=None, gamma=False, **name): # PYCHOK gamma
1003
1015
  # overloaded for the _ChLV.forward.__doc__
1004
- lat, lon, h, name = _llhn4(latlonh, lon, height, name=name)
1005
- a, b, h_ = _ChLV._llh2abh_3(lat, lon, h)
1006
- ab_M, z, _H = ChLV._ab_M, 0, Fhorner
1016
+ lat, lon, h, n = _llhn4(latlonh, lon, height, **name)
1017
+ a, b, h_ = _ChLV._llh2abh_3(lat, lon, h)
1018
+ ab_M, z, _H = ChLV._ab_M, 0, Fhorner
1007
1019
 
1008
1020
  B1 = _H(a, 211428.533991, -10939.608605, -2.658213, -8.539078, -0.00345, -0.007992)
1009
1021
  B3 = _H(a, -44.232717, 4.291740, -0.309883, 0.013924)
@@ -1016,7 +1028,7 @@ class ChLVe(_ChLV, LocalCartesian):
1016
1028
  B6 = 0.000488
1017
1029
  X = _H(b, B0, z, B2, z, B4, z, B6).fover(ab_M) # 1,000 Km!
1018
1030
 
1019
- t = self._ChLV9Tuple(True, M, name, Y, X, h_, lat, lon, h)
1031
+ t = self._ChLV9Tuple(True, M, n, Y, X, h_, lat, lon, h)
1020
1032
  if gamma:
1021
1033
  U1 = _H(a, 2255515.207166, 2642.456961, 1.284180, 2.577486, 0.001165)
1022
1034
  U3 = _H(a, -412.991934, 64.106344, -2.679566, 0.123833)
@@ -1025,11 +1037,11 @@ class ChLVe(_ChLV, LocalCartesian):
1025
1037
  t = t, g
1026
1038
  return t
1027
1039
 
1028
- def reverse(self, enh_, n=None, h_=0, M=None, name=NN, gamma=False): # PYCHOK gamma
1040
+ def reverse(self, enh_, n=None, h_=0, M=None, gamma=False, **name): # PYCHOK gamma
1029
1041
  # overloaded for the _ChLV.reverse.__doc__
1030
- Y, X, h_, name = self._YXh_n4(enh_, n, h_, name=name)
1031
- a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
1032
- s_d, _H, z = ChLV._s_d, Fhorner, 0
1042
+ Y, X, h_, n = self._YXh_n4(enh_, n, h_, **name)
1043
+ a, b, h = _ChLV._YXh_2abh3(Y, X, h_)
1044
+ s_d, _H, z = ChLV._s_d, Fhorner, 0
1033
1045
 
1034
1046
  A0 = _H(b, ChLV._sLat, 32386.4877666, -25.486822, -132.457771, 0.48747, 0.81305, -0.0069)
1035
1047
  A2 = _H(b, -2713.537919, -450.442705, -75.53194, -14.63049, -2.7604)
@@ -1043,7 +1055,7 @@ class ChLVe(_ChLV, LocalCartesian):
1043
1055
  lon = _H(a, ChLV._sLon, A1, z, A3, z, A5).fover(s_d)
1044
1056
  # == (ChLV._sLon + a * (A1 + a**2 * (A3 + a**2 * A5))) / s_d
1045
1057
 
1046
- t = self._ChLV9Tuple(False, M, name, Y, X, h_, lat, lon, h)
1058
+ t = self._ChLV9Tuple(False, M, n, Y, X, h_, lat, lon, h)
1047
1059
  if gamma:
1048
1060
  U1 = _H(b, 106679.792202, 17876.57022, 4306.5241, 794.87772, 148.1545, 27.8725)
1049
1061
  U3 = _H(b, -1435.508, -794.8777, -296.309, -92.908)
pygeodesy/ltpTuples.py CHANGED
@@ -18,9 +18,8 @@ from pygeodesy.errors import _TypeError, _TypesError, _xattr, \
18
18
  _xkwds, _xkwds_item2
19
19
  from pygeodesy.fmath import hypot, hypot_
20
20
  from pygeodesy.interns import NN, _4_, _azimuth_, _center_, _COMMASPACE_, \
21
- _down_, _east_, _ecef_, _elevation_, _height_, \
22
- _lat_, _lon_, _ltp_, _M_, _north_, _not_, _up_, \
23
- _X_, _x_, _xyz_, _Y_, _y_, _z_
21
+ _ecef_, _elevation_, _height_, _lat_, _lon_, \
22
+ _ltp_, _M_, _up_, _X_, _x_, _xyz_, _Y_, _y_, _z_
24
23
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
25
24
  from pygeodesy.named import _NamedBase, _NamedTuple, _Pass, _xnamed
26
25
  from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
@@ -35,13 +34,16 @@ from pygeodesy.vector3d import Vector3d
35
34
  from math import cos, radians
36
35
 
37
36
  __all__ = _ALL_LAZY.ltpTuples
38
- __version__ = '24.04.07'
37
+ __version__ = '24.05.24'
39
38
 
40
39
  _aer_ = 'aer'
41
40
  _alt_ = 'alt'
41
+ _down_ = 'down'
42
+ _east_ = 'east'
42
43
  _enu_ = 'enu'
43
44
  _h__ = 'h_'
44
45
  _ned_ = 'ned'
46
+ _north_ = 'north'
45
47
  _local_ = 'local'
46
48
  _roll_ = 'roll'
47
49
  _slantrange_ = 'slantrange'
@@ -108,7 +110,7 @@ def _xyzLocal(*Types, **name_inst):
108
110
  try:
109
111
  return inst.xyzLocal
110
112
  except (AttributeError, TypeError):
111
- raise _TypeError(n, inst, txt=_not_(_local_))
113
+ raise _TypeError(n, inst, txt_not_=_local_)
112
114
 
113
115
 
114
116
  class _NamedAerNed(_NamedBase):
pygeodesy/mgrs.py CHANGED
@@ -42,7 +42,7 @@ from pygeodesy.errors import _AssertionError, MGRSError, _parseX, \
42
42
  _ValueError, _xkwds
43
43
  from pygeodesy.interns import NN, _0_, _A_, _AtoZnoIO_, _band_, _B_, \
44
44
  _COMMASPACE_, _datum_, _easting_, _invalid_, \
45
- _northing_, _not_, _SPACE_, _W_, _Y_, _Z_, _zone_
45
+ _northing_, _SPACE_, _W_, _Y_, _Z_, _zone_
46
46
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _PYGEODESY_GEOCONVERT_
47
47
  from pygeodesy.named import _NamedBase, _NamedTuple, _Pass, _xnamed
48
48
  from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple
@@ -55,7 +55,7 @@ from pygeodesy.utm import toUtm8, _to3zBlat, Utm, _UTM_ZONE_MAX, _UTM_ZONE_MIN
55
55
  # from pygeodesy.utmupsBase import _UTM_ZONE_MAX, _UTM_ZONE_MIN # from .utm
56
56
 
57
57
  __all__ = _ALL_LAZY.mgrs
58
- __version__ = '23.12.03'
58
+ __version__ = '24.05.24'
59
59
 
60
60
  _AN_ = 'AN' # default south pole grid tile and band B
61
61
  _AtoPx_ = _AtoZnoIO_.tillP
@@ -357,7 +357,7 @@ class Mgrs(_NamedBase):
357
357
  @raise MGRSError: This MGRS is a I{non-polar} UTM reference.
358
358
  '''
359
359
  if self.isUTM:
360
- raise MGRSError(zoneB=self.zoneB, txt=_not_(_polar_))
360
+ raise MGRSError(zoneB=self.zoneB, txt_not_=_polar_)
361
361
  return self._toUtmUps(Ups, center)
362
362
 
363
363
  def toUtm(self, Utm=Utm, center=False):
@@ -654,7 +654,8 @@ def _um100km2(m):
654
654
  if __name__ == '__main__':
655
655
 
656
656
  from pygeodesy.ellipsoidalVincenty import fabs, LatLon
657
- from pygeodesy.lazily import _getenv, printf
657
+ # from pygeodesy.internals import printf # from .lazily
658
+ from pygeodesy.lazily import _getenv, printf
658
659
 
659
660
  # from math import fabs # from .ellipsoidalVincenty
660
661
  from os import access as _access, linesep as _NL, X_OK as _X_OK