pygeodesy 24.6.24__py2.py3-none-any.whl → 24.7.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.
pygeodesy/props.py CHANGED
@@ -25,7 +25,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
25
25
  from functools import wraps as _wraps
26
26
 
27
27
  __all__ = _ALL_LAZY.props
28
- __version__ = '24.05.26'
28
+ __version__ = '24.07.23'
29
29
 
30
30
  _class_ = 'class'
31
31
  _dont_use_ = _DEPRECATED_ + ", don't use."
@@ -48,11 +48,12 @@ def _allPropertiesOf(Clas_or_inst, *Bases, **excls):
48
48
  except AttributeError:
49
49
  raise
50
50
  S = () # not an inst
51
- B = Bases or _PropertyBase
52
- _isa = isinstance
51
+ B = Bases or _PropertyBase
52
+ P = _property_RO___
53
53
  for C in S:
54
54
  for n, p in C.__dict__.items():
55
- if _isa(p, B) and p.name == n and n not in excls:
55
+ if isinstance(p, B) and p.name == n and not (
56
+ isinstance(p, P) or n in excls):
56
57
  yield p
57
58
 
58
59
 
@@ -251,9 +252,9 @@ class Property_RO(_PropertyBase):
251
252
  <https://Docs.Python.org/3/library/functools.html#functools.cache>}
252
253
  to I{cache} or I{memoize} the property value.
253
254
 
254
- @see: Luciano Ramalho, "Fluent Python", O'Reilly, Example 19-24, 2016
255
- p. 636 or Example 22-28, 2022 p. 870 and U{class Property
256
- <https://docs.Python.org/3/howto/descriptor.html>}.
255
+ @see: Luciano Ramalho, "Fluent Python", O'Reilly, 2016 p. 636
256
+ Example 19-24 or 2022 p. 870 Example 22-28 and U{class
257
+ Property<https://docs.Python.org/3/howto/descriptor.html>}.
257
258
  '''
258
259
  _fget = method if _FOR_DOCS else self._fget # XXX force method.__doc__ to epydoc
259
260
  _PropertyBase.__init__(self, method, _fget, self._fset_error)
@@ -355,6 +356,61 @@ class property_RO(_PropertyBase):
355
356
  inst.__dict__.pop(uname)
356
357
 
357
358
 
359
+ class _property_RO___(_PropertyBase):
360
+ # No __doc__ on purpose
361
+
362
+ def __init__(self, method, doc=NN): # PYCHOK expected
363
+ '''New C{property_ROnce} or C{property_ROver}, holding a singleton value as
364
+ class attribute for all instances of that class and overwriting C{self},
365
+ the C{property_ROver} instance in the 1st invokation.
366
+
367
+ @see: L{property_RO} for further details.
368
+ '''
369
+ _PropertyBase.__init__(self, method, self._fget, self._fset_error, doc=doc)
370
+
371
+ def _fdel(self, unused): # PYCHOK no cover
372
+ '''Silently ignored, always.
373
+ '''
374
+ pass
375
+
376
+ def _update(self, *unused): # PYCHOK signature
377
+ '''(INTERNAL) No-op, ignore updates.
378
+ '''
379
+ pass
380
+
381
+
382
+ class property_ROnce(_property_RO___):
383
+ # No __doc__ on purpose
384
+
385
+ def _fget(self, inst):
386
+ '''Get the C{property} value, only I{once} and memoize/cache it.
387
+ '''
388
+ try:
389
+ v = self._val
390
+ except AttributeError:
391
+ v = self._val = self.method(inst)
392
+ return v
393
+
394
+
395
+ class property_ROver(_property_RO___):
396
+ # No __doc__ on purpose
397
+
398
+ def _fget(self, inst):
399
+ '''Get the C{property} value I{once} and overwrite C{self}, this C{property} instance.
400
+ '''
401
+ v = self.method(inst)
402
+ n = self.name
403
+ C = inst.__class__
404
+ for c in C.__mro__: # [:-1]
405
+ if getattr(c, n, None) is self:
406
+ setattr(c, n, v) # overwrite property_ROver
407
+ break
408
+ else:
409
+ n = _DOT_(C.__name__, n)
410
+ raise _AssertionError(_EQUALSPACED_(n, v))
411
+ return v
412
+
413
+
358
414
  class _NamedProperty(property):
359
415
  '''Class C{property} with retrievable name.
360
416
  '''
@@ -372,16 +428,18 @@ def property_doc_(doc):
372
428
 
373
429
  @example:
374
430
 
375
- >>> @property_doc_("documentation text.")
376
- >>> def name(self):
377
- >>> ...
431
+ >>>class Clas(object):
432
+ >>>
433
+ >>> @property_doc_("documentation text.")
434
+ >>> def name(self):
435
+ >>> ...
378
436
  >>>
379
- >>> @name.setter
380
- >>> def name(self, value):
381
- >>> ...
437
+ >>> @name.setter
438
+ >>> def name(self, value):
439
+ >>> ...
382
440
  '''
383
- # See Luciano Ramalho, "Fluent Python", O'Reilly, Example 7-23,
384
- # 2016 p. 212+, 2022 p. 331+, Example 9-22 and <https://
441
+ # See Luciano Ramalho, "Fluent Python", O'Reilly, 2016 p. 212+
442
+ # Example 7-23 or 2022 p. 331+ Example 9-22 and <https://
385
443
  # Python-3-Patterns-Idioms-Test.ReadTheDocs.io/en/latest/PythonDecorators.html>
386
444
 
387
445
  def _documented_property(method):
@@ -396,8 +454,8 @@ def property_doc_(doc):
396
454
  def _deprecated(call, kind, qual_d):
397
455
  '''(INTERNAL) Decorator for DEPRECATED functions, methods, etc.
398
456
 
399
- @see: Brett Slatkin, "Effective Python", page 105, 2nd ed,
400
- Addison-Wesley, 2019.
457
+ @see: Brett Slatkin, "Effective Python", 2019 page 105, 2nd
458
+ ed, Addison-Wesley.
401
459
  '''
402
460
  doc = _docof(call)
403
461
 
pygeodesy/rhumb/solve.py CHANGED
@@ -17,21 +17,21 @@ from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv,
17
17
  _PYGEODESY_RHUMBSOLVE_
18
18
  from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
19
19
  from pygeodesy.props import deprecated_method, Property, Property_RO
20
- from pygeodesy.solveBase import _SolveBase, _SolveLineBase
20
+ from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
21
21
  from pygeodesy.utily import _unrollon, _Wrap, wrap360
22
22
 
23
23
  __all__ = _ALL_LAZY.rhumb_solve
24
- __version__ = '24.06.04'
24
+ __version__ = '24.07.11'
25
25
 
26
26
 
27
- class _RhumbSolveBase(_SolveBase):
27
+ class _RhumbSolveBase(_SolveGDictBase):
28
28
  '''(INTERNAL) Base class for L{RhumbSolve} and L{RhumbLineSolve}.
29
29
  '''
30
30
  _Error = RhumbError
31
31
  _Names_Direct = _lat2_, _lon2_, _S12_
32
32
  _Names_Inverse = _azi12_, _s12_, _S12_
33
- _Solve_name = 'RhumbSolve'
34
- _Solve_path = _getenv(_PYGEODESY_RHUMBSOLVE_, _PYGEODESY_RHUMBSOLVE_)
33
+ _Xable_name = 'RhumbSolve'
34
+ _Xable_path = _getenv(_PYGEODESY_RHUMBSOLVE_, _PYGEODESY_RHUMBSOLVE_)
35
35
 
36
36
  @Property_RO
37
37
  def _cmdBasic(self):
@@ -46,7 +46,7 @@ class _RhumbSolveBase(_SolveBase):
46
46
  '''Get the U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
47
47
  executable (C{filename}).
48
48
  '''
49
- return self._Solve_path
49
+ return self._Xable_path
50
50
 
51
51
  @RhumbSolve.setter # PYCHOK setter!
52
52
  def RhumbSolve(self, path):
@@ -56,7 +56,7 @@ class _RhumbSolveBase(_SolveBase):
56
56
  @raise RhumbError: Invalid B{C{path}}, B{C{path}} doesn't exist or isn't
57
57
  the C{RhumbSolve} executable.
58
58
  '''
59
- self._setSolve(path)
59
+ self._setXable(path)
60
60
 
61
61
  @Property_RO
62
62
  def _s_option(self): # == not -E for GeodSolve
@@ -65,11 +65,11 @@ class _RhumbSolveBase(_SolveBase):
65
65
  def toStr(self, **prec_sep): # PYCHOK signature
66
66
  '''Return this C{RhumbSolve} as string.
67
67
 
68
- @kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=', '}
68
+ @kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
69
69
  for the C{float} C{prec}ision, number of decimal digits
70
70
  (0..9) and the C{sep}arator string to join. Trailing
71
- zero decimals are stripped for B{C{prec}} values of
72
- 1 and above, but kept for negative B{C{prec}} values.
71
+ zero decimals are stripped for B{C{prec}} values of 1
72
+ and above, but kept for negative B{C{prec}} values.
73
73
 
74
74
  @return: RhumbSolve items (C{str}).
75
75
  '''
@@ -173,8 +173,7 @@ class RhumbSolve(_RhumbSolveBase):
173
173
  return r
174
174
 
175
175
  def _GDictInverse(self, lat1, lon1, lat2, lon2, *unused, **floats): # PYCHOK signature
176
- '''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but
177
- I{without} C{_SALPs_CALPs_}.
176
+ '''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but I{without} C{_SALP_CALPs_}.
178
177
  '''
179
178
  i = _RhumbSolveBase._GDictInverse(self, lat1, lon1, lat2, lon2, **floats)
180
179
  a = _over(float(i.s12), self._mpd) # for .Inverse1
@@ -231,7 +230,7 @@ class RhumbSolve(_RhumbSolveBase):
231
230
  Line = DirectLine
232
231
 
233
232
 
234
- class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
233
+ class RhumbLineSolve(_RhumbSolveBase, _SolveGDictLineBase):
235
234
  '''Wrapper to invoke I{Karney}'s U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
236
235
  like a class, similar to L{pygeodesy.RhumbLine} and L{pygeodesy.RhumbLineAux}.
237
236
 
@@ -267,7 +266,7 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
267
266
  _xinstanceof(RhumbSolve, rhumb=rhumb)
268
267
  if (caps & Caps.LINE_OFF): # copy to avoid updates
269
268
  rhumb = rhumb.copy(deep=False, name=NN(_UNDER_, rhumb.name))
270
- _SolveLineBase.__init__(self, rhumb, lat1, lon1, caps, azi12=azi12, **name)
269
+ _SolveGDictLineBase.__init__(self, rhumb, lat1, lon1, caps, azi12=azi12, **name)
271
270
  try:
272
271
  self.RhumbSolve = rhumb.RhumbSolve # rhumb or copy of rhumb
273
272
  except RhumbError:
@@ -283,7 +282,7 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
283
282
  # azi12, a12, s12, S12}.
284
283
  # '''
285
284
  # s = a12 * self._mpd
286
- # a = self._GDictInvoke(self._cmdArc, True, self._Names_Direct, s)
285
+ # a = self._GDictInvoke(self._cmdArc, self._Names_Direct, s)
287
286
  # r = GDict(a12=a12, s12=s, **self._lla1)
288
287
  # r.updated(a)
289
288
  # return r
@@ -318,7 +317,7 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
318
317
  @return: A L{GDict} with 7 items C{lat1, lon1, lat2, lon2,
319
318
  azi12, s12, S12}.
320
319
  '''
321
- d = self._GDictInvoke(self._cmdDistance, True, self._Names_Direct, s12)
320
+ d = self._GDictInvoke(self._cmdDistance, self._Names_Direct, s12)
322
321
  r = GDict(s12=s12, **self._lla1) # a12=_over(s12, self._mpd)
323
322
  r.update(d)
324
323
  return r
@@ -326,16 +325,16 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
326
325
  def toStr(self, **prec_sep): # PYCHOK signature
327
326
  '''Return this C{RhumbLineSolve} as string.
328
327
 
329
- @kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=', '}
328
+ @kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
330
329
  for the C{float} C{prec}ision, number of decimal digits
331
330
  (0..9) and the C{sep}arator string to join. Trailing
332
- zero decimals are stripped for B{C{prec}} values of
333
- 1 and above, but kept for negative B{C{prec}} values.
331
+ zero decimals are stripped for B{C{prec}} values of 1
332
+ and above, but kept for negative B{C{prec}} values.
334
333
 
335
334
  @return: RhumbLineSolve items (C{str}).
336
335
  '''
337
- return _SolveLineBase._toStr(self, azi12=self.azi12, rhumb=self._solve,
338
- RhumbSolve=self.RhumbSolve, **prec_sep)
336
+ return _SolveGDictLineBase._toStr(self, azi12=self.azi12, rhumb=self._solve,
337
+ RhumbSolve=self.RhumbSolve, **prec_sep)
339
338
 
340
339
 
341
340
  class RhumbSolve7Tuple(Rhumb8Tuple):
@@ -396,7 +395,7 @@ if __name__ == '__main__':
396
395
  rS.verbose = '--verbose' in argv # or '-v' in argv
397
396
 
398
397
  if rS.RhumbSolve in (_PYGEODESY_RHUMBSOLVE_, None): # not set
399
- rS.RhumbSolve = '/opt/local/bin/RhumbSolve' # '/opt/local/Cellar/geographiclib/2.2/bin/RhumbSolve' # HomeBrew
398
+ rS.RhumbSolve = '/opt/local/bin/RhumbSolve' # '/opt/local/Cellar/geographiclib/2.3/bin/RhumbSolve' # HomeBrew
400
399
  printf('version: %s', rS.version)
401
400
 
402
401
  if len(argv) > 6: # 60 0 30 0 45 1e6