pygeodesy 24.5.24__py2.py3-none-any.whl → 24.6.9__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-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/METADATA +6 -5
- PyGeodesy-24.6.9.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +4 -4
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +4 -4
- pygeodesy/basics.py +39 -5
- pygeodesy/booleans.py +54 -67
- pygeodesy/cartesianBase.py +138 -147
- pygeodesy/constants.py +3 -3
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/ecef.py +67 -72
- pygeodesy/ellipsoidalBase.py +18 -56
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoidalNvector.py +7 -7
- pygeodesy/ellipsoids.py +6 -5
- pygeodesy/errors.py +20 -10
- pygeodesy/etm.py +16 -21
- pygeodesy/fmath.py +9 -20
- pygeodesy/formy.py +60 -74
- pygeodesy/frechet.py +13 -14
- pygeodesy/fsums.py +60 -26
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +3 -5
- pygeodesy/geodsolve.py +24 -26
- pygeodesy/geohash.py +27 -40
- pygeodesy/geoids.py +1 -1
- pygeodesy/hausdorff.py +17 -18
- pygeodesy/heights.py +17 -30
- pygeodesy/internals.py +15 -14
- pygeodesy/interns.py +3 -9
- pygeodesy/iters.py +2 -2
- pygeodesy/karney.py +8 -7
- pygeodesy/latlonBase.py +189 -176
- pygeodesy/lazily.py +92 -56
- pygeodesy/lcc.py +2 -2
- pygeodesy/ltp.py +93 -55
- pygeodesy/ltpTuples.py +304 -240
- pygeodesy/mgrs.py +51 -24
- pygeodesy/named.py +159 -136
- pygeodesy/namedTuples.py +43 -14
- pygeodesy/nvectorBase.py +20 -23
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +11 -11
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +20 -70
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +35 -32
- pygeodesy/sphericalBase.py +33 -31
- pygeodesy/sphericalTrigonometry.py +17 -17
- pygeodesy/streprs.py +6 -4
- pygeodesy/trf.py +11 -9
- pygeodesy/triaxials.py +71 -50
- pygeodesy/units.py +40 -65
- pygeodesy/unitsBase.py +2 -2
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +7 -6
- pygeodesy/utm.py +152 -156
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +102 -106
- pygeodesy/vector3d.py +34 -36
- pygeodesy/vector3dBase.py +12 -9
- pygeodesy/webmercator.py +43 -51
- PyGeodesy-24.5.24.dist-info/RECORD +0 -116
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/top_level.txt +0 -0
pygeodesy/mgrs.py
CHANGED
|
@@ -44,7 +44,7 @@ from pygeodesy.interns import NN, _0_, _A_, _AtoZnoIO_, _band_, _B_, \
|
|
|
44
44
|
_COMMASPACE_, _datum_, _easting_, _invalid_, \
|
|
45
45
|
_northing_, _SPACE_, _W_, _Y_, _Z_, _zone_
|
|
46
46
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _PYGEODESY_GEOCONVERT_
|
|
47
|
-
from pygeodesy.named import _NamedBase, _NamedTuple, _Pass
|
|
47
|
+
from pygeodesy.named import _name2__, _NamedBase, _NamedTuple, _Pass
|
|
48
48
|
from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple
|
|
49
49
|
from pygeodesy.props import deprecated_property_RO, property_RO, Property_RO
|
|
50
50
|
from pygeodesy.streprs import enstr2, _enstr2m3, Fmt, _resolution10, _xzipairs
|
|
@@ -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__ = '24.
|
|
58
|
+
__version__ = '24.06.04'
|
|
59
59
|
|
|
60
60
|
_AN_ = 'AN' # default south pole grid tile and band B
|
|
61
61
|
_AtoPx_ = _AtoZnoIO_.tillP
|
|
@@ -87,7 +87,7 @@ class Mgrs(_NamedBase):
|
|
|
87
87
|
_zone = 0 # longitudinal or polar zone (C{int}), 0..60
|
|
88
88
|
|
|
89
89
|
def __init__(self, zone=0, EN=NN, easting=0, northing=0, band=NN,
|
|
90
|
-
datum=_WGS84, resolution=0, name
|
|
90
|
+
datum=_WGS84, resolution=0, **name):
|
|
91
91
|
'''New L{Mgrs} Military grid reference.
|
|
92
92
|
|
|
93
93
|
@arg zone: The 6° I{longitudinal} zone (C{int}), 1..60 covering
|
|
@@ -104,7 +104,7 @@ class Mgrs(_NamedBase):
|
|
|
104
104
|
@kwarg datum: This reference's datum (L{Datum}, L{Ellipsoid},
|
|
105
105
|
L{Ellipsoid2} or L{a_f2Tuple}).
|
|
106
106
|
@kwarg resolution: Optional resolution (C{meter}), C{0} for default.
|
|
107
|
-
@kwarg name: Optional name (C{str}).
|
|
107
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
108
108
|
|
|
109
109
|
@raise MGRSError: Invalid B{C{zone}}, B{C{EN}}, B{C{easting}},
|
|
110
110
|
B{C{northing}}, B{C{band}} or B{C{resolution}}.
|
|
@@ -235,20 +235,18 @@ class Mgrs(_NamedBase):
|
|
|
235
235
|
toUps8(a, 0, datum=self.datum, Ups=None)
|
|
236
236
|
return int(u.northing / _100km) * _100km
|
|
237
237
|
|
|
238
|
-
def parse(self, strMGRS, name
|
|
238
|
+
def parse(self, strMGRS, **name):
|
|
239
239
|
'''Parse a string to a similar L{Mgrs} instance.
|
|
240
240
|
|
|
241
|
-
@arg strMGRS: The MGRS reference (C{str}),
|
|
242
|
-
|
|
243
|
-
@kwarg name: Optional instance name (C{str}),
|
|
244
|
-
overriding this name.
|
|
241
|
+
@arg strMGRS: The MGRS reference (C{str}), see function L{parseMGRS}.
|
|
242
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
|
|
245
243
|
|
|
246
244
|
@return: The similar instance (L{Mgrs}).
|
|
247
245
|
|
|
248
246
|
@raise MGRSError: Invalid B{C{strMGRS}}.
|
|
249
247
|
'''
|
|
250
248
|
return parseMGRS(strMGRS, datum=self.datum, Mgrs=self.classof,
|
|
251
|
-
|
|
249
|
+
name=self._name__(name))
|
|
252
250
|
|
|
253
251
|
@property
|
|
254
252
|
def resolution(self):
|
|
@@ -536,7 +534,7 @@ class _RE(object):
|
|
|
536
534
|
_RE = _RE() # PYCHOK singleton
|
|
537
535
|
|
|
538
536
|
|
|
539
|
-
def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, name
|
|
537
|
+
def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, **name):
|
|
540
538
|
'''Parse a string representing a MGRS grid reference,
|
|
541
539
|
consisting of C{"[zone]Band, EN, easting, northing"}.
|
|
542
540
|
|
|
@@ -544,7 +542,7 @@ def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, name=NN):
|
|
|
544
542
|
@kwarg datum: Optional datum to use (L{Datum}).
|
|
545
543
|
@kwarg Mgrs: Optional class to return the MGRS grid
|
|
546
544
|
reference (L{Mgrs}) or C{None}.
|
|
547
|
-
@kwarg name: Optional B{C{Mgrs}} name (C{str}).
|
|
545
|
+
@kwarg name: Optional B{C{Mgrs}} C{B{name}=NN} (C{str}).
|
|
548
546
|
|
|
549
547
|
@return: The MGRS grid reference as B{C{Mgrs}} or if
|
|
550
548
|
C{B{Mgrs} is None} as an L{Mgrs4Tuple}C{(zone,
|
|
@@ -582,29 +580,29 @@ def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, name=NN):
|
|
|
582
580
|
e, n, m = _enstr2m3(*m[2:])
|
|
583
581
|
|
|
584
582
|
if Mgrs is None:
|
|
585
|
-
r = Mgrs4Tuple(zB, EN, e, n, name
|
|
583
|
+
r = Mgrs4Tuple(zB, EN, e, n, **name)
|
|
586
584
|
_ = r.toMgrs(resolution=m) # validate
|
|
587
585
|
else:
|
|
588
|
-
r = Mgrs(zB, EN, e, n, datum=datum, resolution=m, name
|
|
586
|
+
r = Mgrs(zB, EN, e, n, datum=datum, resolution=m, **name)
|
|
589
587
|
return r
|
|
590
588
|
|
|
591
589
|
return _parseX(_MGRS, strMGRS, datum, Mgrs, name,
|
|
592
590
|
strMGRS=strMGRS, Error=MGRSError)
|
|
593
591
|
|
|
594
592
|
|
|
595
|
-
def toMgrs(utmups, Mgrs=Mgrs,
|
|
593
|
+
def toMgrs(utmups, Mgrs=Mgrs, **name_Mgrs_kwds):
|
|
596
594
|
'''Convert a UTM or UPS coordinate to an MGRS grid reference.
|
|
597
595
|
|
|
598
596
|
@arg utmups: A UTM or UPS coordinate (L{Utm}, L{Etm} or L{Ups}).
|
|
599
597
|
@kwarg Mgrs: Optional class to return the MGRS grid reference
|
|
600
598
|
(L{Mgrs}) or C{None}.
|
|
601
|
-
@kwarg
|
|
602
|
-
|
|
603
|
-
|
|
599
|
+
@kwarg name_Mgrs_kwds: Optional C{B{name}=NN} (C{str}) and
|
|
600
|
+
optional, additional B{C{Mgrs}} keyword arguments,
|
|
601
|
+
ignored if C{B{Mgrs} is None}.
|
|
604
602
|
|
|
605
|
-
@return: The MGRS grid reference as B{C{Mgrs}} or if
|
|
606
|
-
|
|
607
|
-
|
|
603
|
+
@return: The MGRS grid reference as B{C{Mgrs}} or if C{B{Mgrs}
|
|
604
|
+
is None} as an L{Mgrs6Tuple}C{(zone, EN, easting,
|
|
605
|
+
northing, band, datum)}.
|
|
608
606
|
|
|
609
607
|
@raise MGRSError: Invalid B{C{utmups}}.
|
|
610
608
|
|
|
@@ -634,12 +632,14 @@ def toMgrs(utmups, Mgrs=Mgrs, name=NN, **Mgrs_kwds):
|
|
|
634
632
|
except (IndexError, TypeError, ValueError) as x:
|
|
635
633
|
raise MGRSError(B=B, E=E, N=N, utmups=utmups, cause=x)
|
|
636
634
|
|
|
635
|
+
t, kwds = _name2__(name_Mgrs_kwds, _or_nameof=utmups)
|
|
637
636
|
if Mgrs is None:
|
|
638
|
-
r = Mgrs4Tuple(Fmt.zone(z), EN, e, n
|
|
637
|
+
r = Mgrs4Tuple(Fmt.zone(z), EN, e, n, name=t) \
|
|
638
|
+
.to6Tuple(B, utmups.datum)
|
|
639
639
|
else:
|
|
640
|
-
kwds = _xkwds(
|
|
640
|
+
kwds = _xkwds(kwds, band=B, datum=utmups.datum, name=t)
|
|
641
641
|
r = Mgrs(z, EN, e, n, **kwds)
|
|
642
|
-
return
|
|
642
|
+
return r
|
|
643
643
|
|
|
644
644
|
|
|
645
645
|
def _um100km2(m):
|
|
@@ -699,6 +699,33 @@ if __name__ == '__main__':
|
|
|
699
699
|
p = e * 100.0 / n
|
|
700
700
|
printf('%6s: %s errors (%.2f%%)', n, (e if e else 'no'), p)
|
|
701
701
|
|
|
702
|
+
# % python3 -m pygeodesy.mgrs
|
|
703
|
+
# using: /opt/local/bin/GeoConvert -m ...
|
|
704
|
+
# 0: lat -90 ... OK
|
|
705
|
+
# 361: lat -89 ... OK
|
|
706
|
+
# 722: lat -88 ... OK
|
|
707
|
+
# 1083: lat -87 ... OK
|
|
708
|
+
# 1444: lat -86 ... OK
|
|
709
|
+
# 1805: lat -85 ... OK
|
|
710
|
+
# 2166: lat -84 ... OK
|
|
711
|
+
# 2527: lat -83 ... OK
|
|
712
|
+
# 2888: lat -82 ... OK
|
|
713
|
+
# 3249: lat -81 ... OK
|
|
714
|
+
# 3610: lat -80 ... OK
|
|
715
|
+
# ...
|
|
716
|
+
# 61370: lat 80 ... OK
|
|
717
|
+
# 61731: lat 81 ... OK
|
|
718
|
+
# 62092: lat 82 ... OK
|
|
719
|
+
# 62453: lat 83 ... OK
|
|
720
|
+
# 62814: lat 84 ... OK
|
|
721
|
+
# 63175: lat 85 ... OK
|
|
722
|
+
# 63536: lat 86 ... OK
|
|
723
|
+
# 63897: lat 87 ... OK
|
|
724
|
+
# 64258: lat 88 ... OK
|
|
725
|
+
# 64619: lat 89 ... OK
|
|
726
|
+
# 64980: lat 90 ... OK
|
|
727
|
+
# 65341: no errors (0.00%)
|
|
728
|
+
|
|
702
729
|
# **) MIT License
|
|
703
730
|
#
|
|
704
731
|
# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
pygeodesy/named.py
CHANGED
|
@@ -13,27 +13,28 @@ standard Python C{namedtuple}s.
|
|
|
13
13
|
@see: Module L{pygeodesy.namedTuples} for (most of) the C{Named-Tuples}.
|
|
14
14
|
'''
|
|
15
15
|
|
|
16
|
-
from pygeodesy.basics import
|
|
17
|
-
|
|
16
|
+
from pygeodesy.basics import isidentifier, iskeyword, isstr, itemsorted, len2, \
|
|
17
|
+
_xcopy, _xdup, _xinstanceof, _xsubclassof, _zip
|
|
18
18
|
from pygeodesy.errors import _AssertionError, _AttributeError, _incompatible, \
|
|
19
|
-
_IndexError,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
_xkwds_item2, _xkwds_pop2
|
|
19
|
+
_IndexError, _KeyError, LenError, _NameError, \
|
|
20
|
+
_NotImplementedError, _TypeError, _TypesError, \
|
|
21
|
+
_UnexpectedError, UnitError, _ValueError, \
|
|
22
|
+
_xattr, _xkwds, _xkwds_item2, _xkwds_pop2
|
|
23
23
|
from pygeodesy.internals import _caller3, _dunder_nameof, _isPyPy, _sizeof, _under
|
|
24
24
|
from pygeodesy.interns import MISSING, NN, _AT_, _COLON_, _COLONSPACE_, _COMMA_, \
|
|
25
25
|
_COMMASPACE_, _doesn_t_exist_, _DOT_, _DUNDER_, \
|
|
26
26
|
_dunder_name_, _EQUAL_, _exists_, _immutable_, _name_, \
|
|
27
27
|
_NL_, _NN_, _no_, _other_, _s_, _SPACE_, _std_, \
|
|
28
|
-
_UNDER_,
|
|
28
|
+
_UNDER_, _vs_
|
|
29
29
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
30
30
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_method, _hasProperty, \
|
|
31
31
|
_update_all, property_doc_, Property_RO, property_RO, \
|
|
32
32
|
_update_attrs
|
|
33
33
|
from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
|
|
34
|
+
# from pygeodesy.units import _toUnit # _MODS
|
|
34
35
|
|
|
35
36
|
__all__ = _ALL_LAZY.named
|
|
36
|
-
__version__ = '24.
|
|
37
|
+
__version__ = '24.06.10'
|
|
37
38
|
|
|
38
39
|
_COMMANL_ = _COMMA_ + _NL_
|
|
39
40
|
_COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
|
|
@@ -50,69 +51,6 @@ _Units_ = '_Units_'
|
|
|
50
51
|
_UP = 2
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
def _xjoined_(prefix, name=NN, enquote=True, **name__of_name):
|
|
54
|
-
'''(INTERNAL) Join C{prefix} and non-empty C{name}.
|
|
55
|
-
'''
|
|
56
|
-
if name__of_name:
|
|
57
|
-
name = _name__(name, **name__of_name)
|
|
58
|
-
if name and prefix:
|
|
59
|
-
if enquote:
|
|
60
|
-
name = repr(name)
|
|
61
|
-
t = _SPACE_(prefix, name)
|
|
62
|
-
else:
|
|
63
|
-
t = prefix or name
|
|
64
|
-
return t
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def _xnamed(inst, name=NN, force=False, **name__of_name):
|
|
68
|
-
'''(INTERNAL) Set the instance' C{.name = B{name}}.
|
|
69
|
-
|
|
70
|
-
@arg inst: The instance (C{_Named}).
|
|
71
|
-
@kwarg name: The name (C{str}).
|
|
72
|
-
@kwarg force: If C{True}, force rename (C{bool}).
|
|
73
|
-
|
|
74
|
-
@return: The B{C{inst}}, renamed if B{C{force}}d
|
|
75
|
-
or if not named before.
|
|
76
|
-
'''
|
|
77
|
-
if name__of_name:
|
|
78
|
-
name = _name__(name, **name__of_name)
|
|
79
|
-
if name and isinstance(inst, _Named):
|
|
80
|
-
if not inst.name:
|
|
81
|
-
inst.name = name
|
|
82
|
-
elif force:
|
|
83
|
-
inst.rename(name)
|
|
84
|
-
return inst
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def _xother3(inst, other, name=_other_, up=1, **name_other):
|
|
88
|
-
'''(INTERNAL) Get C{name} and C{up} for a named C{other}.
|
|
89
|
-
'''
|
|
90
|
-
if name_other: # and other is None
|
|
91
|
-
name, other = _xkwds_item2(name_other)
|
|
92
|
-
elif other and len(other) == 1:
|
|
93
|
-
name, other = _name__(name), other[0]
|
|
94
|
-
else:
|
|
95
|
-
raise _AssertionError(name, other, txt=classname(inst, prefixed=True))
|
|
96
|
-
return other, name, up
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def _xotherError(inst, other, name=_other_, up=1):
|
|
100
|
-
'''(INTERNAL) Return a C{_TypeError} for an incompatible, named C{other}.
|
|
101
|
-
'''
|
|
102
|
-
n = _callname(name, classname(inst, prefixed=True), inst.name, up=up + 1)
|
|
103
|
-
return _TypeError(name, other, txt=_incompatible(n))
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def _xvalid(name, underOK=False):
|
|
107
|
-
'''(INTERNAL) Check valid attribute name C{name}.
|
|
108
|
-
'''
|
|
109
|
-
return bool(name and isstr(name)
|
|
110
|
-
and name != _name_
|
|
111
|
-
and (underOK or not name.startswith(_UNDER_))
|
|
112
|
-
and (not iskeyword(name))
|
|
113
|
-
and isidentifier(name))
|
|
114
|
-
|
|
115
|
-
|
|
116
54
|
class ADict(dict):
|
|
117
55
|
'''A C{dict} with both key I{and} attribute access to
|
|
118
56
|
the C{dict} items.
|
|
@@ -170,7 +108,6 @@ class ADict(dict):
|
|
|
170
108
|
C{floats} formatted by function L{pygeodesy.fstr}.
|
|
171
109
|
'''
|
|
172
110
|
n = _xattr(self, name=NN) or self.__class__.__name__
|
|
173
|
-
print(1, n)
|
|
174
111
|
return Fmt.PAREN(n, self._toT(_EQUAL_, **prec_fmt))
|
|
175
112
|
|
|
176
113
|
def toStr(self, **prec_fmt):
|
|
@@ -312,7 +249,7 @@ class _Named(object):
|
|
|
312
249
|
|
|
313
250
|
fmt, props, kwds = _fmt_props_kwds(**fmt_props_kwds)
|
|
314
251
|
|
|
315
|
-
t = () if name is None else (Fmt.EQUAL(name=repr(
|
|
252
|
+
t = () if name is None else (Fmt.EQUAL(name=repr(self._name__(name))),)
|
|
316
253
|
if attrs:
|
|
317
254
|
t += pairs(((a, getattr(self, a)) for a in attrs),
|
|
318
255
|
prec=prec, ints=True, fmt=fmt)
|
|
@@ -373,6 +310,11 @@ class _Named(object):
|
|
|
373
310
|
'''
|
|
374
311
|
return _name__(name, _or_nameof=self) # nameof(self)
|
|
375
312
|
|
|
313
|
+
def _name1__(self, kwds):
|
|
314
|
+
'''(INTERNAL) Resolve and set the C{B{name}=NN}.
|
|
315
|
+
'''
|
|
316
|
+
return _name1__(kwds, _or_nameof=self.name) if self.name else kwds
|
|
317
|
+
|
|
376
318
|
@Property_RO
|
|
377
319
|
def named(self):
|
|
378
320
|
'''Get the name I{or} class name or C{""} (C{str}).
|
|
@@ -486,11 +428,8 @@ class _Named(object):
|
|
|
486
428
|
|
|
487
429
|
@raise TypeError: Not C{isinstance(B{inst}, _Named)}.
|
|
488
430
|
'''
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
_ = inst.rename(self.name)
|
|
493
|
-
return inst
|
|
431
|
+
_xinstanceof(_Named, inst=inst) # assert
|
|
432
|
+
return inst.renamed(self.name)
|
|
494
433
|
|
|
495
434
|
_Named_Property_ROs = _allPropertiesOf_n(5, _Named, Property_RO) # PYCHOK once
|
|
496
435
|
|
|
@@ -780,12 +719,14 @@ class _NamedEnum(_NamedDict):
|
|
|
780
719
|
if not (n and isstr(n) and isidentifier(n)):
|
|
781
720
|
raise ValueError()
|
|
782
721
|
except (AttributeError, ValueError, TypeError) as x:
|
|
783
|
-
|
|
722
|
+
n = _DOT_(_item_, _name_)
|
|
723
|
+
raise _NameError(n, item, cause=x)
|
|
784
724
|
if n in self:
|
|
785
725
|
t = _SPACE_(_item_, self._DOT_(n), _exists_)
|
|
786
726
|
raise _NameError(t, txt=repr(item))
|
|
787
|
-
if not isinstance(item, self._item_Classes):
|
|
788
|
-
|
|
727
|
+
if not isinstance(item, self._item_Classes): # _xinstanceof
|
|
728
|
+
n = self._DOT_(n)
|
|
729
|
+
raise _TypesError(n, item, *self._item_Classes)
|
|
789
730
|
self[n] = item
|
|
790
731
|
return n
|
|
791
732
|
|
|
@@ -907,7 +848,7 @@ class _NamedEnumItem(_NamedBase):
|
|
|
907
848
|
'''
|
|
908
849
|
name = _name__(name) or _NN_
|
|
909
850
|
if self._enum:
|
|
910
|
-
raise _NameError(name, self, txt=_registered_) #
|
|
851
|
+
raise _NameError(name, self, txt=_registered_) # _TypeError
|
|
911
852
|
if name:
|
|
912
853
|
self._name = name
|
|
913
854
|
|
|
@@ -934,8 +875,8 @@ class _NamedEnumItem(_NamedBase):
|
|
|
934
875
|
enum = self._enum
|
|
935
876
|
if enum and self.name and self.name in enum:
|
|
936
877
|
item = enum.unregister(self.name)
|
|
937
|
-
if item is not self:
|
|
938
|
-
t = _SPACE_(repr(item), _vs_, repr(self))
|
|
878
|
+
if item is not self: # PYCHOK no cover
|
|
879
|
+
t = _SPACE_(repr(item), _vs_, repr(self))
|
|
939
880
|
raise _AssertionError(t)
|
|
940
881
|
|
|
941
882
|
|
|
@@ -987,7 +928,11 @@ class _NamedTuple(tuple, _Named):
|
|
|
987
928
|
raise LenError(self.__class__, args=n, _Names_=N)
|
|
988
929
|
|
|
989
930
|
if iteration_name:
|
|
990
|
-
|
|
931
|
+
i, name = _xkwds_pop2(iteration_name, iteration=None)
|
|
932
|
+
if i is not None:
|
|
933
|
+
self._iteration = i
|
|
934
|
+
if name:
|
|
935
|
+
self.name = name
|
|
991
936
|
return self
|
|
992
937
|
|
|
993
938
|
def __delattr__(self, name):
|
|
@@ -996,7 +941,8 @@ class _NamedTuple(tuple, _Named):
|
|
|
996
941
|
@note: Items can not be deleted.
|
|
997
942
|
'''
|
|
998
943
|
if name in self._Names_:
|
|
999
|
-
|
|
944
|
+
t = _SPACE_(_del_, self._DOT_(name))
|
|
945
|
+
raise _TypeError(t, txt=_immutable_)
|
|
1000
946
|
elif name in (_name_, _name):
|
|
1001
947
|
_Named.__setattr__(self, name, NN) # XXX _Named.name.fset(self, NN)
|
|
1002
948
|
else:
|
|
@@ -1007,10 +953,10 @@ class _NamedTuple(tuple, _Named):
|
|
|
1007
953
|
'''
|
|
1008
954
|
try:
|
|
1009
955
|
return tuple.__getitem__(self, self._Names_.index(name))
|
|
1010
|
-
except IndexError:
|
|
1011
|
-
raise _IndexError(
|
|
956
|
+
except IndexError as x:
|
|
957
|
+
raise _IndexError(self._DOT_(name), cause=x)
|
|
1012
958
|
except ValueError: # e.g. _iteration
|
|
1013
|
-
return tuple.
|
|
959
|
+
return tuple.__getattr__(self, name) # __getattribute__
|
|
1014
960
|
|
|
1015
961
|
# def __getitem__(self, index): # index, slice, etc.
|
|
1016
962
|
# '''Get the item(s) at an B{C{index}} or slice.
|
|
@@ -1029,7 +975,8 @@ class _NamedTuple(tuple, _Named):
|
|
|
1029
975
|
'''Set attribute or item B{C{name}} to B{C{value}}.
|
|
1030
976
|
'''
|
|
1031
977
|
if name in self._Names_:
|
|
1032
|
-
|
|
978
|
+
t = Fmt.EQUALSPACED(self._DOT_(name), repr(value))
|
|
979
|
+
raise _TypeError(t, txt=_immutable_)
|
|
1033
980
|
elif name in (_name_, _name):
|
|
1034
981
|
_Named.__setattr__(self, name, value) # XXX _Named.name.fset(self, value)
|
|
1035
982
|
else: # e.g. _iteration
|
|
@@ -1040,6 +987,11 @@ class _NamedTuple(tuple, _Named):
|
|
|
1040
987
|
'''
|
|
1041
988
|
return self.toStr()
|
|
1042
989
|
|
|
990
|
+
def _DOT_(self, *names):
|
|
991
|
+
'''(INTERNAL) Period-join C{self.classname} and C{names}.
|
|
992
|
+
'''
|
|
993
|
+
return _DOT_(self.classname, *names)
|
|
994
|
+
|
|
1043
995
|
def dup(self, name=NN, **items):
|
|
1044
996
|
'''Duplicate this tuple replacing one or more items.
|
|
1045
997
|
|
|
@@ -1050,15 +1002,18 @@ class _NamedTuple(tuple, _Named):
|
|
|
1050
1002
|
|
|
1051
1003
|
@raise NameError: Some B{C{items}} invalid.
|
|
1052
1004
|
'''
|
|
1053
|
-
|
|
1005
|
+
t = list(self)
|
|
1006
|
+
U = self._Units_
|
|
1054
1007
|
if items:
|
|
1055
|
-
_ix =
|
|
1008
|
+
_ix = self._Names_.index
|
|
1009
|
+
_2U = _MODS.units._toUnit
|
|
1056
1010
|
try:
|
|
1057
1011
|
for n, v in items.items():
|
|
1058
|
-
|
|
1012
|
+
i = _ix(n)
|
|
1013
|
+
t[i] = _2U(U[i], v, name=n)
|
|
1059
1014
|
except ValueError: # bad item name
|
|
1060
|
-
raise _NameError(_DOT_(
|
|
1061
|
-
return self.classof(*
|
|
1015
|
+
raise _NameError(self._DOT_(n), v, this=self)
|
|
1016
|
+
return self.classof(*t).reUnit(*U, name=name)
|
|
1062
1017
|
|
|
1063
1018
|
def items(self):
|
|
1064
1019
|
'''Yield the items, each as a C{(name, value)} pair (C{2-tuple}).
|
|
@@ -1070,13 +1025,23 @@ class _NamedTuple(tuple, _Named):
|
|
|
1070
1025
|
|
|
1071
1026
|
iteritems = items
|
|
1072
1027
|
|
|
1073
|
-
def
|
|
1074
|
-
'''
|
|
1028
|
+
def reUnit(self, *Units, **name):
|
|
1029
|
+
'''Replace some of this C{Named-Tuple}'s C{Units}.
|
|
1030
|
+
|
|
1031
|
+
@arg Units: One or more C{Unit} classes, all positional.
|
|
1032
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1033
|
+
|
|
1034
|
+
@return: This instance with updated C{Units}.
|
|
1035
|
+
|
|
1036
|
+
@note: This C{Named-Tuple}'s values are I{not updated}.
|
|
1075
1037
|
'''
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
if
|
|
1079
|
-
|
|
1038
|
+
U = self._Units_
|
|
1039
|
+
n = min(len(U), len(Units))
|
|
1040
|
+
if n:
|
|
1041
|
+
R = Units + U[n:]
|
|
1042
|
+
if R != U:
|
|
1043
|
+
self._Units_ = R
|
|
1044
|
+
return self.renamed(name) if name else self
|
|
1080
1045
|
|
|
1081
1046
|
def toRepr(self, prec=6, sep=_COMMASPACE_, fmt=Fmt.F, **unused): # PYCHOK signature
|
|
1082
1047
|
'''Return this C{Named-Tuple} items as C{name=value} string(s).
|
|
@@ -1107,37 +1072,34 @@ class _NamedTuple(tuple, _Named):
|
|
|
1107
1072
|
'''
|
|
1108
1073
|
return Fmt.PAREN(sep.join(reprs(self, prec=prec, fmt=fmt)))
|
|
1109
1074
|
|
|
1110
|
-
def toUnits(self, Error=UnitError): # overloaded in .frechet, .hausdorff
|
|
1075
|
+
def toUnits(self, Error=UnitError, **name): # overloaded in .frechet, .hausdorff
|
|
1111
1076
|
'''Return a copy of this C{Named-Tuple} with each item value wrapped
|
|
1112
1077
|
as an instance of its L{units} class.
|
|
1113
1078
|
|
|
1114
1079
|
@kwarg Error: Error to raise for L{units} issues (C{UnitError}).
|
|
1080
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1115
1081
|
|
|
1116
1082
|
@return: A duplicate of this C{Named-Tuple} (C{C{Named-Tuple}}).
|
|
1117
1083
|
|
|
1118
1084
|
@raise Error: Invalid C{Named-Tuple} item or L{units} class.
|
|
1119
1085
|
'''
|
|
1120
|
-
t = (v for _, v in self.units(Error=Error))
|
|
1121
|
-
return self.classof(*
|
|
1086
|
+
t = tuple(v for _, v in self.units(Error=Error))
|
|
1087
|
+
return self.classof(*t).reUnit(*self._Units_, **name)
|
|
1122
1088
|
|
|
1123
|
-
def units(self, Error
|
|
1124
|
-
'''Yield the items, each as a C{(name, value})
|
|
1125
|
-
|
|
1089
|
+
def units(self, **Error):
|
|
1090
|
+
'''Yield the items, each as a C{2-tuple (name, value}) with the
|
|
1091
|
+
value wrapped as an instance of its L{units} class.
|
|
1126
1092
|
|
|
1127
|
-
@kwarg Error: Error to raise for
|
|
1093
|
+
@kwarg Error: Optional C{B{Error}=UnitError} to raise for
|
|
1094
|
+
L{units} issues.
|
|
1128
1095
|
|
|
1129
1096
|
@raise Error: Invalid C{Named-Tuple} item or L{units} class.
|
|
1130
1097
|
|
|
1131
1098
|
@see: Method C{.items}.
|
|
1132
1099
|
'''
|
|
1100
|
+
_2U = _MODS.units._toUnit
|
|
1133
1101
|
for n, v, U in _zip(self._Names_, self, self._Units_): # strict=True
|
|
1134
|
-
|
|
1135
|
-
or (isclass(U) and
|
|
1136
|
-
isinstance(v, U) and
|
|
1137
|
-
hasattr(v, _name_) and
|
|
1138
|
-
v.name == n)): # PYCHOK indent
|
|
1139
|
-
v = U(v, name=n, Error=Error)
|
|
1140
|
-
yield n, v
|
|
1102
|
+
yield n, _2U(U, v, name=n, **Error)
|
|
1141
1103
|
|
|
1142
1104
|
iterunits = units
|
|
1143
1105
|
|
|
@@ -1147,35 +1109,35 @@ class _NamedTuple(tuple, _Named):
|
|
|
1147
1109
|
'''
|
|
1148
1110
|
ns = self._Names_
|
|
1149
1111
|
if not (isinstance(ns, tuple) and len(ns) > 1): # XXX > 0
|
|
1150
|
-
raise _TypeError(_DOT_(
|
|
1112
|
+
raise _TypeError(self._DOT_(_Names_), ns)
|
|
1151
1113
|
for i, n in enumerate(ns):
|
|
1152
1114
|
if not _xvalid(n, underOK=underOK):
|
|
1153
1115
|
t = Fmt.SQUARE(_Names_=i) # PYCHOK no cover
|
|
1154
|
-
raise _ValueError(_DOT_(
|
|
1116
|
+
raise _ValueError(self._DOT_(t), n)
|
|
1155
1117
|
|
|
1156
1118
|
us = self._Units_
|
|
1157
1119
|
if not isinstance(us, tuple):
|
|
1158
|
-
raise _TypeError(_DOT_(
|
|
1120
|
+
raise _TypeError(self._DOT_(_Units_), us)
|
|
1159
1121
|
if len(us) != len(ns):
|
|
1160
1122
|
raise LenError(self.__class__, _Units_=len(us), _Names_=len(ns))
|
|
1161
1123
|
for i, u in enumerate(us):
|
|
1162
1124
|
if not (u is None or callable(u)):
|
|
1163
1125
|
t = Fmt.SQUARE(_Units_=i) # PYCHOK no cover
|
|
1164
|
-
raise _TypeError(_DOT_(
|
|
1126
|
+
raise _TypeError(self._DOT_(t), u)
|
|
1165
1127
|
|
|
1166
1128
|
self.__class__._validated = True
|
|
1167
1129
|
|
|
1168
1130
|
def _xtend(self, xTuple, *items, **name):
|
|
1169
1131
|
'''(INTERNAL) Extend this C{Named-Tuple} with C{items} to an other B{C{xTuple}}.
|
|
1170
1132
|
'''
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1133
|
+
_xsubclassof(_NamedTuple, xTuple=xTuple)
|
|
1134
|
+
if len(xTuple._Names_) != (len(self._Names_) + len(items)) or \
|
|
1135
|
+
xTuple._Names_[:len(self)] != self._Names_: # PYCHOK no cover
|
|
1136
|
+
c = NN(self.classname, repr(self._Names_))
|
|
1137
|
+
x = NN(xTuple.__name__, repr(xTuple._Names_))
|
|
1138
|
+
raise TypeError(_SPACE_(c, _vs_, x))
|
|
1139
|
+
t = self + items
|
|
1140
|
+
return xTuple(t, name=self._name__(name)) # .reUnit(*self._Units_)
|
|
1179
1141
|
|
|
1180
1142
|
|
|
1181
1143
|
def callername(up=1, dflt=NN, source=False, underOK=False):
|
|
@@ -1295,18 +1257,16 @@ def _name__(name=NN, **kwds):
|
|
|
1295
1257
|
if name or kwds:
|
|
1296
1258
|
name, kwds = _name2__(name, **kwds)
|
|
1297
1259
|
if kwds: # "unexpected keyword arguments ..."
|
|
1298
|
-
|
|
1299
|
-
raise m._UnexpectedError(**kwds)
|
|
1260
|
+
raise _UnexpectedError(**kwds)
|
|
1300
1261
|
return name if name or name is None else NN
|
|
1301
1262
|
|
|
1302
1263
|
|
|
1303
|
-
def _name1__(kwds_name,
|
|
1264
|
+
def _name1__(kwds_name, **name__or_nameof):
|
|
1304
1265
|
'''(INTERNAL) Resolve and set the C{B{name}=NN}.
|
|
1305
1266
|
'''
|
|
1306
|
-
if kwds_name:
|
|
1307
|
-
n, kwds_name = _name2__(kwds_name,
|
|
1308
|
-
|
|
1309
|
-
kwds_name.update(name=n)
|
|
1267
|
+
if kwds_name or name__or_nameof:
|
|
1268
|
+
n, kwds_name = _name2__(kwds_name, **name__or_nameof)
|
|
1269
|
+
kwds_name.update(name=n)
|
|
1310
1270
|
return kwds_name
|
|
1311
1271
|
|
|
1312
1272
|
|
|
@@ -1320,11 +1280,11 @@ def _name2__(name=NN, name__=None, _or_nameof=None, **kwds):
|
|
|
1320
1280
|
else:
|
|
1321
1281
|
n = str(name)
|
|
1322
1282
|
elif name__ is not None:
|
|
1323
|
-
n =
|
|
1283
|
+
n = _dunder_nameof(name__, NN)
|
|
1324
1284
|
else:
|
|
1325
1285
|
n = name if name is None else NN
|
|
1326
1286
|
if _or_nameof is not None and not n:
|
|
1327
|
-
n =
|
|
1287
|
+
n = _xattr(_or_nameof, name=NN) # nameof
|
|
1328
1288
|
return n, kwds # (str or None or {}), dict
|
|
1329
1289
|
|
|
1330
1290
|
|
|
@@ -1406,6 +1366,69 @@ def _Pass(arg, **unused): # PYCHOK no cover
|
|
|
1406
1366
|
return arg
|
|
1407
1367
|
|
|
1408
1368
|
|
|
1369
|
+
def _xjoined_(prefix, name=NN, enquote=True, **name__or_nameof):
|
|
1370
|
+
'''(INTERNAL) Join C{prefix} and non-empty C{name}.
|
|
1371
|
+
'''
|
|
1372
|
+
if name__or_nameof:
|
|
1373
|
+
name = _name__(name, **name__or_nameof)
|
|
1374
|
+
if name and prefix:
|
|
1375
|
+
if enquote:
|
|
1376
|
+
name = repr(name)
|
|
1377
|
+
t = _SPACE_(prefix, name)
|
|
1378
|
+
else:
|
|
1379
|
+
t = prefix or name
|
|
1380
|
+
return t
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
def _xnamed(inst, name=NN, force=False, **name__or_nameof):
|
|
1384
|
+
'''(INTERNAL) Set the instance' C{.name = B{name}}.
|
|
1385
|
+
|
|
1386
|
+
@arg inst: The instance (C{_Named}).
|
|
1387
|
+
@kwarg name: The name (C{str}).
|
|
1388
|
+
@kwarg force: If C{True}, force rename (C{bool}).
|
|
1389
|
+
|
|
1390
|
+
@return: The B{C{inst}}, renamed if B{C{force}}d
|
|
1391
|
+
or if not named before.
|
|
1392
|
+
'''
|
|
1393
|
+
if name__or_nameof:
|
|
1394
|
+
name = _name__(name, **name__or_nameof)
|
|
1395
|
+
if name and isinstance(inst, _Named):
|
|
1396
|
+
if not inst.name:
|
|
1397
|
+
inst.name = name
|
|
1398
|
+
elif force:
|
|
1399
|
+
inst.rename(name)
|
|
1400
|
+
return inst
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
def _xother3(inst, other, name=_other_, up=1, **name_other):
|
|
1404
|
+
'''(INTERNAL) Get C{name} and C{up} for a named C{other}.
|
|
1405
|
+
'''
|
|
1406
|
+
if name_other: # and other is None
|
|
1407
|
+
name, other = _xkwds_item2(name_other)
|
|
1408
|
+
elif other and len(other) == 1:
|
|
1409
|
+
name, other = _name__(name), other[0]
|
|
1410
|
+
else:
|
|
1411
|
+
raise _AssertionError(name, other, txt=classname(inst, prefixed=True))
|
|
1412
|
+
return other, name, up
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
def _xotherError(inst, other, name=_other_, up=1):
|
|
1416
|
+
'''(INTERNAL) Return a C{_TypeError} for an incompatible, named C{other}.
|
|
1417
|
+
'''
|
|
1418
|
+
n = _callname(name, classname(inst, prefixed=True), inst.name, up=up + 1)
|
|
1419
|
+
return _TypeError(name, other, txt=_incompatible(n))
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
def _xvalid(name, underOK=False):
|
|
1423
|
+
'''(INTERNAL) Check valid attribute name C{name}.
|
|
1424
|
+
'''
|
|
1425
|
+
return bool(name and isstr(name)
|
|
1426
|
+
and name != _name_
|
|
1427
|
+
and (underOK or not name.startswith(_UNDER_))
|
|
1428
|
+
and (not iskeyword(name))
|
|
1429
|
+
and isidentifier(name))
|
|
1430
|
+
|
|
1431
|
+
|
|
1409
1432
|
__all__ += _ALL_DOCS(_Named,
|
|
1410
1433
|
_NamedBase, # _NamedDict,
|
|
1411
1434
|
_NamedEnum, _NamedEnumItem,
|