pygeodesy 25.4.8__py2.py3-none-any.whl → 25.5.5__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 (97) hide show
  1. pygeodesy/__init__.py +36 -31
  2. pygeodesy/__main__.py +3 -3
  3. pygeodesy/albers.py +29 -36
  4. pygeodesy/auxilats/_CX_4.py +2 -2
  5. pygeodesy/auxilats/_CX_6.py +2 -2
  6. pygeodesy/auxilats/_CX_8.py +2 -2
  7. pygeodesy/auxilats/_CX_Rs.py +9 -9
  8. pygeodesy/auxilats/__init__.py +3 -3
  9. pygeodesy/auxilats/__main__.py +8 -6
  10. pygeodesy/auxilats/auxAngle.py +2 -2
  11. pygeodesy/auxilats/auxLat.py +5 -5
  12. pygeodesy/auxilats/auxily.py +5 -3
  13. pygeodesy/azimuthal.py +7 -6
  14. pygeodesy/basics.py +32 -18
  15. pygeodesy/booleans.py +18 -16
  16. pygeodesy/cartesianBase.py +26 -24
  17. pygeodesy/clipy.py +11 -10
  18. pygeodesy/constants.py +11 -10
  19. pygeodesy/css.py +14 -11
  20. pygeodesy/datums.py +8 -8
  21. pygeodesy/deprecated/bases.py +2 -2
  22. pygeodesy/deprecated/classes.py +2 -2
  23. pygeodesy/deprecated/consterns.py +4 -4
  24. pygeodesy/dms.py +8 -8
  25. pygeodesy/ecef.py +22 -29
  26. pygeodesy/ecefLocals.py +186 -0
  27. pygeodesy/elevations.py +9 -8
  28. pygeodesy/ellipsoidalBase.py +19 -8
  29. pygeodesy/ellipsoidalBaseDI.py +17 -15
  30. pygeodesy/ellipsoidalNvector.py +6 -3
  31. pygeodesy/ellipsoidalVincenty.py +4 -1
  32. pygeodesy/ellipsoids.py +186 -164
  33. pygeodesy/elliptic.py +9 -9
  34. pygeodesy/errors.py +44 -43
  35. pygeodesy/etm.py +7 -7
  36. pygeodesy/fmath.py +30 -14
  37. pygeodesy/formy.py +11 -12
  38. pygeodesy/frechet.py +216 -109
  39. pygeodesy/fstats.py +5 -4
  40. pygeodesy/fsums.py +79 -78
  41. pygeodesy/gars.py +4 -3
  42. pygeodesy/geodesici.py +15 -14
  43. pygeodesy/geodesicw.py +34 -32
  44. pygeodesy/geodesicx/__init__.py +1 -1
  45. pygeodesy/geodesicx/__main__.py +11 -9
  46. pygeodesy/geodesicx/gx.py +30 -33
  47. pygeodesy/geodesicx/gxarea.py +2 -2
  48. pygeodesy/geodesicx/gxline.py +5 -5
  49. pygeodesy/geodsolve.py +18 -17
  50. pygeodesy/geohash.py +5 -5
  51. pygeodesy/geoids.py +34 -31
  52. pygeodesy/hausdorff.py +17 -13
  53. pygeodesy/heights.py +2 -4
  54. pygeodesy/internals.py +28 -44
  55. pygeodesy/interns.py +10 -7
  56. pygeodesy/iters.py +8 -8
  57. pygeodesy/karney.py +68 -62
  58. pygeodesy/ktm.py +5 -5
  59. pygeodesy/latlonBase.py +20 -21
  60. pygeodesy/lazily.py +104 -78
  61. pygeodesy/lcc.py +11 -9
  62. pygeodesy/ltp.py +56 -58
  63. pygeodesy/ltpTuples.py +35 -36
  64. pygeodesy/mgrs.py +7 -6
  65. pygeodesy/named.py +48 -177
  66. pygeodesy/nvectorBase.py +7 -7
  67. pygeodesy/osgr.py +9 -8
  68. pygeodesy/points.py +12 -10
  69. pygeodesy/props.py +25 -25
  70. pygeodesy/resections.py +83 -80
  71. pygeodesy/rhumb/__init__.py +1 -1
  72. pygeodesy/rhumb/aux_.py +7 -7
  73. pygeodesy/rhumb/bases.py +22 -20
  74. pygeodesy/rhumb/ekx.py +6 -6
  75. pygeodesy/rhumb/solve.py +15 -15
  76. pygeodesy/solveBase.py +3 -3
  77. pygeodesy/sphericalBase.py +6 -6
  78. pygeodesy/sphericalNvector.py +6 -5
  79. pygeodesy/sphericalTrigonometry.py +8 -7
  80. pygeodesy/streprs.py +14 -14
  81. pygeodesy/trf.py +14 -12
  82. pygeodesy/triaxials.py +29 -26
  83. pygeodesy/units.py +5 -4
  84. pygeodesy/unitsBase.py +5 -4
  85. pygeodesy/ups.py +3 -3
  86. pygeodesy/utily.py +4 -4
  87. pygeodesy/utmups.py +4 -4
  88. pygeodesy/utmupsBase.py +110 -18
  89. pygeodesy/vector2d.py +20 -13
  90. pygeodesy/vector3d.py +7 -6
  91. pygeodesy/webmercator.py +6 -5
  92. pygeodesy/wgrs.py +6 -5
  93. {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/METADATA +30 -25
  94. pygeodesy-25.5.5.dist-info/RECORD +119 -0
  95. pygeodesy-25.4.8.dist-info/RECORD +0 -118
  96. {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/WHEEL +0 -0
  97. {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/top_level.txt +0 -0
pygeodesy/lazily.py CHANGED
@@ -30,13 +30,14 @@ and line number.
30
30
  from pygeodesy import internals as _internals, interns as _interns, \
31
31
  _isfrozen # DON'T _lazy_import2
32
32
  # from pygeodesy.errors import _error_init, _xkwds_item2 # _ALL_MODS
33
- from pygeodesy.internals import _caller3, _DUNDER_nameof, _getPYGEODESY, _headof, \
34
- _is_DUNDER_main, printf, _tailof, _versions
35
- from pygeodesy.interns import NN, _1_, _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, \
36
- _doesn_t_exist_, _DOT_, _DUNDER_all_, _EQUALSPACED_, \
37
- _from_, _HASH_, _immutable_, _line_, _module_, _no_, \
38
- _not_, _or_, _pygeodesy_abspath_, _pygeodesy_, _sys, \
39
- _SUB_PACKAGES, _UNDER_, _version_, _intern # function
33
+ from pygeodesy.internals import _caller3, _envPYGEODESY, _headof, printf, _tailof, \
34
+ typename, _versions # _getenv, _PYGEODESY_ENV, \
35
+ # _MODS_Base, _MODS.sys_version_info2
36
+ from pygeodesy.interns import _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, _DALL_, \
37
+ _DMAIN_, _doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
38
+ _HASH_, _immutable_, _line_, _module_, NN, _no_, _not_, \
39
+ _pygeodesy_, _pygeodesy_abspath_, _SPACE_, _SUB_PACKAGES, \
40
+ _or_, _UNDER_, _version_, _sys, _intern # function, _1_
40
41
  try:
41
42
  from importlib import import_module
42
43
  except ImportError as x: # Python 2.6-
@@ -45,12 +46,13 @@ except ImportError as x: # Python 2.6-
45
46
 
46
47
  _a0 = () # PYCHOK empty tuple
47
48
  _asSPACED_ = ' as '
48
- _FOR_DOCS = _getPYGEODESY('FOR_DOCS') # for epydoc ...
49
- _init__all__ = _FOR_DOCS or _getPYGEODESY('_init__all__', _DUNDER_all_) == _DUNDER_all_ # PYCHOK exported
49
+ _FOR_DOCS = _envPYGEODESY('FOR_DOCS') # for epydoc ...
50
+ _imported_ = 'imported'
51
+ _init__all__ = _FOR_DOCS or _envPYGEODESY('_init__all__', _DALL_) == _DALL_ # PYCHOK exported
50
52
  _lazily_ = 'lazily'
51
53
  _PYTHON_X_DEV = getattr(_sys.flags, 'dev_mode', False) # PYCHOK Python 3.2+
52
54
  _unlazy = _unLazy0 = _isfrozen or _internals._MODS.sys_version_info2 < (3, 7) # PYCHOK mod.__getattr__ 3.7+
53
- _WARNINGS_X_DEV = _getPYGEODESY('WARNINGS') and (_PYTHON_X_DEV or bool(_sys.warnoptions)) # PYCHOK .props
55
+ _WARNINGS_X_DEV = _envPYGEODESY('WARNINGS') and (_PYTHON_X_DEV or bool(_sys.warnoptions)) # PYCHOK .props
54
56
 
55
57
  # @module_property[_RO?] <https://GitHub.com/jtushman/proxy_tools/> <https://discuss.Python.org/t/47379>
56
58
  isLazy = None # see @var isLazy in .__init__
@@ -93,18 +95,18 @@ class _Dict(dict):
93
95
  @raise AssertionError: The B{C{name}} already exists
94
96
  with a different B{C{mod_}}.
95
97
  '''
96
- if name in self: # PYCHOK no cover
98
+ try:
97
99
  sub = self[name] # duplicate OK
98
100
  if sub != mod_ and sub not in subs:
99
101
  t = _DOT_(self._name, name)
100
102
  t = _COLONSPACE_(t, repr(sub))
101
103
  t = _COMMASPACE_(t, _not_(repr(mod_)))
102
104
  raise AssertionError(t)
103
- else:
105
+ except KeyError:
104
106
  self[name] = mod_
105
107
 
106
108
  def _NAME(self, which):
107
- self._name = _intern(_DUNDER_nameof(which).upper())
109
+ self._name = _intern(typename(which).upper())
108
110
 
109
111
 
110
112
  class _NamedEnum_RO(dict):
@@ -214,6 +216,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
214
216
  'parseDDDMMSS', 'parseDMS', 'parseDMS2', 'parse3llh', 'parseRad', 'precision', 'toDMS'),
215
217
  ecef=_a('EcefError', 'EcefFarrell21', 'EcefFarrell22', 'EcefKarney', 'EcefMatrix',
216
218
  'EcefSudano', 'Ecef9Tuple', 'EcefVeness', 'EcefYou'),
219
+ ecefLocals=_a(), # module only
217
220
  elevations=_a('Elevation2Tuple', 'GeoidHeight2Tuple',
218
221
  'elevation2', 'geoidHeight2'),
219
222
  ellipsoidalBase=_a(), # module only
@@ -238,7 +241,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
238
241
  'crosserrors', 'exception_chaining', 'isError', 'limiterrors', 'rangerrors'),
239
242
  etm=_a('Etm', 'ETMError', 'ExactTransverseMercator',
240
243
  'parseETM5', 'toEtm8'),
241
- fmath=_a('Fdot', 'Fhorner', 'Fhypot', 'Fpolynomial', 'Fpowers', 'Fcbrt', 'Froot', 'Fsqrt',
244
+ fmath=_a('Fdot', 'Fdot_', 'Fhorner', 'Fhypot', 'Fpolynomial', 'Fpowers', 'Fcbrt', 'Froot', 'Fsqrt',
242
245
  'bqrt', 'cbrt', 'cbrt2', 'euclid', 'euclid_',
243
246
  'facos1', 'fasin1', 'fatan', 'fatan1', 'fatan2', 'favg',
244
247
  'fdot', 'fdot_', 'fdot3', 'fma', 'fmean', 'fmean_', 'fhorner', 'fidw', 'f2mul_',
@@ -429,7 +432,7 @@ class _ALL_MODS(_internals._MODS_Base):
429
432
  v = _lazy_dict[name] # package.__dict__
430
433
  except KeyError:
431
434
  v = _lazy_module(name) # package.__getattr__
432
- if _tailof(_DUNDER_nameof(v)) != name:
435
+ if _tailof(typename(v)) != name:
433
436
  try:
434
437
  v = getattr(v, _tailof(name))
435
438
  except AttributeError:
@@ -463,7 +466,7 @@ class _ALL_MODS(_internals._MODS_Base):
463
466
 
464
467
  @raise ImportError: Importing module B{C{name}} failed.
465
468
  '''
466
- if _headof(name) != parent and not _is_DUNDER_main(name):
469
+ if _headof(name) != parent and name != _DMAIN_:
467
470
  name = _DOT_(parent, name)
468
471
  try:
469
472
  return _sys.modules[name]
@@ -475,20 +478,18 @@ class _ALL_MODS(_internals._MODS_Base):
475
478
  '''
476
479
  return _sys.modules.get(name, None)
477
480
 
478
- def into(self, **mod_DUNDER_name):
479
- '''Lazily import module C{mod} into module C{DUNDER_name}
480
- and set C{DUNDER_name._mod} to module C{mod}, I{once}.
481
+ def into(self, **mod_DNAME):
482
+ '''Deferred import of module C{mod} into module C{_DNAME_}
483
+ and overwrite C{_DNAME_._mod} to module C{mod}, I{once}
484
+ at the first access of an attribute of module C{mod}.
481
485
  '''
486
+ # assert len(mod_DNAME) == 1
487
+ # mod, dun = mod_DNAME.popitem()
488
+
482
489
  class _Into(object):
483
490
 
484
491
  def __getattr__(unused, name):
485
- mod, dun = self.errors._xkwds_item2(mod_DUNDER_name)
486
- _mod = _UNDER_(NN, mod)
487
- d = self.getmodule(dun) # '__main__' OK
488
- i = _getmodattr(d, _mod, dun)
489
- assert isinstance(i, _Into)
490
- m = self.getmodule(mod)
491
- setattr(d, _mod, m) # overwrite C{d._mod}
492
+ m = _getmodinto(mod_DNAME, _Into)
492
493
  return getattr(m, name)
493
494
 
494
495
  return _Into()
@@ -509,14 +510,14 @@ class _ALL_MODS(_internals._MODS_Base):
509
510
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
510
511
 
511
512
  __all__ = _ALL_LAZY.lazily
512
- __version__ = '25.01.25'
513
+ __version__ = '25.04.30'
513
514
 
514
515
 
515
516
  def _ALL_OTHER(*objs):
516
517
  '''(INTERNAL) Get class and function B{C{objs}} for __all__.
517
518
  '''
518
519
  def _interned(o): # intern'd base name
519
- n = _tailof(_DUNDER_nameof(o))
520
+ n = _tailof(typename(o))
520
521
  i = NN(_UNDER_, n, _UNDER_) # intern'd
521
522
  return getattr(_interns, i, n)
522
523
 
@@ -536,12 +537,12 @@ else:
536
537
 
537
538
 
538
539
  def _all_deprecates():
539
- '''(INTERNAL) Build C{dict} of all deprecated imports.
540
+ '''(INTERNAL) Build C{dict} of all deprecated imports and attributes.
540
541
  '''
541
- _D = _ALL_DEPRECATES
542
- if not _D:
543
- _ALL_DEPRECATED.fill_D(_D, _all_deprecates) # see _all_imports()
544
- return _D
542
+ D = _ALL_DEPRECATES
543
+ if not D:
544
+ _ALL_DEPRECATED.fill_D(D, _all_deprecates) # see _all_imports()
545
+ return D
545
546
 
546
547
  _ALL_DEPRECATES = _Dict() # PYCHOK _ALL_DEPRECATED.imports()
547
548
 
@@ -565,10 +566,10 @@ def _all_imports():
565
566
  # from <module> import <attr> - [<attr>] = <module>
566
567
  # from pygeodesy import <attr> - [<attr>] = <attr>
567
568
  # from <module> import <attr> as <name> - [<name>] = <module>.<attr>.
568
- _D = _ALL_IMPORTS
569
- if not _D:
570
- _ALL_LAZY.fill_D(_D, _all_imports) # see _all_deprecates()
571
- return _D
569
+ D = _ALL_IMPORTS
570
+ if not D:
571
+ _ALL_LAZY.fill_D(D, _all_imports) # see _all_deprecates()
572
+ return D
572
573
 
573
574
  _ALL_IMPORTS = _Dict() # PYCHOK _ALL_LAZY.imports()
574
575
 
@@ -582,7 +583,7 @@ def _all_missing2(_all_):
582
583
  _alzy = _Dict((a, a) for a in _ALL_INIT)
583
584
  _alzy.update(_all_imports()) # without _all_backups!
584
585
  return ((_DOT_(_lazily_, _all_imports.__name__), _diff(_all_, _alzy)),
585
- (_DOT_(_pygeodesy_, _DUNDER_all_), _diff(_alzy.keys(), _all_)))
586
+ (_DOT_(_pygeodesy_, _DALL_), _diff(_alzy.keys(), _all_)))
586
587
 
587
588
 
588
589
  def _getattras(attr_as): # test/testDeprecated
@@ -598,11 +599,29 @@ def _getmodattr(m, name, mod=_pygeodesy_):
598
599
  try:
599
600
  return getattr(m, name)
600
601
  except AttributeError:
601
- name = _DOT_(mod, name)
602
+ name = _DOT_(typename(m, mod), name)
602
603
  # <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
603
604
  raise LazyAttributeError(_no_(_attribute_), txt=name)
604
605
 
605
606
 
607
+ def _getmodinto(mod_DNAME, *Intos):
608
+ '''(INTERNAL) Core of C{_ALL_MODS.into}.
609
+ '''
610
+ _MODS = _ALL_MODS
611
+ mod, dun = _MODS.errors._xkwds_item2(mod_DNAME)
612
+ _mod = _UNDER_(NN, mod)
613
+ d = _MODS.getmodule(dun) # '__main__' OK
614
+ i = _getmodattr(d, _mod, dun)
615
+ assert isinstance(i, Intos)
616
+ m = _MODS.getmodule(mod)
617
+ setattr(d, _mod, m) # overwrite C{d._mod}
618
+ if isLazy > 1:
619
+ t = _SPACE_(_HASH_, _imported_, m.__name__) # typename(m)
620
+ _hash_imported(t, _MODS.into.__name__)
621
+ assert getattr(d, _mod, None) is m
622
+ return m
623
+
624
+
606
625
  def _getmodule(name, *parent):
607
626
  '''(INTERNAL) Wrapper for C{import_module}.
608
627
  '''
@@ -613,6 +632,18 @@ def _getmodule(name, *parent):
613
632
  raise LazyImportError(_no_(_module_), txt=name)
614
633
 
615
634
 
635
+ def _hash_imported(t, by_into, up=3):
636
+ '''(INTERNAL) Helper for C{_lazy_import2} and C{_ALL_MODS.into}.
637
+ '''
638
+ if isLazy > 2:
639
+ try: # see C{internals._caller3}
640
+ _, f, s = _caller3(up)
641
+ t = _SPACE_(t, by_into, f, _line_, s)
642
+ except ValueError:
643
+ pass
644
+ printf(t) # XXX print
645
+
646
+
616
647
  # def _lazy_attributes(DUNDER_name):
617
648
  # '''(INTERNAL) Return a function to C{B{__name__}.__getattr__(attr)}
618
649
  # on lazily imported modules and sub-modules.
@@ -656,19 +687,16 @@ def _lazy_import2(pack): # MCCABE 14
656
687
 
657
688
  @see: The original U{modutil<https://PyPI.org/project/modutil>},
658
689
  U{PEP 562<https://www.Python.org/dev/peps/pep-0562>} and the
659
- U{new way<https://Snarky.Ca/lazy-importing-in-python-3-7/>}.
690
+ U{new way<https://Snarky.CA/lazy-importing-in-python-3-7/>}.
660
691
  '''
661
- _DOT_ = _interns._DOT_
662
- _SPACE_ = _interns._SPACE_
663
-
664
692
  if pack != _pygeodesy_ or _unlazy: # Python 3.7+ # PYCHOK no cover
665
- t = _DOT_(pack, _DUNDER_nameof(_lazy_import2))
693
+ t = _DOT_(pack, typename(_lazy_import2))
666
694
  raise LazyImportError(_no_(t), txt=_versions())
667
695
 
668
696
  package, parent = _lazy_init2(pack) # _pygeodesy_
669
697
 
670
- _DUNDER_package_ = '__package__'
671
- _lazily_imported_ = _SPACE_(_HASH_, _lazily_, 'imported', parent)
698
+ _DPACKAGE_ = '__package__'
699
+ _lazily_imported_ = _SPACE_(_HASH_, _lazily_, _imported_, parent)
672
700
 
673
701
  sub_packages = set((parent, NN) + tuple(
674
702
  _DOT_(parent, s) for s in _SUB_PACKAGES))
@@ -687,13 +715,13 @@ def _lazy_import2(pack): # MCCABE 14
687
715
  else: # from mod import name
688
716
  attr = name
689
717
  v = _getmodule(_DOT_(pack, mod), parent)
690
- t = getattr(v, _DUNDER_package_, None)
718
+ t = getattr(v, _DPACKAGE_, None)
691
719
  if t not in sub_packages: # invalid module package
692
- raise LazyImportError(_DOT_(mod, _DUNDER_package_), t)
720
+ raise LazyImportError(_DOT_(mod, _DPACKAGE_), t)
693
721
  if attr: # get mod.attr
694
722
  v = _getmodattr(v, attr, mod)
695
723
 
696
- elif name in (_DUNDER_all_,): # XXX _DUNDER_dir_, _DUNDER_members_?
724
+ elif name in (_DALL_,): # XXX _Ddir_, _Dmembers_?
697
725
  v = _ALL_INIT + tuple(imports.keys())
698
726
  else: # PYCHOK no cover
699
727
  t = _no_(_module_, _or_, _attribute_)
@@ -705,13 +733,7 @@ def _lazy_import2(pack): # MCCABE 14
705
733
  t = _DOT_(_lazily_imported_, name)
706
734
  if mod and _tailof(mod) != name:
707
735
  t = _SPACE_(t, _from_, _DOT_(NN, mod))
708
- if isLazy > 2:
709
- try: # see C{_caller3}
710
- _, f, s = _caller3(2)
711
- t = _SPACE_(t, _by_, f, _line_, s)
712
- except ValueError:
713
- pass
714
- printf(t) # XXX print
736
+ _hash_imported(t, _by_)
715
737
 
716
738
  return v # __getattr__
717
739
 
@@ -722,18 +744,18 @@ def _lazy_import2(pack): # MCCABE 14
722
744
  return package, __getattr__ # _lazy_import2
723
745
 
724
746
 
725
- # def _lazy_import_all(DUNDER_name):
747
+ # def _lazy_import_all(Dname):
726
748
  # '''(INTERNAL) Return a function mimicking C{from B{__name__} import *},
727
749
  # of all items, see .deprecated.__init__
728
750
  # '''
729
751
  # if _unlazy:
730
- # raise AssertionError(_COMMASPACE_(DUNDER_name, _not_(_DEPRECATED_)))
752
+ # raise AssertionError(_COMMASPACE_(Dname, _not_(_DEPRECATED_)))
731
753
  #
732
- # _getattr = _lazy_attributes(DUNDER_name) # __name__.__getattr__
733
- # _import_start = _lazy_import_star(DUNDER_name, ALL_=_ALL_IMPORTS)
754
+ # _getattr = _lazy_attributes(Dname) # __name__.__getattr__
755
+ # _import_start = _lazy_import_star(Dname, ALL_=_ALL_IMPORTS)
734
756
  #
735
757
  # def _import_all(attr, *dflt):
736
- # return _import_star(DUNDER_name) if attr == _DUNDER_all_ else \
758
+ # return _import_star(Dname) if attr == _DALL_ else \
737
759
  # _getattr(attr, *dflt)
738
760
  #
739
761
  # return _import_all
@@ -799,15 +821,15 @@ def _lazy_init2(pack):
799
821
  '''
800
822
  global isLazy, _unLazy0
801
823
 
802
- z = _getPYGEODESY('LAZY_IMPORT', _1_) # 1 default on 3.7+
824
+ E = _internals._PYGEODESY_ENV('LAZY_IMPORT')
825
+ z = _internals._getenv(E, _interns._1_) # 1 default on 3.7+
803
826
  z = z.strip() # like PYTHONVERBOSE et.al.
804
827
  isLazy = int(z) if z.isdigit() else (1 if z else 0)
805
828
 
806
829
  _unLazy0 = _unlazy or not isLazy # pre-3.7 or w/o lazy import
807
830
 
808
831
  if isLazy < 1: # invalid, not enabled
809
- e = _internals._PYGEODESY('LAZY_IMPORT')
810
- raise LazyImportError(e, repr(z), txt_not_='enabled')
832
+ raise LazyImportError(E, repr(z), txt_not_='enabled')
811
833
  if _sys.flags.verbose: # PYCHOK no cover
812
834
  isLazy += 1
813
835
 
@@ -820,7 +842,7 @@ def _lazy_init2(pack):
820
842
 
821
843
  except (AttributeError, ImportError) as x:
822
844
  isLazy = False # failed
823
- z = _DUNDER_nameof(_lazy_init2)
845
+ z = typename(_lazy_init2)
824
846
  raise LazyImportError(z, pack, cause=x)
825
847
 
826
848
  return package, parent
@@ -837,23 +859,22 @@ def _lazy_module(name): # overwritten by _lazy_import2
837
859
  return m
838
860
 
839
861
 
840
- # def _lazy_subs(DUNDER_name, force=_FOR_DOCS, over=False):
841
- # '''(INTERNAL) Return the names of a package's sub-packages and
842
- # update the package's C{__dict__} accordingly.
862
+ # def _lazy_subs(__name__, force=_FOR_DOCS, over=False):
863
+ # '''(INTERNAL) Return the names of a __name__ package's sub-packages
864
+ # and update the package's C{__dict__} accordingly.
843
865
  # '''
844
866
  # sm = dict()
845
- # if force and not _is_DUNDER_main(DUNDER_name):
846
- # nm = _tailof(DUNDER_name)
867
+ # if force and __name__ != _DMAIN_:
868
+ # nm = _tailof(__name__)
847
869
  # _a = _ALL_MODS.getattr
848
870
  # _m = _ALL_MODS.getmodule
849
- # d = _a(DUNDER_name, _DUNDER_dict_, {})
850
- # for n in _a(DUNDER_name, _DUNDER_all_, ()):
871
+ # d = _a(__name__, _DDICT_, {})
872
+ # for n in _a(__name__, _DALL_, ()):
851
873
  # try: # n is a class name, get its mod name
852
- # m = _a(DUNDER_name, n).__module__
874
+ # m = _a(__name__, n).__module__
853
875
  # n, s = m.split(_DOT_)[-2:]
854
876
  # if n == nm and s not in sm:
855
- # # like import m as s
856
- # m = _m(m)
877
+ # m = _m(m) # == import m as s
857
878
  # sm[s] = m if over else d.get(s, m)
858
879
  # except (AttributeError, ImportError, ValueError) as x:
859
880
  # pass
@@ -861,9 +882,8 @@ def _lazy_module(name): # overwritten by _lazy_import2
861
882
  #
862
883
  # return _ALL_OTHER(*sm.values())
863
884
 
864
- # del _a, _a0
865
885
 
866
- if _is_DUNDER_main(__name__): # PYCHOK no cover
886
+ if __name__ == _DMAIN_:
867
887
 
868
888
  def _main():
869
889
  from timeit import timeit
@@ -879,12 +899,18 @@ if _is_DUNDER_main(__name__): # PYCHOK no cover
879
899
 
880
900
  t1 = timeit(t1, number=1000000)
881
901
  t2 = timeit(t2, number=1000000)
882
- A = _DUNDER_nameof(_ALL_MODS.__class__)
902
+ A = typename(_ALL_MODS)
883
903
  v = _versions()
884
904
  printf('%.6f import vs %.6f %s: %.2fX, %s', t1, t2, A, (t1 / t2), v)
885
905
 
886
906
  _main()
887
907
 
908
+ # % python3.13 -W ignore -m pygeodesy.lazily
909
+ # 0.054235 import vs 0.052469 _ALL_MODS: 1.03X, pygeodesy 25.4.24 Python 3.13.3 64bit arm64 macOS 15.4
910
+
911
+ # % python2 -m pygeodesy.lazily
912
+ # 0.653715 import vs 0.321318 _ALL_MODS: 2.03X, pygeodesy 25.4.24 Python 2.7.18 64bit arm64_x86_64 macOS 10.16
913
+
888
914
  # % python3.13 -W ignore -m pygeodesy.lazily
889
915
  # 0.106602 import vs 0.078136 _ALL_MODS: 1.36X, pygeodesy 24.10.24 Python 3.13.0 64bit arm64 macOS 14.6.1
890
916
 
pygeodesy/lcc.py CHANGED
@@ -24,15 +24,17 @@ and John P. Snyder U{'Map Projections - A Working Manual'<https://Pubs.USGS.gov/
24
24
  # make sure int/int division yields float quotient, see .basics
25
25
  from __future__ import division as _; del _ # PYCHOK semicolon
26
26
 
27
- from pygeodesy.basics import copysign0, _xinstanceof, _xsubclassof
27
+ from pygeodesy.basics import copysign0, _isin, _xinstanceof, _xsubclassof, \
28
+ typename
28
29
  from pygeodesy.constants import EPS, EPS02, PI_2, _float as _F, _0_0, _0_5, \
29
30
  _1_0, _2_0, _90_0
30
31
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
31
32
  from pygeodesy.datums import Datums, _ellipsoidal_datum
32
33
  from pygeodesy.errors import _IsnotError, _ValueError
33
34
  from pygeodesy.fmath import hypot, _ALL_LAZY
34
- from pygeodesy.interns import NN, _COMMASPACE_, _ellipsoidal_, _GRS80_, _k0_, \
35
- _lat0_, _lon0_, _m_, _NAD83_, _NTF_, _SPACE_, \
35
+ # from pygeodesy.internals import typename # from .basics
36
+ from pygeodesy.interns import NN, _COMMASPACE_, _DMAIN_, _ellipsoidal_, _GRS80_, \
37
+ _k0_, _lat0_, _lon0_, _m_, _NAD83_, _NTF_, _SPACE_, \
36
38
  _WGS84_, _C_ # PYCHOK used!
37
39
  # from pygeodesy.lazily import _ALL_LAZY # from .fmath
38
40
  from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name2__, _NamedBase, \
@@ -48,7 +50,7 @@ from pygeodesy.utily import atan1, degrees90, degrees180, sincos2, tanPI_2_2
48
50
  from math import atan, fabs, log, radians, sin, sqrt
49
51
 
50
52
  __all__ = _ALL_LAZY.lcc
51
- __version__ = '24.11.06'
53
+ __version__ = '25.04.14'
52
54
 
53
55
  _E0_ = 'E0'
54
56
  _N0_ = 'N0'
@@ -348,7 +350,7 @@ class Conic(_NamedEnumItem):
348
350
  return PI_2 - atan(t_x) * _2_0 # XXX + self._phi0
349
351
 
350
352
 
351
- Conic._name = Conic.__name__
353
+ Conic._name = typename(Conic)
352
354
 
353
355
 
354
356
  class Conics(_NamedEnum):
@@ -414,7 +416,7 @@ class Lcc(_NamedBase):
414
416
 
415
417
  @raise TypeError: If B{C{conic}} is not L{Conic}.
416
418
  '''
417
- if conic not in (None, Lcc._conic):
419
+ if not _isin(conic, None, Lcc._conic):
418
420
  self.conic = conic
419
421
  self._easting = Easting(e, falsed=conic.E0 > 0, Error=LCCError)
420
422
  self._northing = Northing(n, falsed=conic.N0 > 0, Error=LCCError)
@@ -524,7 +526,7 @@ class Lcc(_NamedBase):
524
526
 
525
527
  @raise TypeError: If B{C{datum}} is not ellipsoidal.
526
528
  '''
527
- if datum in (None, self.conic.datum):
529
+ if _isin(datum, None, self.conic.datum):
528
530
  r = LatLonDatum3Tuple(self.latlon.lat,
529
531
  self.latlon.lon,
530
532
  self.conic.datum, name=self.name)
@@ -556,7 +558,7 @@ class Lcc(_NamedBase):
556
558
  _xsubclassof(_LLEB, LatLon=LatLon)
557
559
 
558
560
  c = self.conic
559
- if datum not in (None, self.conic.datum):
561
+ if not _isin(datum, None, self.conic.datum):
560
562
  c = c.toDatum(datum)
561
563
 
562
564
  e = self.easting - c._E0
@@ -648,7 +650,7 @@ def toLcc(latlon, conic=Conics.WRF_Lb, height=None, Lcc=Lcc,
648
650
  return _xnamed(r, name) if name else r
649
651
 
650
652
 
651
- if __name__ == '__main__':
653
+ if __name__ == _DMAIN_:
652
654
 
653
655
  from pygeodesy.interns import _NL_, _NLATvar_
654
656
  from pygeodesy.lazily import printf