From cbe2b9eaa9c8d5614c1170a7da508221361d6aef Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 10 Oct 2024 12:23:44 -0400 Subject: [PATCH 01/69] wxGUI: Fixed E722 in frame.py (#4440) --- .flake8 | 3 --- gui/wxpython/lmgr/frame.py | 12 ++++++------ gui/wxpython/lmgr/layertree.py | 11 ++++------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/.flake8 b/.flake8 index 5126c042439..313241f2d9d 100644 --- a/.flake8 +++ b/.flake8 @@ -27,9 +27,6 @@ per-file-ignores = gui/scripts/d.wms.py: E501 gui/wxpython/image2target/*: F841, E722 gui/wxpython/image2target/g.gui.image2target.py: E501, F841 - gui/wxpython/lmgr/frame.py: E722 - # layertree still includes some formatting issues (it is ignored by Black) - gui/wxpython/lmgr/layertree.py: E722 gui/wxpython/modules/*: F841, E722 gui/wxpython/nviz/*: F841, E266, E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 diff --git a/gui/wxpython/lmgr/frame.py b/gui/wxpython/lmgr/frame.py index 80f373239f8..2413d3b7c4a 100644 --- a/gui/wxpython/lmgr/frame.py +++ b/gui/wxpython/lmgr/frame.py @@ -271,7 +271,7 @@ def show_menu_errors(messages): y = client_disp[1] self.SetPosition((x, y)) self.SetSize((w, h)) - except: + except (ValueError, IndexError): pass else: # does center (of screen) make sense for lmgr? @@ -884,7 +884,7 @@ def OnCBPageChanged(self, event): try: self.GetMapDisplay().SetFocus() self.GetMapDisplay().Raise() - except: + except AttributeError: pass event.Skip() @@ -1123,7 +1123,7 @@ def GetMenuCmd(self, event): try: cmdlist = cmd.split(" ") - except: # already list? + except AttributeError: # already list? cmdlist = cmd # check list of dummy commands for GUI modules that do not have GRASS @@ -1135,7 +1135,7 @@ def GetMenuCmd(self, event): layer = self.GetLayerTree().layer_selected name = self.GetLayerTree().GetLayerInfo(layer, key="maplayer").name type = self.GetLayerTree().GetLayerInfo(layer, key="type") - except: + except AttributeError: layer = None if layer and len(cmdlist) == 1: # only if no parameters given @@ -1183,7 +1183,7 @@ def OnVDigit(self, event): # available only for vector map layers try: mapLayer = tree.GetLayerInfo(layer, key="maplayer") - except: + except AttributeError: mapLayer = None if not mapLayer or mapLayer.GetType() != "vector": @@ -1860,7 +1860,7 @@ def OnShowAttributeTable(self, event, selection=None): # available only for vector map layers try: maptype = tree.GetLayerInfo(layer, key="maplayer").type - except: + except AttributeError: maptype = None if not maptype or maptype != "vector": diff --git a/gui/wxpython/lmgr/layertree.py b/gui/wxpython/lmgr/layertree.py index daefab44223..86531bcb5ad 100644 --- a/gui/wxpython/lmgr/layertree.py +++ b/gui/wxpython/lmgr/layertree.py @@ -1742,7 +1742,7 @@ def OnDeleteLayer(self, event): try: item.properties.Close(True) - except: + except AttributeError: pass if item != self.root: @@ -1758,7 +1758,7 @@ def OnDeleteLayer(self, event): try: if self.GetLayerInfo(item, key="type") != "group": self.Map.DeleteLayer(self.GetLayerInfo(item, key="maplayer")) - except: + except AttributeError: pass # redraw map if auto-rendering is enabled @@ -1997,10 +1997,7 @@ def OnEndDrag(self, event): def OnDrop(self, dropTarget, dragItem): # save everything associated with item to drag - try: - old = dragItem # make sure this member exists - except: - return + old = dragItem # make sure this member exists Debug.msg(4, "LayerTree.OnDrop(): layer=%s" % (self.GetItemText(dragItem))) @@ -2046,7 +2043,7 @@ def RecreateItem(self, dragItem, dropTarget, parent=None): newctrl.SetValue( self.GetLayerInfo(dragItem, key="maplayer").GetCmd(string=True) ) - except: + except Exception: pass newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged) data = self.GetPyData(dragItem) From 400b0df4a7823b1f767294dd567f16d226e80dcc Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Thu, 10 Oct 2024 20:41:09 +0200 Subject: [PATCH 02/69] docs: minor fixes to g.gisenv, i.atcorr, v.centroids, v.overlay, v.type (#4484) - g.gisenv.html: add EXAMPLES section (MEMORYMB, NPROCS) - i.atcorr.html: explain missing acronyms - v.centroids.html: start intro with what a centroid means - v.out.svg: fix GRASS_NS URL (fixes #4474) - v.overlay figures: colorize selected polygon in yellow color, not grey (sync to v.select) - v.type.html: explain vector object types in intro Note that the v.overlay figures should be redone to improve their quality (in a different PR). Co-authored-by: Anna Petrasova --- general/g.gisenv/g.gisenv.html | 29 +++++++++++++++++++++++++- imagery/i.atcorr/i.atcorr.html | 12 ++++++++++- scripts/v.centroids/v.centroids.html | 12 ++++++----- vector/v.out.svg/main.c | 2 +- vector/v.overlay/v.overlay.html | 8 +++---- vector/v.overlay/v_overlay_op_and.png | Bin 48720 -> 56006 bytes vector/v.overlay/v_overlay_op_not.png | Bin 33159 -> 40911 bytes vector/v.overlay/v_overlay_op_or.png | Bin 53214 -> 63574 bytes vector/v.overlay/v_overlay_op_xor.png | Bin 42262 -> 50253 bytes vector/v.type/v.type.html | 21 +++++++++++++++++++ 10 files changed, 72 insertions(+), 12 deletions(-) diff --git a/general/g.gisenv/g.gisenv.html b/general/g.gisenv/g.gisenv.html index 833e5051b36..4f5d9e165b3 100644 --- a/general/g.gisenv/g.gisenv.html +++ b/general/g.gisenv/g.gisenv.html @@ -149,6 +149,32 @@

NOTES

variables are stored in <gisdbase>/<project>/<mapset>/VAR after the current GRASS session is closed. +

EXAMPLES

+ +

Cache for raster operations

+ +The maximum memory to be used, i.e. the cache size for raster rows, is set +to 300 MB by default (GRASS variable MEMORYMB). To speed up +raster operations, it is recommended to increase this setting if enough RAM +is available. It is important to note that parallel processes will each +consume this amount of RAM. + +Set the maximum memory to be used (in MB), i.e. the cache size for raster rows: + +
+# set to 6 GB (default: 300 MB)
+g.gisenv set="MEMORYMB=6000"
+
+ +

Number of threads for parallel computing

+ +Set the number of threads for parallel computing: + +
+# set to use 12 threads (default: 1)
+g.gisenv set="NPROCS=12"
+
+

GRASS Debugging

To print debugging messages, the variable DEBUG must be set to level @@ -189,7 +215,8 @@

SEE ALSO

-See also variables list +See also +list of selected GRASS gisenv variables

AUTHOR

diff --git a/imagery/i.atcorr/i.atcorr.html b/imagery/i.atcorr/i.atcorr.html index 7c0b772e089..779ca7c7ef7 100644 --- a/imagery/i.atcorr/i.atcorr.html +++ b/imagery/i.atcorr/i.atcorr.html @@ -4,7 +4,7 @@

DESCRIPTION

map using the 6S algorithm (Second Simulation of Satellite Signal in the Solar Spectrum). A detailed algorithm description is available at the -Land Surface +Land Surface Reflectance Science Computing Facility website.

Important: Current region settings are ignored! The @@ -507,6 +507,16 @@

F. Sensor band

Define your own spectral conditions: +Note that "wlinf" and "wlsup" refer to the limits of the wavelength range +defined by the user for a given simulation. Specifically: + +

    +
  • wlinf: This represents the lower wavelength limit (or minimum wavelength) + of the spectral band for which the simulation is being performed.
  • +
  • wlsup: This represents the upper wavelength limit (or maximum wavelength) + of the spectral band for the simulation.
  • +
+ diff --git a/scripts/v.centroids/v.centroids.html b/scripts/v.centroids/v.centroids.html index 2bebed24e97..b814b702bab 100644 --- a/scripts/v.centroids/v.centroids.html +++ b/scripts/v.centroids/v.centroids.html @@ -1,11 +1,13 @@

DESCRIPTION

-GRASS defines vector areas as composite entities consisting of a set of +In GRASS GIS, a centroid is a point within a closed ring of boundaries. +A vector area is defined as composite entity consisting of a set of closed boundaries and a centroid. The attribute information associated -with that area is linked to the centroid. The v.centroids module -adds centroids to closed boundaries in the input file and assigns a -category number to them. The starting value as well as the increment size -may be set using optional parameters. +with this area is linked to the centroid. + +The v.centroids module adds centroids to closed boundaries in +the input file and assigns a category number to them. The starting +value as well as the increment size may be set using optional parameters.

Multiple attributes may be linked to a single vector entity through numbered fields referred to as layers. Refer to v.category for more details, as v.centroids is simply a frontend to that diff --git a/vector/v.out.svg/main.c b/vector/v.out.svg/main.c index 4c99d148d04..4d29f845b29 100644 --- a/vector/v.out.svg/main.c +++ b/vector/v.out.svg/main.c @@ -25,7 +25,7 @@ #define SVG_NS "http://www.w3.org/2000/svg" #define XLINK_NS "http://www.w3.org/1999/xlink" -#define GRASS_NS "http:/grass.itc.it/2006/gg" +#define GRASS_NS "http://grass.itc.it/2006/gg" #define RADIUS_SCALE .003 #define WIDTH_SCALE .001 #define G_Areas "G_Areas" diff --git a/vector/v.overlay/v.overlay.html b/vector/v.overlay/v.overlay.html index 2b2a35be8c8..0077f2915f5 100644 --- a/vector/v.overlay/v.overlay.html +++ b/vector/v.overlay/v.overlay.html @@ -97,7 +97,7 @@

AND operator

v.overlay with AND operator
-Figure: v.overlay with AND operator (selected polygons in grey color) +Figure: v.overlay with AND operator (selected polygons in yellow color)

OR operator

@@ -113,7 +113,7 @@

OR operator

v.overlay with OR operator
-Figure: v.overlay with OR operator (selected polygons in grey color) +Figure: v.overlay with OR operator (selected polygons in yellow color)

XOR operator

@@ -129,7 +129,7 @@

XOR operator

v.overlay with XOR operator
-Figure: v.overlay with XOR operator (selected polygons in grey color) +Figure: v.overlay with XOR operator (selected polygons in yellow color)

NOT operator

@@ -145,7 +145,7 @@

NOT operator

v.overlay with NOT operator
-Figure: v.overlay with NOT operator (selected polygon in grey color) +Figure: v.overlay with NOT operator (selected polygon in yellow color)

Overlay operations: AND, OR, NOT, XOR

diff --git a/vector/v.overlay/v_overlay_op_and.png b/vector/v.overlay/v_overlay_op_and.png index 3d4bb3a07ffa2b09a6a6e1191549f12d994f925c..c545f2140ad461fc5d436123d2a902b9d336713b 100644 GIT binary patch literal 56006 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�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 KgCc}!@c#iUi@)~( literal 48720 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 diff --git a/vector/v.overlay/v_overlay_op_not.png b/vector/v.overlay/v_overlay_op_not.png index ac7eb441bbcb8da3025e231801337d5c28c8337b..2c903f22d6071a1357a3ab3b90942bfc8ef99a5e 100644 GIT binary patch literal 40911 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
#=g&t)Ma9L%MJGmQ)@QbuTU0NV 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 KF?nW$#{559Z_b1O diff --git a/vector/v.overlay/v_overlay_op_or.png b/vector/v.overlay/v_overlay_op_or.png index c19bd32ce9f09244b0523d36220c0e9afbda6ff4..bbde7b06eb1eaa3f6e76eb190e805459bbcd6dc6 100644 GIT binary patch literal 63574 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

2b;;H($19zc;m^mN#p>juk$~^5Qd?|N9jant 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 L&5iCG*oXZeHz)d< diff --git a/vector/v.overlay/v_overlay_op_xor.png b/vector/v.overlay/v_overlay_op_xor.png index 446624f36ec744c8ccc50c73eeb3da975955d58d..bf5bd5b8e4581c26e1c0ef2d6f66b5259f2dc647 100644 GIT binary patch literal 50253 zcmeFYWl&vDw>NkoL4&)y6Wl$xyG!tcTW}}A-Q6X)LkJMu-JJvt4#8b#lmC_HshO&& zTQl#sn>tC(>D|4$``2r&Ube%O6eJPh@!&xq5Tdk{m+8xj8u8!^HRRJ1?*_{U=?~{cg~|TVr7ES``Fj=#=)+rK6;jG=bHWo+Lu9(9*x%gc z%89Tw8AjC!|3-~)Enx>a0Se2q@rL+<^By_&|O zPu-X@Kd;<~ZM(ezLkP2r4_U20XC886DJ@gqKp%qTt)d(S{_+;u7)l3mg_xtuE5WP! z8#i>Nh^UaPpQx-;C1Ry8%H^A>Uz2LHXpX;2a>cG0b~gmp9zM0-eD+qGlrJ`cmm6tF zs4aL*w zRb4pWra)x`#jm;-FV@hTFfhOp?osy>Tu>-Y(!>>imJQ^`f=7}z7W;YoVDLgV%un#02G$PpQ&<^`>@LU9s~9K~rO<}?s1Ozn-qjPAA$0KYM%F_|7>Zzb+;%RNdV@f6@2+!}% z3lOjcI~$R>+uGPU@wy9;{iVwbe1C0bA|v_R#o1bbOiNygMAY69Ov28{&dAIl?r!PI zN+t+T!tZEm#;YPG@gF3BUjk$n&dv_JOiXTWZj5ehjP{P^Oe{P+JWR~2OsuR7Ko15d z4?AZgcLqBr@>df7&=3PVnK)WHI9uA=k-XA0GPZYd79b-7o|F9N`fMHK<^PMkozs7y z0N}yoZsfqk!pO{IYs>VnBb=PYT>&Ehv7rCQ5l(7=crvMgo$Os4O~B%=U^{2>eh9r?aKme}naJ zYkPh2cRT;O5McO!(fzmH|GD?Soq=BR^1Nd9CN8hblNJ*od!3)x)ZWC>l=tsf4r3Ez z9y22_0~Ze`2Ln47s|f>-2@4Mc3lAF?Cks0dI}a!OzmSr)b8fv z%;aEa{&$X7zg~57aDe!K%(iuV}Jxv2t^8 zFmrITu(JVQ|5@{2dKzFyCx8=QX|gagvT^?%{(3CDz-9nojb8Z_An>;x*bA?yBiP8< z-cilo-bR4zl?2J_$p3mQ4~Ubgk+YGQkuw+|%FN2n%fbwN)PR3EIC)u_>6ux1ng6A~ zy{V;{$NyXJSK%Sy|L4f1ES-S)J^nWRBT=g0PyhV-=ckS3Ur{0<`70E>MkfDk!O6%K zZ2EVd0Ih!>nOGRvnS%lC@gMB^pY4|a53Imt1m6%f=I=q#{(EmX3-IeH0Dv(7T=oxO z?5w;jZ2tim)BpJ`8kuphfLWP27|hs=SOI}CV`bn5a{??6u&gmF3p*>TiP^s|`v3bD zUwMM%-?zxm^r{yB^HBMj{%^R)GI=ab8n`A-1-Rz<>PS+9V$3YAbf8KQGo7F7}4FPRE7s-LV2A zQZ-w$kl*q4os*0e-84AY8g96xwk$T5h^`D#e7u`pkQpk^hh~oAiIFz$Gb@TI zgU;!rRO;xbz;gPHBavjTL2_Sg!oxc92inIE;%&pA!H1+R)nWL98?7QWlXMN86< zOHO?mvmH$pg6)Q%cnAHC6guEe&J@qO!7{DEA#Ay)rzf*biDcK1y#b?laE`uDpk+(h zM4iFEgf$uai{a^!VK};b<(mN7uY+~7HK^O#1(w34Bp`JB*h@@$O+^T|NQD6P{#) zw&(Ad*y>XM;+Vi;9a|&R?x2f4F#XGL9hW(iw~%aPo8CeroOn5wTTPlF6vkB=)7@<0-g3`S%Kp_;?GRzP|{pbZFWwrV_Bo z^p)+F4wC47$M}0jTR7s)9@oYXe2r5n0vARL@=R}shSlF4*HU=dFJf?+f7hBzYIW00 zmR;nF#h(wK$o^8vpx2rU{L*BkH)qnQSto+{Jid23k}N4GXu6WlZ`!Dn@w6d2 z!C8^;_%!57XrZ|qg)s-3p#95xLlF7jtk*kf|M02&`MISIt68NinWI7^AmZz5y7ug> zL3Me+Xmh9jXRBA+O26B{IxkzZ>eqW~Q7s)*Scri%ZHI~VoRwk6w`Xr1^$J7RFCs^eHw(3%>`gW6zl@bRtgSo6Hh zAwViQxmH!rnY)8CC?crY>$T{j^pYmpwVXCu?&%b1pVFde&juRZXV>jGNwN# zT(aVB{TC4s1n&d731?7@^j$455z&(A?Ko!28qzbNP1*OQpueM`JoXhAmCc)G(S2~ zcVw_^xLBRWQEz>GNF7WFub)YMdD4*As3J>@HplyWaIFvhYTG>X=bK=SLaJ{zVjH+g z1pzGla!3Nh$G;fWUF?WmXC>ofXoh|G*Z!H1kSH&IYabsx@MU(q8 zPb^T{ST>KCZ|o)NJ#DcuY&CElHXh|r5$e=2Bb7Rt%QuqM?*&08 zgvPH*j8Y$3xRQlji74=NzVfI4XPR^44dM!1r(6X@-*bv$A<-pj+QE*q-vN1oo`P>% zf?ro9CoKUsgO(xkm&nSrNT&*){4Bj0T-eX-T=P3jm6OFhvB-CU%jSG=^Nj-y;w!hQ zifBqS=#Vijp(m%muf)0(kwWz%LgjkjG<#xpD<-zA*AWf*7=Mp!lea61;u+2akANkD zP$b3>#fp{u`5fzg4|A+LTPqEcfxM)SL#Zrw1a!S-s_2?TPmc>AIob-CkSz!yZq&)T=T| z-K-2uR?i%4bq|CK!-am6$^sMdg=I7~z(g|5n5iL^TYRoaJ>BiewKnBR%rYha7f9)} z&;L~iVGR6?uW@x5OOR}Gi&5)~qfy}8n9U;(NsA`3WjBhq+DBITFe5#n;LM&*CGE&g zg5GZScS7Uu>{ehSyPOpM?p}P0tv%yKT?u(f*AueGN2eZ2p)&I5VFt(>o3%Unu;!ZJAd#Cm>JuB45TeaFF&kmX7{RrN#)njuw$CjGMWEn{c zAc`1d+I{&u42Dc`IIZ8R8MXT&+yGssfRPql!O$dmWp(lLbEm;7>V6%f)JJM|RJ&c< zn_Rp(qMGdQA(V(D_;PZJ9p?6alSAC97%o{TrCF+{3j6GFaZ{(#=&ma_lHEXWtylMT zBU|W5%?kEZ)^?3_Z=z=oWwxZA2+)UY7O?}i3AV0@(ee}e1Z>raTIyhZdT`C zIWV+yNN_-S26{M0sDQ;nt{+Th-T1CKJ9e+eCu8f6sM(qCi%$}Tm-)F%zk-r_smSFX znOeC56~(p3J^NW#0AECMNjcAA}Op;3IP58cBdZSSWa$@4}U>H6mKBYv;;1P1ObvL~0_5GWoo`uI1v4a?KbV z2bq`Ky=kPmTkrbOi_3@?nSL&#DXJ(H4)^Y%QgW>^_GsNdoH!TfZw;#ty5O&5c-T-h`5iyP0;Ooxso;uxH-gk~fQ0jZzk9#=DTk`pamv{TZya6pK%1gS`8RhD8pNQw7R}X z9ciJwZiW2T%byOw7-^OBEp?7h7GlMfx?f%J4=k71D1XIkw@w7T`$Vlc7?Xh7(>a7b z{6#d<=WfLPp=Jx-sHk@84`1yf3Sh`dDl6$#I9@;>ET$PR`q7oBS4e4D{ubIn@IWH$ zt=0|+I+Yi{go!Pd<4wqnG#gXq(|8t&U(@V(P8SBf$1;7vw0FZvTI=`1ck5@Dj3D`rjK>Mmh=uhUFXD&qj{Ra+@sf~D>u zH_7ZGDuEl2KDCNyAzv|}X6Tg#R zVrX9WzgjlAdyF|n#pDN3xl+Oiqnkdp;MFy>^Zw8Faw(gMJ}`@K9>6yTs?_q=n7x?s z1VNKdHpH*DS<#@;=&-kw(0jw9#RS|R?-m(}`+CNj%p1M=!_`sP&pysIJFUIXOOjsp zSK{SF0(302sx!X`$|dyW58aKyjkt%KAy;tJBI{CbUglXykn!!O5vpgk8-@KWKA)UE z7(Dp`Q%WR!m{;4C7LT$O(USxYrMJ_*_+xmuni`!=B7sS%2aju_<*wa;pur4z2pIbI zrP)hyLe7LiI=b^`h|+9<1Ypsh-N0U1tl%xJlCo0iXq0v?1-*@}1v`G>aVwXFv6vg) zoi1$RC@*9oXA6lU(5n_yU&~zMgLy?G_rhb5e*S}(-ebF{ z-4xma)-y#aO9=klt_c&JqUu!qcG)rqq&exw6A8f5YsUg@|@n<&J$ z)e3Bo?_=#BF34<9r&hejSajZr8S%O(!maa08X^6A_J)DP&4xv!ICJQOJ`LYPW{ShQ z7=pkfzX5G(qcSML`m9*~^-l}VM`)`B*M}3Ydz`>(@HTI<=wHj}qTuV-T%tDG@Yd9j zM6tfPB;cA%iuZ@UQe1w3ArJksShp0{qrDa;WUs!~T=@+-?D@iQ;QcCb3Pa!PvIXh$ zzfm)4>@UkFWMLl$#mW_oTp-AI%a2pErCF0|xKX#bUT1Us^gD9*?2DORtfkIrpEbNN zgK4Sj4@38M{bPcLuFUo_(DCPTY!m-Yw>(+xUylruX}rx*oK$+?$hq_>e>X37y`@t3 zG;0~YHTCgcQ87obzJYSq`718Eej`=KOKwZso24Sk4#%ivlD8)0ei(pv1UAEA`_VOp zj+sD2(=Mo(%vfEDy=?Li)`C1-=pJ5P{vhkyTM0wf5mY~-GW1V%b_qokokH8q1&Z{a zYGsP1p5}zcmgp1uGorI=KDOu_ObTAch(;2P7+r5o`nL#y^W6{R=88*8jGk^;e)C5a zv3!>ZqfRrQepigQGR?&%CR?fD@n{&6RMzw+r}OCgJvtq7wvOV&5n&27Uh-*MY>EI4XV zn@vu=EHgs@oBF+(DpGZ|KJCZoYAb75welaimLCX}mucxgg*&QhRE@~^`^VSThrV7Q zTX52XnU^0(hghqh(=43@K83H;W(;i!Y#6iz_yTSKSV$^a0|fFU<)(!C*qoVc={&L7 zmcqai{H*}`ipz)Ocs8?*-RXxrl}=d8FyXzbeus8cRE{l=oL;lu5ARC7N}WKrCrew= zAB_6bu8+6ZJ;5%a(Uy#~#WfkQO^E2w0bhPqMVxy}BotvttBtce!o0K!*^gIBv~SIg zz}w3m&ESJbj&L6K;_7^U?hgz}CFkB?vwwyqA%zM?VpX1X(be62_F*?vawWzCzemiI z%SSNFwJReq3s$clA}iY z=NdzigHl4L{}n>PaF3B0O5hT_k6ADMv7Ze8I) zot0j|l^3t+Q|D(u%5O|ntS^p2@E!S8$P?JaJl6c1$?V0Xr7cFelk9(gKy*R@9n4v8 z9uZ7&YSnz_6i|?OmoizLZ+i0MG2_I=nfdvtr~GAYcuJB_la*1YTRz=TrSt>}CW${Ds2GDCDqS4} z?I)0AWJ`ZqQtNB+0*Lk$CsVq6#<-onTg^GrUd!-iM-T`VNKb-EAm2;IoY5I%TdZE5 z9s4vrG5xavOu2-lK&JaiAI}9&bEdAJQ`tuIJHd5@2!O*kt7d8>?H%q^vZ3E0t$J{6 z8(2(^E#khBIo&oAWh6TOYEAK>c)5)*Kq60MoRncNlbiPbb2RHFXZZt?QOvU?($lj` z$Q`V-a7m0$(t%2`&Mf9zT&id+OJAKW7l0rPB7R)MVQgVV*w4mECfx%fq(;9>*tu%- z4sWn+!ljT6<*P!37F-NCect9S)ToSEJ1SLF!W>Y{S1-=DYjuydS};0u-U6J_={?k< z(uBUa9=U@4lIdv_`K*TZcwZgLKE3xY=YdBD{3dgXcJbbCNn6h&U!|y%4~-fl@jxT$ zy}|Qu7kvcJt*y)#k<`A2v2>$@UrFC**Qs5y9bBmrxme*Cnz0|Q2dN8|&_< zH*s6!;pZTH_}BZ|V}?+U7tJ+S$3j3<1Z1aL`*9*8`|3o`LBhPpSN}XpR zboPS?4t{C!=!3zK&a`0wEIWmp>k~iSgM<04mzxOo3$M9+kImpHa?@>APVCoXeFK7r zBo`JL(O5dbE}>Cs4!=fs4^+f^h|do#eskVxfYb5EjXpVGVCW>e!*)$#u{DVYjS630 z6m{Ap;&m0dz0?Y@{!P8B*)_ARqg58*0%=u7hf+*={PNQxT-d@*e27=S+0i3;e)LzS#bhoIhVzrryW_J$*#@S5PNa7i zYu^jxGEjKg(7)Rxd;7S%Av>-c@-nDi>>uS~6a4{#4{p>CSN1xMR4=;_8C^YlfZ7o7 zoPtfFcbxIu{^8{SJ6A!w_FW*UYN2&ty>#ueIOG06%!9Zc)nUpO0b0gNIBhTZ>Xulu zbS(9#DuxtlJ;8+&Fmy2BK%FJIiuUev4{)IAt6%F7MZs6@1#zdgA`AwFjD-z@Ys%DpHV73yt;H~>YrZ*iPM>y?Kr10*WSewE6kp;<6Q>I zs&6i-PU1f=1yRB&#Y&@e)=qbOArF`Cp&VVm8h*5vbndL&O^N}*YCq>8G46duJD%uP zn(_jPOn8uZzoQ>`3dpzi><4MwU7>PyaQshp^E_LsBlP&=uG7(An*MpI9L z7*Ptk6*7@T3cX?^j=VwJcptS6H3hF;i#DHN?R7&&gZ&!Qp?VI#vpX6iZ-4+0i7+LV zc?dzow>N{v=YoPD7@hKhQ^K6J)O6ykGI$3%{Vj9Vdqx$`%j!p}ndjeu>vTJo0zS`% zEhM36U-kL69xv#eMgX<6-?2q6c8{)`QJ!7;s~ zW9*EvUp4j*Uixg0`0A=s2GO4-+#JQjAgj08HL88fh6ADt&yAJBhHO^D6fX4yp=0yYSnWI8 zczVHgnM*fCRaYZ4Adp30*EgP{6v-WDpy9%g=;D$E1c1oz?};P|++d{k1c!tXW-SI? zqDIR$_D|tf3;Ojz?|gP9P&F%TS{)laN2OG$3}8TYx1J{mL>~8V=c+{8cLT`y+zNL` zu@-FA%+DLbx34B!S|$fmGP(Rp^M7@^!Mx5Y_5lTp9kGkF`LI?ul$TQ5!Oh(7M0X*A zfM<5LN`7Z`WqRWj-WSnBHcCNW67qAhfO0jb{mF-;rKDJggohuBNAcqJ*fm4U7FtNH zZTPJxs_oB36&51D2SQ_rD6tk~jh7r#0${ctVt6-N-kbn<_7RJFI8bSDDe6o(?>Pz}>tX~D> zsM#aQdL2%>r8|23)$mTo_rW>M`YS;u11*-RgtwesM1bUGPQ4>EA4AcsG-|L>JHv@f zkN&oP3%CrSB@IvfyEfZAR8;nf!GQ-%`X?;OUA`@=hV zb-+ny8L)sm!e!Z;!lZb*DHJplPvpdfJ~h0(1dmsyS8LRE|8?rN6-Rd{Q}))j_=itu zF1C&l!>bR1(NWnIA{|pCmX#QSP;ag_ATzu8!rjZA=rvuy^)xaOpB&|VH6mAV$Yqex zzL&5PN-E(pI+XUSPMa=Ve4$S9jqM9bwU;h$R$J%9huuxb~vnAO8 z<;E2gud@}r)|*ql_PIhYjrnm!RmA+;%fZOcxiZuls+8bNj9ea9HO^EkjFa+0C(XvM z6wY_UdO%R>gzzGEQ;ST0w+thOYBP+M#e26q&?P56 z1sQ@g+%7K#;}!G1eQHrThE9X5Na5X}r4gYywo1X5coGDp?Z`LKQ(4RV?w@$u|N4{S z*=*R0@R*^P<$C%J8iViN!ohoLY`u37jDGSc_+}Z=k}U9Yscj1l>_u<{#%1a3|2HF`-VM|Hwdk|S-ckm|H>vGM6c_my=_L?-Hv4-*oOSVp}j zXx%-K0K1&uI~AXYEA7%>Nu`PautlnWrlqolk88oKN&Y1>`q|!YacNgqnY|JVFj*l; zSkrCS;?6ClIFa*%5sKLm@MwAsppJhDCs1j4UrjK69N|1GCi*ooc5Y^zpHHLYcwoz; z$vS?ok2xEOz5V9%-#C)^4wK4&fx1NWcw@gbqxulyAw@`d?>Yn(Hn!uCqsvd%*~*L( zPxXRv3j^*b6wlk_e31C+myW|iL>w_yHM@2KzyQ8RdMm7zm?>+aRtY3V%!DKO7K=&!fymS>dlCG|gUOv2Tp=6<~uYQ``6v@oqc~8FASU`!u!bSb(x`_IYG^*L=>7P6}1(Nfy zLXP{5f6N~)gGF#ytij@sE#Er_)?DahO10wlrZUE*B>h320%X!OAJZ++RcPpvs0DW7 z9qOy;WK4_(Lk+O&e6EfhyYQOTWYW;VUm62Xy9A)Tg)SLaL;E8& zIqZjDcA0|mRqj&Sk?7VkdWA7Jj^r5^EwwvHHDV!t&ew+dEu3EFo zn;bs2BFVALD=1;^NmKH4coJBrzY(WcG$LPiDhXWXP<7UA}`Ze_gjk}c-}=^5b~XzJW<-( z%A*9PQxK}F)r7;-u9g?QGIPFIuyBh}R;@Tn1N}yVbCOf34AH&nb2SQNC$>)sgV0FO z7>N`_@WX;V-A~*HL__RxY^FvvWMX4a%^*IGwQUkj|PW^_n@5eJ5jYb zu_?lT%DuE|A*txgJJ}Q}9O&Uh(%~dGqrF=8?TA+y@wTgTf0-#ZnXl$pUexVX0_p_* zsRcm6M&J{gDrUD4J6^rAYdD;4=xXID-eFWiB;LPopZ^TCftvs1g;}87;Cv?3w*MyM zbZ!N>h~#K#%bM%OL4%t`f<)Tc+86 zgsyWV>F(Jg7}|wlhV5!`3j&)7uldr+9z$(?J#0(&g#<;yr*j2as!DmmkdYIHO$&4; zfthjSR+kzFIvv-yE}QLDf+>-n?&5gK@pf{{6Kc&hjRrr=_l{ei zndXz7x77SGozKAM21$pRX~2MxfL`4%GZNtA^Fwd;(Jqd|N5ItcTcHD=>&Iq*)$#3# z(P$kQlTC0ob^QGSEkG;$h&#+bF}W9s30Tp0?u*4t9J-vczy;%?{8Q*6G&3_a0y{Ai z`%|FZ}^muIrI;bhaT`0ev?AN9zf@>S0%6oxH26k()n~6PcvL zGAoeHhE;1j%TO0USRx}<4_Y5jKA9b{IhFiYY1X1QP`XUFF)@L8#_hwx^j+vx6U3Qhaa%kEl-lJ7Z_ArKVr$F7vs$PQod+$f?)K^O9t&H{eEDuNTb-pX7xaNt0UQW) z195D=+oqjXVhK`L`Wd)uj3FJY?KG=%ZE+lZI+Co4Nr%$al?}RU)~L#V)8hK>;aGRd z!t{qTiX+;?L9^2XhZl@Uff=Z?KUhk(2QWnwadsx;OO*p=Jx`9eCOP&YemH9LcuOhx z!EFz(SsayD=>-82Hj?B96sT;Cjy$q$Iw$gbCt6KhLE@b9C1Q*nFIx0XRx3@JU)KsfbCkSCN4b`cRk)j zMoDg29N(Xb=dx7>!nSw%*0$>;1{rm`fHn5rN}VZVU;)=Q7@<{SrpAN*;-EzwiqD_x z^TntQsBUoIs|xGYgf8`&mAO^+2Igk!!kmT@Dky092Lg@3M!YVEdZEl$AkwEI zZqMMgX|h&r&G6B?@FNVb-(jd(&Tx{z)&09>FZ&q%IiCy)$jv?OyUkI`q zMnkJA5)`&d@_PQEy7U%;R@P%VnJnzw*O%7o26%_fCJXN_vnwB5;CbV~=Y4ve15@RE zaz5n}k*iK0L(G@Hqa5&PSM>XE*$a~%H9qi_Z*hU32`g(Ly5dWN=bd6OF;tI)v)?lT z7@Q|5Z82eI*~6<=rj}^S^CO&miYn06@tn&9>E))TAb3Dm3++?)xIZ4Yc(Ugi0T`#^ zJ;#2t#f{DwF39jKen+TMaH%TlEGB>xOON!xGbc5)tR(?Toq05pXI(!)x~XjIeyJQh zVSm>!UzN2GjKr?)QaF-A4f-HVk`5wuD3RJ?5sIgym^*k1(S}aS=ca5|p zjagT>OyB3cy#1SKv)_FD^`E4U16iT>O`l3jQa}#;-HYw=`q{S|CXz{Sq~5`Mqk2|2 zNBf^|s3x=gY<%dy)IM3Tf?Q9ewKMQnb$(YKE37t0{Y77|xx)EGns`{h zf3_^t&tGWFr;{Mppx~G~dPFjYCWGq~o@_XYT<5JaR&t;OIVU2C9}hCrE~+4Kb2X)f z=E`SBi=rs@M+J|{skiAc4MeK?-GQCtg&Xhrd>>tDt-F^>kvc7Da-U_$L(U2YfbIVr ze79rcUF>>lroI@FvLyUezl|gzR%;@Wii2ee=c`xvY#*1~kLWH;B3MJm>~aui4F^Bc zCMrxo$bdnK_<>eL8;;utGGGW1o2gz=Rk?6jtSY8vxwFIs~uNmmt3s@U2nWy+<(BHJ!Dkv|7mr zH5W>lE4C=2a;w$MGDFGBW2(JKPH58GF>f^KYYmLO89ug%YUflaTR*6cfRTmAwKMPkY$jeGgh+UXh)|I zkh-cj|6u+tjg7v|o>=uDp@%`YyvSF#Co?K&VxgC1t2im|3FgTf6Hm}B%r=JbC)!iG z($25SM*&Bx^x)sas$W~ub~-cAvHb!L=LC9IvllxQccLt|EO>KqUC#WcYgqPwU!`Dk zf2u3fE&et;+fz7#(j&?GEdK{|nYC?DF1Q0jhpIn;{h@{>bNS zdYeH=wu^y@7``&)ga>r;Ca)L{P9~wqxob`l8Ap(U^*W!`0XAVx(r)%@D~p4>K9`SY_)2u2`c6@_pbm;rA)mhmb333WgU^}z^6)oZ@SXx?RKC#c_B_aqUE!^IOm)I}QBTV)EcGIt@~aF%ppnI9n6_#YqL^cihc}blD_o$HhsC z8MmrY2Nygl!flg!;&8B~6hTl*rrYNyd^rPRInqA5B>x5t84$oc#*tjHEpj6FWWS- zswNZ7UaS^7(Hlb~3K!zkl0$SvLLrlY-(4$^;tL4~L_wLCYOypL32Q0YXP{0MjgHS5 zp2^%?2jxb5PWt6!9owf#xkvsQN$#Sv|71q94aMdfPDB@OQ<~QLV49Nh3`w)uxF@E} zt7wXnoqhiRynVd#n*atx5)J}MBgc~D0%_``@DH$Y6vE26DiG4VK-6RX&y}r|k3R~l z@3r1gO_=H;PkrCzMuWf3rOBRAkO9(b!kCAghv&J=XEvV_B1i%j4)WXbBR@%xcQ*Bo za6OmcU^5!~^;tn_F~z5zDTv36)}CJkypw7LJ8&n^ zWo1>ShwFIu8XbJZ1LN7a_fLA`^`6fW1HbML!hXxO{dniJlY<2RxR67!l!4vMC5t4F z<92e(Qs_f%b)|z3+F4^s<2+f`YJ)sk+zVQKH@rVHW$*LLoP;K}S}QDrcj}w(SbF;t z*ITH&M~`*6k@>_RDk6svPlO_z8ZRMqS1pCcpX%-kmM0b0JrZTfjN^@)X(2sJp#|sp zP{v)+@A4c|s=)}v@As|@!QxFnP=(&Z4L6V-L~`2d6pp2q(rIR=@^?93K&zA*?K#}L z9IrfzA5cd0r8f+oGT*5pNTR%%FyIHm!eJC&ioWDS(B{&Rgy*U}(dSJ340&`7E|Zsq zI8SDruB|jQgO-fp7^}wI$&9`^x|{hekug0Z%ubpB3sh=eU}@~m(o1zicmZKKWy*w` z#j~G?F?eF0Ms!)E(x-byzS*%^gn7B$>-&PG+epfBvF;)7kW>7g#2wxEwuq%(nz{wC z4+~2b>uhZE+8gV6@LvW5L7x#sX(z1qfBF`BUgyWhPiC(bHXP1f?1ljVXpG%?6C)My z&No4bWle!fAmpImOj~7*F5Swl)=Mq~7Arp2HgyJc_~~cJ0+Def!n|jXg0H#$aBD!h z)+1hba|b%r3@e9zL*&EF$I49{2byo~!Am;sXiJ|&1fUb%)YTn-{Ys<$@!d*P!Aw_% z_Jqe*$E4}}QWTfzPcE!T_@=z*m3r+OeYr3l!P2XOTL%qRSyL<-`**x1efu-LK&g!V z_kp_E)>ha0s2JpCuN3d+%(^Qsmyqw>{bO<+)j4z`d1X;8LuT@kl3rG3iG!!K8*nE?Yr<}z_{b6maIG}nXhWdy4Efk3LVc?AxZ zugnnjjeb0;{B~&-?UrBc?3A*JS^{;bKlkAU%=vnuG6L1fS-xP$qj!~tEo<#*Rz?(J z*Q7e=cxOR#3!5pn;um8kdLEd(WB<+CV`e;an`#r=-Q4X&yAJT#+5{HH#3$g5SZ z#Y9`iq^k^ebBNENfF>8C{d@uQNbh|mTBJ8d`ScrySM^3KGB_OdjeTodoT?v_74yC9 zd)>V8h0n0lxsv|-c|4jW=DnG1lZ9`-S#7u2uQh8h+#(U0KqEgDD>ze~%++ZhrJj`? ze=LjbMf~hAX!ixOruNR8KAe4SYckHlzlH+#9potObf#*E?>EcsOG~&1S6THHInqBR zf(9P#NrG{GFcef0#Luc~rC(^|h)6-H^_mBsr51Rnua?H;;&Vp3_nk3ro{I0B4bqv zo=9jZrdE1IfAhg?TD%D zV3GIn5Jq?(Tk+;rD&hS?0yPlr!R#W3>6Conx+wZ?(sSY(V%U)9_MrNcw?IyqkpB<9Ck&=PP(C zLjDpxkM3o>_D9Db>Bn%3o&4^vrN01AfWk{OmTzP+g8) zLOQhH5@Ap6oGyQ8E)S@he#CwG0-+R|b<4>RbQ&t5+M!NKnI{UfZI>04YbJDau)oVR?1Z!7IK^yy8cOo%=o}L`~@0$4;u@UHiw&Wp#R6VGcKp*o5<6ucM&OdDNMAJ zo7D!#&mTFZeLL>58*t#zg7IEj6FBNNI8OCg+C{Q(w|E`QhWajV%HPG(HUu34~q zaLQQ*emEE&Itmx_`Uv-j)4~lHZ+KJ4KuhKi?`2zy6v|6!PEis0oHIoMZxL9rL%XI@ zDz}In$RY!U9b@iyajxFYQRUMF>I}yN%o^%31z2?c8_ad*U(8JMPlVi^u50t2> zMUulU9PC$8+0L87=$trjS5FSAect_-F5?ju>IVO#gz{PyX=;^aBF8d7D_ zTpq31ensu=zD8{a-pG>YY?(Oc)iyB&mvUmrtC{9+bg)GoRFghR-B-!04XZj?*V7iV zkgq^DrmH1Pw7m4vu6k{E8jWjkr>fJYqv`u3UUn$1kX^Lgs@`U909b;MAShvtAjrYK|PoP-l|_$oWfV+B%aDQRI=8AhFA zA1dBT9gaG0o)0LMl3Gi@p7YrB%-hB0@I>%qJe6lLr%|L1NCXvAFt&hg7j0x+f^$i@tjuv zBs0?}bSff%>VL0K1Jsu}rts8UQ~Q(~(ox(p5nGR@?g>B1J+-sC*tmI2bE{S}?ai3m zdb!YFjo%#q@=z?NT(z-13zKRZayju%$~T%qj%qkci+9yduTN>e4@QFD^7upr1aNlP zJ{=OJWFr|NyNQIMi$rtfM@CkV75GamB#%|im5D=hZa8ft=>!tRhahQA&1!?Be24o6 z3L;W6+cPSy@IDans;qRd*mo7SR<~YduWch`3Enjp3W=rxl^czAd2{6%+nWA?6|-}= zwj}r&)j_8DAqdXj>dE_~pD_U$xJX;9Q7F?%qWSWMx>F`TSD&F>$E7Zqy4km0C%*07 zZmCS&O^U%3hkzaDbs-kRAed^c%`2aT#GmHkASYr+7Ly(g@HM|z2GOGT#r*K3LRBD2 zap_lVV!!7XW%KZNKl4{v$-1>rKR!~e*4G<5n2?N7r4-nyyZ!7oH)hFhl3eDvJ^TGn zDPV`u+)^yy|8z~aT_JNh+H$0+z_U;P0^F&0fqOwaXPQZN0=f6=JU8ueta@?mesJ8;Co0tnsG~ ze!fCutLszmuamwi!k~lW#`N3rAI^nBzc9DTtL=pp+FjVa{^YsZrIc}_Vd<%~Ybgrb zsTQpa4XZ>4dri$Qp`+UW`0QKfxWB{}N6}Rj*~W82XTJ6p^k=!=#}m#8i&>xr%Ynz9 zm`RWh4af+5EhG)h?r`0%1>RKHVk;&CPo!`CDEUL_c=`73WI%MHs=G_{+2E#-DiW1g za0C8_v}0$*iNe>S?&koGk(8kvEH!{*(q@2H6}Nr7w!pGtKn4C*4T0iH`eSmXJP=D- zT0{W~Vh3EiYZEH;VLf*bkwfZ%a;p|M%&aLvz5#Qdnnvn#`k#&?^DUZ8^nL^tk5-D8 zmF)w`cv()A1qA_T_Lz_FI)c3ef@drCg9^LyWYu4FQUr4Rc4{ldvI!vQ>jI>q*=J|r znr&#FF(iXBvZ9wA3z0Z;wN)$WK=x&447I+a=myTaOT%ebOu##o)5ej*+$7H-NtlP% zGtlxW*es)wolr2Ih~pQ#mqssNKn+zSN9C>b7(VIdB3o9ichS^UmacO(E@$`sCe-$X z(vCNQ*CA0cw$AoFMNE#&T8HAZW!AEPOG3{Hv7p-to&MFk5qagpaK8+cGHdFU=#K{G zXYKjl2xH*@Ax*IFHE6p#r%W7mQ3idWc>?2EjD@|p#$^d;noRZp)s*9UhBH^`69#-{ zE6XNfT!|cq^l46TN?H*OR!ao}UU!6iLv|}*qt~-7|akFaAXHwFcyx`Wx zG=S7DpBmZDI97|Z_j2*gpCz^e);r!4z9OiUAN$xYn~2}Q^+1(clj|SuElw2ACFIT2 zPi5hlkvu7PY>>$0lGw=t9BexdH;mmUUKNO*v!g;T`*kNMU*D_(meF}c1U9CdTOG=E zL5N$BGGOB1bFE+0OfSObag}RKhjIO1G<{`I99`G#;1EJ^2=4Cg?(PuWU4y&3ySqEV z9THrEySsaEzx~{|zG8kcRa0Hvr_Ww{$v&5`;0^Tmmx>|iReYEXUHommqkq4iE@(i7 zDF%F`I4S)VV`v()oYW5$a=Z5L^1)0}u`d#^q!70EDw(}HrPSN&5dx-KC8+LTrxf!zon>jaj{4q8WU^7TTKwz8 z`90aiQv8%l2~=8T$aql0b}qsbbawViz?G}wf9MUeYDo^De>{iyUS8VjF|52T?Qv*4!a3t&* z%sb3YWqrxX0kmB{FF+9EY%u3|0I=MFHJ^ z#;QwEcMju!a0vLgdk>bZKpOd!_X?b^kK{DYC)cOL^PeUn;6f;%-ShTJfZ!gA8I4G) z>T$YoyCRT%Q%jN$>u@~+r1Zv`z}O!CM{P(YV{t81k7Imq&h^cSlbz$Al>``EKB4pj zTt=s=077j*kUfPk|$k9XukEf+BWXfw0FX0 zxPrd^gVWk2t3~2h#NwrD4GMvSufh&}aU7~?Z?q95G?CJ z`rGngxh;7S*;a_b4?Lm|2b|Z6kZ*J>o&WZ=JpQ#7aw)Eer@|t7mdYeP_Zt@~0i{Qd zG7fv-6dlF)!7$&!S&c1I`d#-R>gh3!{a+1(L*1ur!rPYppGPIf|MLPMO9>OgMvx|c zeoQ1GzKRsuJgesedsB(_QD=`_c_Hxj8A=QXyC104Pbl@R5%pN?8BkGz$ysne9xyc{pVNs{GP#p;t$Qoj7>xX-|?7l=0nl*vqt^Z z@;=8{;sEFiJ-I72qimML|5ZyZK9W;4K>KqEA?*$031Al4yvI}=+5~&c=vyu>QxtkB zc+R@36fhs2IGuN0i2;=C-cUE%No)v`%AI2T+JKas?*_GI8o8eBc)xx?prDfAoM2); zWxg_m6i5oZj0ogk>c8h-2nQ}W0U8gKhEiAet03(UT+Gg=RIK{lmk9DVS3s5m9}l31 z09*h(ttkvWh1xBJ-=R5U6{~7U6!^8f6tP)iKeh((#AIOgO+`N2?qrV*Jsy2qY$_h@ ziZ^_Jdo1mgO{v~rZRzym2Cv(ft}a#QRx6{zV^pNlV!S>S^?uCWdFC}6ue}0YzoCfL zb>TfwTmd-DqTVYGcri^7YQ-3EnQpk}A=~AiE^OsXVXA%WydCp4kgl zUGhPKD1Sysib0@o;_opaP-3_&F(DKhWFQDOpwM4R@C&#g;W+RIdwo2kUqBEE-VhA} zQ4x;%y(bpJ1|x|ftC##Pg7&xz$Hjl?uu=O0YO)Z*Kt~S-wiSikef7Z;y(ICsSlw*% zdp901^ovud=16%N5f3H6Ey?~Yg)T8$O3UPv$!Ql@DU)Ufg89@F>1;eg%zCh$mHcPb z{%@c}X6(w#Mt?Z;xBkx64oTP_ZQG+3J9y15$|miyu%IxefB;{!zxpW}@`JxhWU?Yv z#zR=l6=d_s<#Q_=sAR6iRsY21OHOHM5O(n#e7?ZME|&9em4B=uWI1<;)})TOp+kad zQWHp#3xtnytkZ*ZJF5^0l656`2}h*?+5oMatuWurFkqtMY~X4cyZshc--$Z(Vrz-j zt%sVje1&I$zTeZUgX8SU<#LKo*m0?;RjC})#TE@B zp1eXvdQc>(IYYyEswDb(_?6iL@W?=dae7Va@Ia(%uwRb>~k_9FFT*0{Pr3L-rj5tgmRzq;^VmFj)|&di>;7AA{+i9gT0OkHQFV`7 zm~R~mNKWFqkh4Bi~JN=1NOyeI!o9Oj9C{1rw80F7ROCorZ|7Darg;P zRB1x#06_sH3)EdsjH{ZJY_+}sIe#uh#V#K6o-BHZ7e6Oz;z*y&$kTZnNHMPo5{sL@ z0XSn>o>mzdU)4B#ydO{F;9YU%3QEmZCOfp3#zVN5YjJvwS||ex01^;WfK{Vj_Hcn= zhuqih&rE~&yRJ5na6Wmu_GQL&jlP(PvO^^W-bh@|zxZEl@5bv8=-SNV*F-0m5p*8dtRI^lz;$6s(qR%gQ}|A zBa#@Wi)Tr-4iNLC(o!noSg^7Q^Bk3syupy9s)Ms|l=tPXl+oXu5G=v09O& z!+~no-R<<$gtM`O&*ObN8rUWhT3lo_Hk;|?gq5}z98Ze`87UD&*3bcoyvO@RO31YL z5T-rVxw1^zS#{dr^umFKDobiMJ}LI;h?QUO)!=syezrgAB9_3o!t)YJi1b~r zB81N6DoUo;Emuf19ZzW{Lz4cquqOvDRCpl9Ix+-`9b&(W8*>&b2W|g>OJF{`lg+HF z(h0`!Z5cK1E@-jF!{$oxhbB7>G)uFw#QMdW#Ud`coEr71ae*b_sBpKh@t=)*YvB-r zcG4n9;8%(JH#$dFu^D27Cm~jp*0x`V<<~#|=B*91_JqN#P^Skfq}ynmKGlCVy5;^< z($Oana2uPPyi`UH|AinI`6h-1tQ`?NS%R^Ux*_E!_jDn zF=)dZl5JITG08t-bWPH9b6?;0Lo{8>*4tTnxsG!C81%`ggtc4RB>n!<>*Z&$ghJUwwA}j{FYweUSZcEfp0{;iy@VW1ch_ivfE6SY zMB0!3bm;bWqmansMO0pt>zECS-=h(2-|5gSyn7o>R+o}Ic}#D>H+D^%K0Jje)lynM z@5`@1(&Q0Ah>PWy>z&`-)JCQ-UAVV7k;FitqYlyA!|p!C2EL@UD!qDHx9$sp zojQ@w7Un~Pq^V!-0h2Sx8KO8y*4B5_ID-3t*<2Pv2;}7j{tKy(<5AkBLZVu8uw*07 zfq7ndXQQ)koOWh(6mGjR*EJ#Kes@#%=MnqmZV0Wm_UagR+*_;PO`_S|=7-<&jEIn7sE#h&R_wRDy4zlw8K1w-=f%v~R^$>yWFYu`LaJV}H@arh#0Kzm)23*~u?k%*UOA zC$n)WxG<6DSIfS2uGI@3Ys^8C*Kv2RrTZ;(M5CS$*Pl#U>D)p1T$P5g%>2LedYuyx z5q1`+%N3E|xwGu%f8h(Kg1&;Q3-c9?z=lOK+7~!4IM!M=Lfele2^*@Dp`#8}s3aCm zOek%E?Z=$$Mw)h*%GhaYC#f$^cf+V1lPeYiYFQ$S->tX-GzgOcve%nxRV!oJM7v(A z;a``Vp4W;Vw4T#0cCSda5z%H3hT3_iH%4rU~WC6 zK!PHp&sCch@{CUZ%Y}F6vIp!>T^-Zc&z#9x z(C93BVxafWcP-R%=A^31oVuHKG!l1rl+=IVs2x038Y&C5F{~Zvflprnv)s@~yQi4@ zV?`JhBrgmIdTep>FIpBm#eMn$;lDz{hV$0aXP)_=qH*|tO^_Z{q~!^eug`|8zL2PA$pn z_ssu%r5|0S%hpd@KB_a3PSNctomgW~Ee}UC8yU}9zvXzWND=F7$eqfK7;V)w&eh_k z<6I)UEQ^2ytLc_X>SW_?TA(-2%!kB;qvgSjv;o z@=tEV+%xqvt3^?C>iKzVAFD*+4*N&!MHi~aeVy7PC>}R`i1wq8!b`pF z$l5#Cbew)zs!k^fWBmMdI$^z|`?UTSvu_Stsk@u=mDXS*6qoP1Bc2~5JkgM3d+MFm zSmCzGx<6b`k&H;NJ;kXFWM173)O+cyJ|8;0Y_5Ek6zXqEc0(<4H?luv!s@V;|a-Mr`6icC`B%-+Q?YE>x9O zHuwGqt-cdgr8?c?Ao1ddU-i!*)9DjC^pSO6LJ_f~s^xKxb#^rQ;XqWtPy|FCiQ;7S zxsQ82)*o;1W$jJ*9XvWEr(LZh>z-wRl^0yIO`!g*6uhV2K3U1#EBb~%J&{{6K7#bm zvG+-3=id6~39&98$4iY!o3{t+{;=m*AkOX4X?Au*9)(I$sp8^dEoLG80oo6(5j`9m z<%3FHkwE)44suwN)taKe%kvkVnhXj6=?mlam>wQa*8LF%0b{Qn_w^YS40;2Aw{cX3Gzae5`Of;pm^p zPGq`OAwEm>`c1Hz2`v_6SX{E53?oI;cy7I+m1+?bablVC)@3>c%BG?y2%vA6yTiuA zG^-v*7MwDty;mBVTn#yE?U+-8=Qd0N1bRJa`leB=HEZau`+X1%>7ut>nPGF--PmEZ(EIM^f2;ri-08F_MQ-0B~K{kpG0r^c1qALs*7AWLlxVl>WEl&scsYM$*a3GSN zc8t4gjjFEJK&K|=a%yuBpa`dqMvK_}oF`@qv7L^$*ar+tVVx*6U4KzDF|<4qwA~nY z%vV*bsxfs}@C@R5e5^Pur5Asa>YO4Y;H3E0eXo#!A3R&yjVEB0PRS{t?OPAS5}xL- z6@0CRTqh(&Ug|clFjp8n75sowO#pj{b;vVoDT*)^;bb;E&HB!&(uG2ko@MQuDd~1~ zdCT+@VXl9`PQYfQVmjXI5M#?5!?YUS=##1Y)3r%v zrK9I~k(bKjx7~IN!w6W)sGZi`Aq${fN2-F&UXA2RNUX>MO)| z))00k_sN-Jmc9nzN1SW03-HWOPLEc3f&TanG3Gz{gHq6m$98 z4Q_!)yXOYu*I_8nNoA;h=z&w`-;&6_Aj8O{I~YuSex&hL!`^be<8`6NSNlU7NC78t z;o8*`lD*G#-ER4Rd;Vdx@Y-(DT1~{Q?}IK66OpkgzAr0Egh_u^V^ChdxZJz##}Vk$ zX?#ohx@Wvi7)e)dhm1{@e}jDc4kM_Eu|O=l#z9bm&#OneA~G2hl8D(&k!ZGLv{H zhh4tbr2P4;k%F@na-<-jQieeFSFzb@(KDtvk6Tl_1{-`@Na`3v(?smbrsj+1T_H1m zcz@_{43@&+7Ncl88P>0;DXE6{6qpRSIc z&IwWe>(aRyim`deb66F55bEGG^(0dvc+LjD&7+v%>#&kep=Z9iw%B~0nd3g=P`^17 zkHIg{ZAzY0@xt!&a1yv$l>2FqL}D&41ZU}g`utSi=56W}Jho?!RJ!c`L45N-S74)g zjtK>UmZsJ5W2p-9;Oy3DNVY?B4>mFIm&yg5$=Ku9&Mos3d;ts|SI?cbgu4sLmOJ7s zHVST6^0H51{n#XM{|wfjz;^K*dQE4~ivWD}jo`BqX%PS?c&iqrllc=XUZwo!Jgrsz z^8beW(vuANA}9IbnT?YsmU(QoD*C5>=tN=iX6Y`!r9s~5HNn!-6&MyZkR6uBD<(8S z!m2`pMF4D~&3Xsbss>SPDX_W%zVjD)3`&bSAhjAboA?njyb=lmAkA@B)oK}bY$e3~ zR=@MXB+pm%9$R!>?N4hC`FS)N2-q>h5O4A-5tg2AZT zg7=*wX}Fa?Wj236!0x{&=!+<)@<`>IAO1VLgP3%tw$iWO)Dpr(d>r1_6n-CbQ}b7i zP1NX4=i!&0f$>S zi@-eVs9i98RH`|}G{Q68P}nZTW;SA0Uv8k6$;YZx+H88!WZvC&Gn;NN!(E{i1=@@A zI52Sdf&;3!cwKk>-xUhK_tExwl0$}Q7#}VaENkng`zf97)tpdI_(z?3EtKskJVcFn zQDYrzG!+}2@coN1WQj|o-tticA{F(@Xv#0E%@je1%quIqQvw?iU6gV?6Pq2whiH`B zL1yDv3O_){GiQ0slo;pZFl*SlW***3-tR8yWWmeS|Z4DIvlggs*k z&jCYfwV81u@_&6 z8Kk$Q4a_h)&3s%D1twNw5_f`{uX{hf-^}@0KA+imDuAvwl)LQ(oSr!MdZTcdvy~<5 zl1F}$D1s9UmM{ytUq?x)R0zE{=hfvYTAVH_z1O#&j4(Mr(r4mzlIiauGO`00SpvaN zvzB-D*A0bw12mD$Z`*W6MH>XzD}E2!hYN*bvfV$7SfvWxC(3cxh~;KOo1P?=bXlLb z-$zxJqT+g)ECX9K2;jzrhl0{HYGE%g2NF^o#SYZUNOlZu^YYW@-!bSd+G^i5J}QUo10Fcs(JRgT-J$ zj)%+t)DnHX+U7ew@AOhz)oS$4_#KcIdgBh`1jszB7#LkKRU5HbPD-NMPz`OXG`Q|^ zzZd}=83eZO*@bp{2fh1c28s#=UyWKAW0EgD#$K3jW=<#1-}K5FT{+W9v#|_R{UYRw zioz%wp?pZn(E`KYKcQFCnl=9!WhQWo~A1t1v$l}$g%qV`8PQVC>Q zS|uj3TIpAcB#;z)1Csu@9_^`U&`azXy4`gb0nexNeGS0X9o&ak%XA)fc*eD>Z2EH* z-@|lEY+D^;igQ{$H-%qh2khV$2nynG#(*v})NDDfu4?JGAv3wSf&fClpsz3TBP9W! zu=Z38rL%aLRJ?OibCamqY?Z<9(Bxapnck^cEW)m&lqc^9lWL8?W!{XB0{%b5qB77{bv)J0UMKO2WhP zoYLcWf{;Hly#$p~9~`_hslMUa-De!{-VIkPn*B|zAWiPD@TsYa$??}Sr!h_qmomNIiXtC9=q5dLt()tUV7N}N`PbMC6~L8L_* z_vtJK!|8mRSvpJyKLFMxHAj~27_WVSoHhw8r}wg8R2?aDt8+cQi9oL<$x?NK7Ew$? zz1SEo)9<|Tr6!nuF_)ES0?c+7cubF(QkAeO)`Lg3USPx&6J^xlSy$IhHH#YMKOXor z#i<6TQGX!c3&{q?S-;HV_iRB(o1Erd!8)CeEo8x zB5912=y%aI@W>ARH7!B+@p1#Fcfyc8Z#d}YGd3H1r4qekStipJZ{!ePRJvihj9{S{ z?6aO#WhtQ_rKU#FAiRbv>tszSHL)5aIIEN-VB>Ow2YK6X_Zfbs4ri{Txh$Da4w(-0 zfc+!lYV+Hk2WUIr-D*ud=CdLu=Hgki_n4NB%;zPA#eDAG9F|_wnfoEpfnUq2fKwko~ zF&S7|_2NdxQMH3`z(Rn>X!mKlw;M{*MkEMNDxE#FAqPzt=ecP+&O5jSl=k+>9Eplb zrBr^o?uOq<^TjUfMjDjJ-i^cEWzdUG98ZW|vEDu-gKd4d*h#G^7D#=uB;5a7!SACL zgQt)agCvgNSDbf>+f1*M==v~GtC_^Ew} zRUucUo=JWI38D#BLCI8gy5Lrrj%U#nA2}}6!qRTBKlzML@2E;Ql~6Po7;RZHj=%CYYZz>Y_-|BjsD$)FGViT9TiX?bXXvcpV-CzUHNq z8}TSt-&*AV!5)h1Hrjqo!IPbxK`+3oo}GuKOI=qI316(+qo+D!kL-# z4THu&Axs5dSbgH~1b$hH+|_9J5*%tfo!G;tKPHb^-@>E z^#^pn90lL#4_E)`_ zjD}<;>*c>;f`a>X(ZF&r2O9l3%h#4)MG{XMD}^Csr*m=V8=cQ#_UIm`W?W-WKy8eF z_ntiSVdgsB4B~a4-^}iYL1Oe~d|TU6>ZShfq{i*(ZZK($yxkH)#`Ixc>2`Hk=q^>p zQpg2B9BvDOygEyu*YNpVyj(Ze_Tdr zy@!>g$9?x?*b5+x97Duk-(+IKOr@LQlf;A)g7jA|nb{;PMY1&}5HLqYZT`B4KU>rix&FLssM$xFlC=4X%Dvu7)}p=CrZ8KB+SgE@e}uHJNEK#bWY1;kbyfq~gqU zes42Q{h8ryZRK?*M{g^wR$E)A!;8hF{9_I%2PF z=J=zyh(b;E0=|zn0;_scqr#-2_I@z#wc*v~_84`!5a#Hj>a*&8K^Gne3U{%7)Qv!= zAEu!-8H@966pNDgXeVOO!>v}m6ky(7`!GR=F*<9pV=ldpbwlBDJ5Qdi$~v?(bFW#Y z0%qWl>3h6?KGvJdBM0EjmZ7Vj};ACnpZ!H`*LZ(Xkw%0-H?q+FwrjKZ2g9J)Qq&*h^ zhN6s0v=+_YBM7({?0LqT0@I6r&S8v}sUm^&Oz`&H+ngjI4d`mnU~LHauu`dv-@G0#>loqn7&VTTavGBTmibN{n#UAt{t3W*iw7B?h4j_wqjucqZ=PAw zn#<3-1-#IM90uIY4p;9}U_Rsd&Gw@vwAayR#|h|djw)1~^rAr5yCF~41;@vdUADK$ zRkfX#d(ASK&v2+G_#47-h3d%o-vJ=DIXZ$wOZ#W+%MvErcdZOuuyDu#n{nd2#nVMw zU~n~A3XN+jQ@~ZI2ILdWQl)OXa^B+{WGEQ;3YfP}Yb^zA@0&OUsZK+S_~AL~lS#PW zLxMB}oF8ThIY zFuwPEOO}?Du+o&Yrk<$Pr#fdd3><827v^PzI3`9O4qDfxCydUm@oyLM?U-pq|7^cS9aA3 z;WrnsS22X(3|1=2frcKL*c?2q)<0AXSE=oqGF(o(d@;xa=0dOTfLuC>bUU?dNFY`N zMq?cu|6GOwGdJ5rU+W_NO~%<;5aiA5u7sANfFEV-SIFJs)kyjMY2{X$*P}FZDs=9KZO^x^Tuh#VpjH4Fql2vJ|!2Od=JpGVbZPWH=L~gXY9?Bw| z8;9U6E0g$5;3?*f1*dkRdMc;_W9abV7;Ux)yh4SB`=m3ZP|u~S_-C*c4K%~M|9GJGYFdgqO}T$53$Kp~Fbh!Nenv?ZdEcsSAFP}9r(QF*uI z2@mLc0I?Y$&?MbHQTs!;ObVizpId{~_3C-IeFSa@eOh4#KAsXhP(}zDj(Ba{=N@FL)w4-qo#VY@}fAedb~?W9T1lq z*9Ltd%7M?qSr7HdFVAKSI_<>Qhpx9ekF+x7KV2au3b~c-9x^iE3%JbD(vnE;+!X}; zrUDO%tPT(MqtxiC<^DZv5}lstDH*Iv3VR-WKYRPWN|hgq+w1CPw8oQ59WUh-j*OGD z8Uyk|-5^{Lbnex9N;bFD(OLwrYs2RCA1x>Ly$iR+>UmSs2qB`sle$%!o?ud(XE%e$ z0-}tbWC8*#JU9$Ur)jU2fsJ#TM;*aYG)kS{c6Qz0o!bBae8c9F(Y?0#=EA;F$#$X@ z=YAus)2j8DqI;aJ8?MXK#_N*wiA5RC)Cx+p5LVfsoW&z@-7g1&3`{nuFQ{6r;ZJbB z6>uDh8r`9ImeVG6WtWS#;-!dQkpE0coh9G?+uA~JY8-W5m7cX2U8AnKP>+g*M;47Q zGd$FMwW@S$*DGF9soZ+Ge<-)U(WI2a9XeNhxY3t)ezuNUhwDzqBlgUYv}erytq{mr^94`RUjjwXpx8(P2k-#b1I z(AZ`W zwrdfNTwQZdzZZ6YKTFQ?lBfznblRa&6E?GH==H=cUMRC*f5xb_mr7n12L2DDyGfy zM^m}1ED|g3w6bB+2dWZ?B5w#M|H#&J{eePUd>J#I(P(M^k?FoCdknTYn3B#Vl9foy z>Zk%p=$T$fw%v(iDH7ax;f2a*Y+XoX;Zq<8a=$iBRXgV3R&2gUQ+R+N++}7q?HiG{SwCFYK19m%ngVATgBx2CNc3!|=Hd@@--fcB7PiHOZc9-DU;&!inG zllb2fBspCS=y1t*GG|cw>;1s%^B}tsDhv76GkFyX?mJ&RI*x9M9X%?sbg-OY{0@^yesh_cN)Aw#uzmQ1qx*+y zwH=p}7aSb5b2?qbDKba1s*gsz-_INSjuVPWZ8dq&kO;!V3QZ^rv9h#=TKe8u4F|EM zrgFRY|Nc=}h#F<^uP;Jr(n*`LPdf5HiaExu+k)-%l}l$Ggp$oq?OqBn0AQRYIU653 zKwDmHQE;7vIn(F-5CDJ4m!_>?}pGEqB+sW1D z^IEG5sVQ#H{luI-1h#K9W5k`%p(`yRd!wiO?N`El+E-0u4+hJ%SYGdNjmq;s#lR^z zH)X{|ab}Y`o*OSI)h6)5B~kC?zpT-U80NVfY3c(TSrVd#3q^_2Gl+t1_!rhGZaTKN z{kdHW>F9)pylcUTWUek2lin{dYoyam&2Z0jpq>k(szzzspP$^|k42TVD z7kt+8iY40;6(z`5V&j_=z8fzS4;;s3mt_=+u-PCB!;OXA@cra%jD%2@BoVmBOZnoP zE31%IjmM<=T1s_U78CSgt$u1_gB*Yxy$@NXMqxHJ@8}KBh+uwy;CT<1%M#%b&=5c* zJ5lKdgGkih2XXM%FjyKV4g}!qV}=%<9MghaoLpl?Wo%lG8(Y6wKTHmX=_6h#t~#-l zQyLL^t{5P@5Ux&OV)xO=9^^(Bfya7HF4cy$ zhP)ewCa(Y1PBlD)QNtN&J(i3Vix=hhF8y`=O09GCNO{uK(fOk~zV75^C1yrCrCZAj z004j1`@$!c%Aic75eMJadD~oM7|k&IQmkhe=}`Ez;{yV2ZL6bMYhmh;jqb!OV2@T3 zW&0t($V!`9EsS3?ihuiE-;n~|ip8J2vkfWzYo4qG)#z%sb{;Zg#3d-}(WB;o%KWQU zA} zW4L?n!l^sD|NFuC>L>zFsaxr^1vbA6)v>ujaK72!rQyi%5z5LKobmX&0azi}&Q7)! zOVw-Chn!;L@FVU|vu2Ag1o9h%!6d$wVOV(oNmqvi93LOk0vkgZ@6Q_MBpN~h^WcMw z?lL%w;ySeZRhW{>kac&`8k`{_EI@6ol`HX?16sz&gYgwFFcE1%#AP| z#y^i-*>3XmRE>XuwXF>sJ4oDEdTB7ad#(zx*{0rZbl0KC1J3UG^(_rBNBCw)#o;%{ zrqD7uqC=iz4<1LTjk`2kp<3}Gk;kUm=V>_j?s@92FNi!|e!*dv0zK7LOhAKtUh3Cc z9XH-5nZKrIserEcZyJk9iP-h5R912PAvrBUK0vY_~7F8`yJO^%!{r5 z(qr0kLdr?Y1hCEV*_=HI(iQ&3M>4itnG*~17 zBCYlM^LKal3P^MLL_4ZyPpb>r=J5Y)OzziOgHeY)WITk3Jl`pc%g|??N~Ap&>;*|T zkp8YX!#|YFR1yM>vZ~rx;VK(=_gcLE7jHJ=M7svyuBA{T4`O1fROrGu_G{_B-RBlb z=n#(%krxO4_g05^I5jn&ZM)I-6QPN{d5;j8ZDyl>fx0^ui^16f$RX%y@OA1hNe9af zDGfKqP46&^!14@KVrVZB&kgdHJF3lzLpaAg?Jb)KGrwg&W740y*O$1-GGc`UmxcuM zCxNRVvK=#(amGe)_rUCz8-~9R5=m00_nQA3#Ot{aD>TnM$O8*cRC*l2%kULTT-Q5B zqEE2Pn~J>jm&;jsPZ{0op+Isc_;(Enbbk!O4vV<>6!po;o}6^|PE8U8}DRYteEORKIMFe14QcWJ0HkkwSfipoQng1N<7@Yl%r^ zO{$Vp0YtM4In2z;fgn}>e=vY;du7Q3d0 z1DT(Pw4Te?vH#-GG3vBZZng%wcszVdDXkNb8a|~gVBKyao4RVo{6q66LS2~5NrJZ( zLsO~?B<)ptgRX_Ym4Ev+l zOyCf;2HIcB?ipl}yTh2EuC?V}cY1n#jHJ2~=ocD)UujQv;a?5nhi0KPvDnCD7n^L_ zXxrO{`XP6YaEd~JTAE+(WXVUs+csT=i07|88zjXVcIHQC=T}Bw972nDx0yHFH0ItH zhUEx&9I+9)+6f5h^etM#&hDYZ9>fLj8Doms1 zMCo`5?MWwD`fcE56*?w7#!q@**#t@CS6{>6R3LcsPdGKQJIKs)MI$@N|8(2Lr>7sy zU(Ux2mnhRE(>AKtT19zyiv0#Jyx7zYzN6-TuTpnd``9(2|Cf=m`zD4mReHK`W|QTC z6bP!*?@ygr-xd3m%4#;yzl3-6x>Gz~;B$T_NX!P;Ot4bU@bS`{MM>w(uv(Oq%g=h@ ze`h%=;jhVqB_<_(NMU-FN&NDkF=*ax+_J|L0o*Mclw_H5f4(SJ(3rQWyVB);c8;~# zUMtn(aa3t_wc&I%LbTBpl1Q)1O=Pg8dcba;7mal?c9X*Or_1%?w*b3C)M39LiCryZ z$lZ_Tf77cA9W?cQmpNiiyqzCrW>em^b3zMN<-q9(pLY0<6-j&Y_)DauS)=K?q?HJg z%6@eyZK<~L<4SNnFsQ78zL==`m7G?b1 zlbKLTD&^~cuKK+`s6S&U8CiQ!!YUOKPL0ZdlNR@W5F_Zi`}yMtpAU`4t)8Wwh}ryV zB158#6h1KhV~_#xtham){-GGFy@WRd*o~!XIKVY>P{Ef{=@>y}b8)Kh?)DR~Dy10( z1FdQuSFvw5YgC%l=^~j$L{DJcKeh{0m1W?-BxJ~JzNNVZDk!3}L>~sgx{U@54*f!Z zA3kw(15T7Ktf`czM#Bok0PQAUCM*?CUgUDiZLef98&66(74h*OG&PO1R@3_PDP)W1 z<^)bYoy*Ht{rtH+gue^WJ3dWE*>>duqO{ZDtb_t{IwVXNUL5#c z5=Bxt3E%s-_`aJ#XMK^rvky%v|hvA2)3Mr-2 z06?;F^*&-VscP3(1If$0e28c_ZKD(79P!tKvBN#`>7pS;+9(jIm^ExJC)vfyMMe_p zYJ2B+JV6}G-TWto8{~hX8w9s2-qER`*%D;lz97SMlkTsZ%|V?%=N7Yl%+mQPRYR+& z`fv2=Zt3xO`rreXI~D9R20nQ>esr>HwPs=lcjkSrCW>|ZI}mszmP|lKIDK?=8b=$% zgjA9mg8bcEB6rX--Fo$#BJNSQhqTH5He|29nL3>}=H8|-w*6_o%tfhtWcB@Fyke=& z@a&t^%IunC!^|fQ3!FBPP9b_|P%Oe&&GOe~$N;6PmvG{XZhyV0l{;X!k`>L~EwHFg zm50jI%VTr(BH+T<=vQd;EU|l0&7tJ~{KzRSiCC~k(zj{!<<72C+=0hO#zHNR7tgG( za3nu}7m#|($qpC0ZH9^SZ4a24730qPW^#LoFUDL6w41GyQ&pTues<5JlkC}~IG=t= z&;S~wj1;9AZZr@6cW~njjv4{x!D@uY_Ur1b?(6guKIwi0+Zm~$VIbgU>!Gu%KiIc) z9-cJm1)Cq4neQ8PUa~8;f89GGLF_Lxe(!Ytw%HY--JF{H0B>s>(({R2rmD8u9hAi# zq%2v)|0##5LCkX7`E{#>e-i>m36R4*n#qqC3UAqT1#Z}E9*2wAa8WiOJ`;Bgj*vHB=U zwK+NS--YV7*OW150XwoI7hocu%tK$SJD?YZ12{*wE7+?Hf8!w)HY=2GYBRrkRxkNR zAYj(oxvI`MQDl`!F^jkS0$|JaF2)f;fy{+;$x}`Yj>Ojmy{>t;4RN4wUa6ibZhffA z2P}lOM;H$&FYShCsj*nAMP;$>nB}fkA$9Wnls?spbEw8T+n04dbBrZj|Jb7b|BMir z+Z6!YQ2%GdAvFI6iVq~jHqoa5&PI50QNBN}cp57#ea^&39U`dS@?UPNSXeuc^_Gjn z_bqt5{5VQaqv!keXwOeFw<4PfO9*ZO77HfWTzSdPu5`U|sh=Wkb0C%|3gOR__i1*I zP03pg8!9sd$+-~t#5tn2l*7(d(lc%y68NK0Z}yiVO(=E#$SsKR_3Cj%VrdS}B$Lec4!IJB`YVQ5qz@bTt^| z(`=110-irYPJcg%$D5DC>JL5bbMp#&JX;b^2oApHMpqCbQ?e&v4LsGq#Tr}Q%fFD7 z7QZC~!wV9>arAeqT1ulmUtJc%0@hLFf16Rm1tZ~~nkB0Nf$=Q{cG30}|F&}P714b1 zQ8;Xa|EJ6z$T-L0hcsJAvECZ|z+lb%6*bcrQRKZSgA5WK`5d#ga;{;}iPq~PY`0=_ zX0t<GZ4oXH3J94hE31j!O`r_m?897gx+nh={;}bAHUa;d=nK z+Jo`Fo4p-Cj`FZlC>i6wAi{BEd>NoRX|%~uR+Fk|cwH0t6{8_b;`U!8d|D)GyCA6P zRpiBHi_GKUD`1nu<>?#NL)mA3a$)bbssRqLIE@P6wI5MR$pm8G?^+u`G$Rz@)uIwp z{XgIoS?$0g7gU7Wfe{ANpPb%1QtgFlDj(1uB5Uctp{dnGzefY>u~8qDi#nYHV}SjRFKUVESyo_pFg;t?4q8W>?REtrg6;F=^w?h zleIL2K0CS4r1@;&1QkzY-tRP;TeaFrRjHnQOsM`D&2XrdSyw>is9oaodRMoZio_`VcP|i^obCiWE5~A7BNkZroWhBeDju0 zifk8!5F_5W+W(|6z|}PjN})P$+C~TkRh-)>QV(jZ80pbdrtGHtC;@SYA-ON6d1xa zU%9X=_b*6UjeJMz+qm$A76$bA2(OzEw`=mlKQ*@y)J))>sRJi}IrmGC9 zqiMPq4Q|0LI0ScsySuvtf?IIc;O_438r&g3@E{j=cX$2vd8h5<==W1a(NT zh)2@w1LxK8K!UO{`0IP%lv;%gPS0i$MZOu>FA%;|QQqVEhvH62LjBJ2-*gkDvQD6} z>InsmG?y6YF@NL5bl9CZ@ZJHC;+w32=m^sPLF2LAwWzC$;A;^Js2o)OWhMMP5|Ah` zkNTL09TDj1f7HtU6Q8|1Cg;W+Rm^-HY$43Vo81Qd0vwYQ*0~=MHX+n}0Iz1yn(Hgh z7&`FH0aA|R$Ix2#n?v5d63rc}?D$`!db;KR&jpZjbfj{9Z1l}m+Zh@`EDmHin2NsN z7=-ZG_{8@qRAdC;vPgu2BP>o(=0#FkT$|42x1UNi=bQ~M9)3-U9}<4m%&}R~@!&2I z)93K=5chL8|#@dn`r|xKE zhYMoOF4%et2UP#AXMqmY?_$ZcdI|x_!KdosZ9g>TbEnXq2{^y8T(#e;WF-f3M<{)L z%^C(ISEgy4$C25?zc}s`a#(DZGa2e1Ww;;^G=sj_(qdk}Yr(?T?>cVS{ZaC*g9;6E2b;;|9O7a%*gPD>U6q7sC^rMr2Y&3NEj(`fhM) zKE7QpFJ9f&tf^AY{p9NcGBSles#8a$DHO>Kp||pBSa!?1CbI;*F5y&LGw8AR?Vw3T7`5rvo5RKcK{Kq*Veg+0$PCe%!-S^EQ_5a_{IdGDf4T^;15ttgnrK1i1u(pS10Q$+CL z#jzFkdK;uj`9BSAxE{|XS*j_Ke9%(k%60s%Jz<(nxJJygblQ%Ur`sEcAa|eY6$uOY z$QAe<0%Sz#zt*9ppnW6dWDn|j=pB!eXY8MVJ@>lZU$R9y&|25v035_qN!yzCns9@X zEJ)efd9MC}AnK`#Xnfx+DqesbF$YE&%3YyhWYMG!L=?VUDkULF732VlZJG15-TmSB zZgILmA$SSLjBH-6N)@bZK8H#n-hXou&#sw0VXkhfoc2K5C4*GiSo9#MoEHBZIF`Y` z>9d`o)al`$AZ6qRo;MM&j$mt!vfKaBr5;6CH3A`2b_ag^iV$gZ+PCntHBl4GwjSxv zZb4PzEU26EuI(Tph&WJ?2tLH%JabzuNhfUH-uPBaE}xh0&(%Xw9-=?`7qrC({t4R$wLA-=;K-)hma2NfO_tWuE&w^oYe3JBOgW8*=AE6e6>lkDDq zWwKt$X!G8(%F?UCvLNw!QUGo`C#O{D=UU2nb`yKN$KG%2l|nC@7i*+I{&yRpD@;;@ zQF7aH#(Rf|2{7yOsO12a9n@SA74A2Kv5gHNaXZA=qr#f)uhGkvl^ zHjtOzsMo!?cXx7hEXkl-V143LV=YO}bFv=|w!3?#E)AlffCKXRG*Xb!X(tesNnf0x z(XpBSRU4+>pExty)Tw+_I*?jxp5SwmnNJoNc4MA!o7U+i-` z1B1=ww%RZU7OG`!qIwa7N|=Ip);hV{52k?rxM7jgBK%zaa-LWbGow`5D4@d~D3_*l7p=_w0;QQz}Gj_%n+MR6e%0dR-jP%GEntLTkb0 zL#tK)u2O_&Dd z&8Etq3}8V9^VF z%OBqiST4i0T;myOHQ)r~4XOcvwU1_~u!-FiAVy-|nAC#KRsXa5-1(6$n5;-dyhu$Xw|kIquwv$p-}kk*Vy~TUfqq;oEBe3BluB)P zglk*P9c*PW3l!LJ*giivNOR9(%9fn77ladqYI@{B05m z(9;VK_*Dk5;vNh-+L|y@&)r<`TxcAiEI1wzgTDf16Nn7-V4sb@z2W!zO9vUKYcoAV z1EF^cQm_XJdgxdo?fqo|EW-wfNiRAa{k1*O&2Y1i`Fj%W%ZnwRXsGH(g%P^b{&@Hx zqBDmzI-s`hj+2^vGi@UT>T`iiSg&sB4b3MVARpW%2TB+^8~fXPE;|yyWy7=)LV$+D zLA?!OK;s!LYzp@6Z&&O3EVK!=+d^W4QhPJ1aOqp{K%tI_%nv@L29+|^&@jH(Pf&8- zv3}-}ltjjf=3P7Pi`7&-H(8_B4kB(*e@XfJDm6mfb)1egL#Skg+r7f44SgZ3%YoL+<# zB!Q-aGcJ4J4u@ohIb+nx2q-Kj#um=iqJiXeYGRpFCOu{G1l}m5FJDZ}A{5yky4@l0 zn=DMTjcw&iOG>T?k?<63Usa85ZOtc3j!Z75a(h4^pm%}z;@ss+`a9xUZR-ATz(OdB zIUhei=FCU1MGg<0d?zEb3eDe7f&N?Md)N({xf?nczGf#2-4!~>OUb_WPmQ2Wu=(gP zGz`D{s}>TsmNFo4CQ&E=)OQ?#;a3kCZ zh=lG0Jhjs_l^fmxnYIjG=j)igbwgssgCw_(HL_Mm^K9K8Nj#!UaU@vC23k2xJ%T5* zCIE_UGV}A}GsidX&r>-OKpA*GDL03eGM%Pu)dYe-Q&Vf@6JV4|`-8tc`@E6Bgbe$D7w-!X5vGM_c<)i`PKzBpA~xVN&yy)Z z_F99OYvJC#s$h|o5Fih^aly8K^G;k{htl*-hSrbQ!A+u{I!-kYO62A^ocw;6h@uc; zCgd=_vnCSXnn;3({58`LU-}1s z9%K65wi3`Sg;|?JO_Kjfqlv^m98D2FQ3MW@CBfJ5XH`>=XYxOX!X_Su#T4NSbq*8C z9Kg`X6#L#BoUh6H{4_k=mP{xsVG%f03e4hGuCJo~$>eqU#Qqzg>hCQ@jDITqFV}A zM+4Xgx%sVqr)}JgJoFp}2^p}J*vtgu3751&=*_h9Yi94DTf95(Sf$(&W2 zYvJyJ!}8wPFMwX^D}76d55!c4vqxu! zz!iQthd0ElWq0B6*+u*EnKvlerXSe_0BkwjnAj945>6&K)ZqB_A?Uy9zifRfE|#XU z!johui3FdsZ(l^ZOG4jKL`8A{rLaVtu0WDWW|ENoP8rYyh~X^jKR`DNW@}S|*?(2J zApG^z<>8TwW%FxCIhz|T$PBZpB2SAopO%5XgwaPdLpbV1y8_0 zM&r@j8AE)8sSUG`gS`l^hv+z!*{fY(tRstu0wEx=#k&*ss(nUyA?7CRwuGWKMW502 z)(a^4SOzNt?3TJUkgYOCX$i8#x3QTXa%rz8=Kv_;M)L<&b2h=s!1JETR;lC8BlxBUBc$g$5Z0t))R@1&Fpq=1rPod2R+6AAEAow zt6cfYhyEho7lZ@%ach@K5x<;8BNM67os)L{!3Xfd0XFg(xD9)aaR+$Eh* z>Ut2oqR>RFRuPoJNv=*iJ(AvvO>MJ|$>k}x@L_$yw^PubBOq{)(xr1~V84 zhy4c|###xpz!*7vS_|mLw{F5^bvhJSriF&3Tu%~4Mni**iCLwLc{;b&<+XA{=20-R zft%=G$GqWoZr(LMnZCA>?KCxx>AHdwq4w3pVZf+WUqT-v3lGQ5xZjN`8WtMjc%Iyz zPq^jP`*Q4_=y1A_Q#FZSf(U_B1rq3haSS6a<2!%_d}+kEBE=fVYuDqS6qiwa_oThWMclr=Kh z@|Zr9JtQB|e0oRjg;*ApYN5ZW=GNYxO?~6yoNr*!Dl7DRb47Z|x>)~($LdZg>SffK zk48qBDEev8aZd_Q7E^?|BOA_c#8V zhf>pCvwD@{1;e1IgN$_pAoJ$X*Jq&+p#WGcJqdGgB6|oT$ZU87?yVwMtO@pbzA)l9 z3V%ftZ3^Z1Lxf>0j?=ThgCr zEymR2|t9sv`IhID!m))@+#QRqF4}`PZ zDJZqOT@({d%G7=jsWp*WAzLn(#kx)X^6btPJ~TI&WQTi;A;ciyRmQC6|6H2GBfZ#^ zYJG$s`#nS?EXn&idS)=PAsMUW*M6wz8!HORTse)$1nqRq{H%AkEIR&dNwUL&!DKZD z(6IwhbGz3%?oIcsC;p}vB(?iyTi7ca8#6NL(pJ4_?^%3NkitV^t0EVZ5#Vk+($+T8 z&jD$mWe}ufm`7rRKtE2#i1^}s-k!_%C&eul6JbNB1VuhmPZ}vH5T*jbpJdeKtfR2m zmYn#AZ$>#GKbeD-hb)PC`I@3K2g{HWT)c{~UX@-wS-E~@FTZn$Hkk}j$Wt!f4TJSX z9t1OX8~?9Qm!QpM5g!&|4Hi5jPW|R;)2H(>O*Ge{0*$8Rf>Y+-pcV;q8m#KJWibh< zChO1iSG!YK>;Ye+Ff=wGnj3D^`E=^#4;fB32yDv{`oskEHWB|1qdU5Wx}y zjuAcLntrF=IABV6JkjucLz`K#(^1@RI$^oh0CP8SaFj3l$+do;}|)br$kc!?8d5BIxCjrRO3AchdKM8J=*rShL!~DUPOza z^1C=Hu!7Y3TSb5^btTf0b4x9n4&j*xIBC|0W2GCAFik~O@8}t%uQ}Qt)6BmMm&mcU zwd50TAnOOZ(Xz zE#nI`ZU`w76bOk%#UN*9pb|Gb#9C?U=ZV6{)H54@`(?~s&9d5OI;~*&=XZ6M2*250 z;29xw|75ldl`n1yeM6$f6e*gE&-9~Z6*)fpMSe7qCeV!}+LV-xln8HQn~6!c@>}m; z*;a`YyiaY3MKiSH9f48=(vvqAzhE8i?kqpfL>0S>`sM z#67gy2MS;$C$ke#L%9f8=wrw@aTS0QuoO$kR+NxJCfH)ZW1bpvmsgOKtzIpQ9es#P zrjDmJ)n+{BoYF1J;7_H5E>U3T_d_>yracsJa~;3I84dVlX9YGEsbb0c?;6U~Y=un2 zF|7SGoTFz+vl<-wdv}b^faCpO_b;SLWaWO)=WF%Y;mh-7qu-_);nxbNVh@QH>5bg6 z302=$ha!zTHt`A*dI0c>Q>8xx^R(h!O6y{X$8TEgCG@J)z#)+Sm*ffJc-ONPqh{Z^ zNwM*fagk)=cLN8y!?@ComKu%-c`?Eepx^;`0uv&pF1z(Q|Dy*Qk)wQRR{@7OIyt@F zVd?7jE7_TS=aX-`yedv*z;Z%%5%~GJ*ucO6RA+UEfW?OPA`hUX(lKvk8-a%uyAe1@ z`}#J#;b%9q&7=K|2~46&8v<#P$LjoH>pvEgGY|>YJ_HEyOBs%SVokOQ2Re!4v zOOO&AIy5kFwbpzg-f)FNs8Av)WX+OOP*knU3M`e)gXw<>@vaw> zFQXY-gwOFe;O&YXjJxwmm{be|a=pM@+3GIi9_Uhjt^WIOF`TvX^Vq@m&R%h3u%1a{ z|GVx~W0SzTB0tZpE>!=OKTV)WSnmb0DJxr&-I_Ao1XfD071+=(RUR^lX(}WBElBNX zHJAsRapd|;#6r)Kh0^+oGX_&t7Id@wu&~2z}naWBNpuwDQCtrjYu#XS)JRO(X*7U^I`3^)=(d zp-2CJQC~GOu_tJab{pZq%f?rysWa}W0Ju^&a<#-1Z(Cb3@j>( z4gb{X7GTInE5UCc!+h|m*>a~E=`2P#Fb|E)Z}W)G*0ot>1%*6+H*Y5<1#I^8_$(o& zE+vx?>f=DCYY)2<)Y+984jFcR6xeloC3QDmUJ|XV*4z~6Ac+Y)#d?2^enB#p_UCX^ zI9Veri*gTEV~R%m+Qk+{yXJgv7Oq7RB5Tc1Z!W41P^|~M2*2y^qf3@Z1dT0rFsKj` zSYgxlrNHq;kr_#bp1hkOaPPH=qz~g*R@( z;nBZNO-UoO#Zq=5jHV^c>G)Uv%(KgP0I#tSf&K+f&trt543COyq_82uXB$`)#BhzX z4#JDP|DEdQnrfS>>K<$iE|gLRN>Ye+nF+1-39nne$)wcaFtb4eJ>Bry z#A{(c=_5|^!x$-;#$~a|OYzdqK{oGK$chL$fu8AqFM>ctHQ7-^sT>30yXBwhdLM}p z$B+1uG|DRUji|e@=y*5SkDc5Sb?eFV^{=*wj^GMTl_CU27GUq!vooigKaq}Wo^w+y zkN#*f=F>i33_bs(mK-cC8=Ec0HwjkmPhvFOeQa)y1E*@_kBdLAUa0enw*U@-^xEK1 z9%2hx^ zhJ+>vuJZw^-`t~3sSp<7yEOS#h37hCa|`NP4HUmU#7oS+l_@(HBc&y+8p%}7*FpNP zNcFXfYdy7{!*8p-_QQ>tT;UI2CV_nYphITRf8V(e;G;HI%Lmq82x}%$G~8)??*8lw zD;?rY_1ZM=2-yW- zh!%#pkUc)!g_XptX z25w^9{pH-Erv4}^9jCD&iAZ>(EG?k*7C3gu4{x}Nq0xvxImuZW&vW)dM6KZjMU)WI z-6`(M#GJ1ThE~8-WuH%D`kh9*-yRoJ7S-5a+a*UMQDAra!agTZ2tN>GCDaJyzIGiA zArDqkcNyg<$8JuYXc1dF0OORTL=i}KsoT>de%&OfQx5!q}Zn%>{( zkuRdrYW8Lyju{e{1m&WWU4B_saJ}2aVX|#|04(u!~TUTN54W){Ml_k~F&{-ZX~_BE7h zf4~14D^VE+9a97v!9qwe$_4K&Ra8DSmiw(!`tBHOJd1HR>twAVi-~8rGcIW*6h$UF zyDTs=nl0D4NP#f%I*L)e$-dq@`FM+Ibe38I^p~w26_}5mmgMhGNoz*)KbXOMyb6kR z5#T&sUiwB_uh4OS+Ya6?w(U}DdG=oG23AIz>GP(fc{#IM*9OxFvcuYsO6c9i$`BjD-65TV4to~ z`@1@Pqh5*!Gj5$tjr;oCCl<# z;61_UnA}jj<@Y;)NU+wf%RWlcw&gCkvmro0$e z(qh7DuKQ6>fGtLh2Bj#HC^_qvtnrFIOvY6&*r8%7<|d#JK~tOO9&<=_dCmY1 zq1F3oJsA3F(>Hvl=s8BfBsqFJ0bq`?;9#0(goPdwO=_={@a-~BZn|E3d zab}(Y`v$uc=Sp24Pl#RQSO6yNpDu>8#keYc$^s^|#{-6(T1q?-R4E*cA9QqeZh6bi zg;0|wfsgsp>pR)r`XM5R(!A#@kJ-W)qN0+h$9+(g`&Fe80y>Lds9&L5es<&j)>Uuo zcg?VhIEe(_sM4vfo@>HxQ6r1?$$Z#U4lTGMF(&)4Oim7M!T`<>++RAyn9QVTQQ`2* z^8o5st7~<1@UwP-@m!%~+N6G2g}QA%4X>Ua^kp3qq#5%GU%$#tQRSx|YsHtHcx(=9 zm9dnFo*=J<@dx1p|0Vmlp=AxOB=9lA+`%)lQ3%TJaFi*dzN-02HNwtRF!BEDrz;0| z9U`1S+At%DurwB`dikGHudCW3zB${cBFMOZP6zu!_tVk4!)aWY({ko2vmrt3P~eLA z`SaV~>Fo{6Rgi7(Lm=?&NdJgMljxdiklG(pab|L{aa=4XGa*BPyOJ!&u@Xm9R*%3V zvoJTGOT7IUAFFZPkQmxRY2Q~Zk5{d>_<7gGpZi8-yI0Z*In#p_E&(5NG%lO5bZTQM zfLTYXFnqwMAOWB(i4d5>O)wv>naE!<^`n+@WFwYMTGPu5{Dy>uKJGil?s-Tut4W@A z8!9t96z=1rxO=m)K?SBWcO-x4oaJBz%mW)EQhyP7Q zcx7;jO|Bcco&un{uPd*GJKFxv>e&%TeVn)EJiHyyE}F~^UB($*9frGFfl-Cj4%LC{ z_jLq7>G5>R(#)%3b#zbnH; z(I#*;Q-_XFll4S@Jyh{$bKYs`Rb|C3>W{$`JOB;=w9MJoOvAF~TE}H3lpg(9LL&?7 z^Pj9OV4R|g%6YFB=27g&x!Sfk_v<1>v=xjzhr|Xc;DsbTlZPFwt|&cRTt;?;+ZLQz5Zv{BUuX(`-EXK+!RGW;!ZHN-lzx@8=$aBum_gYbm>yyH{^}T6i2CqAMXaM zywAeEKLZ?|?FzPb*_4u+yfY?n(MdjV8QhA@-F(3rjEFdm^oSjSMR(SNJb{V_8CuQ| z&)$@}hUcr|E;aSa4t1r*lnDv+hMn%%Al4k~*U(FYuEQyB>;^d|J^CVC5uFazl$0Ol zKk;s1jH&)wmX{Q6%}fxC-dQ)0_?w6t>*thdfk4WT(HUjm^4_0`6;t~DK;`?ZLZCH1 z@3Kl^)SaIAAwbfwRvFT@Hs{$FkNCW>H6FBTmla0NPx6_Jz59H=ePXs|SvFHOzqCHDd8I${lEJc_!sn2fFSB24#1E`~kz0``F$Qvtk%jVz)Bl!#0D7G1_F=m0E&tnwi%z(K{wf3zJy0h(V4#RdeveYK%%jsDqM;BxE@M;{6Vpw7z)G?C3pL*KJ z=h?w=B^eD-_OUgob{k7guhh*BpDP01V(JU!eY`E%)P+GxN#>^Xf3sH_3OZ*TBsFWw zb-*Dui0=B(dWD{;OrdNo_9LF%hRS#zM;Xf(Z10=sHT65+GaP&U0bD^Zq8Z3ULzeI0 z;gFG*ivrHGse$TbA>8ZU!D9$TqVKhW$!zjlk9&S^1stgrsBVt$a5>udUTtJPH8GhA zsN3e|=9XC$mewG~3=h5vKaMv{kCCjXR7WYL(R~dT{%?atXdZQ^%{)aW!`Ui>$_#Gx zx@r%ryW=-**cCq(S!@BN)D$zfFIMkG^VO>~2WFV!n-As%xqkU4^S@l{#(dKgVL`PG z#)^cA8C<15_SQdfrANyvDdJKSa@Q~#-os%dk^x|)a{8|f+fVJhUGX9)Xe@cYN^^wu z_Vj)17@UvF#_`lijah3Rz(1MWaX#ILi|$jFTTj>>94Kzb$N`iW6a71c?$g8>s zA19Ly2gnpd`FHaDJCeF2E|)DG2gpQJOQ&5+VCv6o{?F{<^KTU-knUQr!o5h(83r6_ zLqvl2G|WO(=88Tu@m6OBlYqVci@ZWu)}CBKVUPqNR2a~FcDO}ukSe;1w_>}FiQ}OH z>E9=cr#O{@eQdF^O!0LoIW7VMV%Y5r?P679bwx$DlgaU9DWYBn%We^K(3*0a)kCgehPMH3Jm)5;I^wRS!pO3mMZbaQ!0fdO~rQW z2dk6}R8{Q3bEFb81vY&JM{pS@nsK=BfBqs|+Lq-wq44V0ua+kZ!S*Y(oOU8jwu(>B z^Ir?4-{Z_q*TiMcaeeslHOqaqTx*!b~Zt7Qt_MUJqwkBy$8*yfC9*W&Z} zf8h&~R@AJj`aYfT%o9`aHyPEaPWTX~)n#LKNo1Lb3AqCV7g`?#Y#XLcE;}PG-8PDN z(hig~LbBV4`S6}MQDJe)rdGP1qnT{CS1y&ZySzUvbhwmy5R0HTJ#TRPW%C`aSUO6C zkV$XOCGmL6=}*gie6IrE_!4lQ>bL2&`Zl(Nyg>k5A{+!C{V$UJcb7a%O{^XJ{Fn#< zA7&miz>588ESz4?$>;&9d%Q%p&LcIJ26MVlLeCyo@?|w+`x(=*YbwQyg2G;eNkw_GIlGR;;lEbvs0gL@bF}+ zb>^PsX*)846G-lFOeTk=dGCMP)!17i%>D_-Kc4bt8@-L8BaBtMSf{MfS-Y-<{UaK1 zH+SCp^Zh6c?r83a)XEiMU6DKuolFY;-Bn4bb-5`)F}K@;!NX=?D9O-J;FdYnq%6*) zZi3B~zSX(z9(dqn%##+NnpLe*K|x&lat!dAPcpC8@V+ifc480mb`wsViJDakColF<3!nu_Ts(4Ua-HGN)8!RHEau%m~7Q?f7xs@Exlzr^>)wsnIspjjkw zogo4{soBB5;|Ge>D;2_3qKfonWxI%cWQaMouarJ~x;i=L=NYk&**<8AsyJM>MQd}| zWqaNQ5E4q)o#R2O64jKu2EN_Krt<3*KbJfsr#>B>%uy0>xq%(N2WKG0;JI+#)MNOL z>yO#?xeNXGtDq^q_K`$&J94`XvG?@_++G&wc4*ek6%7bhN#wG~hef(Qsx}QZXRi+3 zi3kdoNXWBZ)2aR=u5pQMvB_#a5fb#O7*8L*zu(SB%Utv3F`u7q)jHDpQ;H8})$;@# zM`1K~el7!#KZt_+yApDl^hKp~YhM3yUs}Kp=oe2PT(D(~h6$)A9J+Ay0JKjn(piSis15_F<*lB;?pPh-jiHEUg{olV# zwS_Vbwcjy1jjkF@_B_l&olXa*3x(;q8kLU7euAN4`CHN@1vDXCW{3}AifX7IWG{VC z;(!=QAmnzmdQkhp_l?VmUJlC!=nr@b#8!VszLy08Tt*h^rR$6No%|Ps#~bL*U>Gx;kbbOR&naJHX~8R~nR(>p~4X zj%#Xh#BQ>QKnrggw%q$BEt!u?%}x-=s1r2!l#VV}%wACQec_w;UXB+0{BU()+u#%( zW3XoT;|C4P!5pFH!ph0=lau2<8xs-Ea}Q2SrKsJ83c~7s5vIJLq3-~dx>G7ihGW0D z*#GX%yXac5XmrI${wF(qh2wp2Vvc~g#g?P{n}m8yA7}1GLhXlYwLzi2uw`Ig5Yd)1 zzF*3DGlNv|Y@lvr9Y7&^cYk_)s!|A88KW{#N4?%rlyG9uF9ev5aX?Q92ox~$yy-W+ zSj2r&D^hDi_-Za5=oaY!e{7XZTe>zu$i1r8h@H;!t6IepnzV;s&)LBM1p2a)0H_MP zmh|EfV;Bl|^;N5th6|T8T_kM%Ww>`Oh4SXxbJ)k<2rK^sR5%q2$1*`!}H+h=Wh&6wRiS`UwZRT!nHtwQ3EU3R|MW|6TjIeo2<}B7Q0sl6#x|!`dgDsjUMBT2w`a!CUI0 z*NY3!XPb0GLt>CYcaXvQ?Pfk8Fhx*6js;4H;)A&`|7sQ2)x~{Hl+#Qk0Q7Vl-v3!0 z$S;pV(bB8*bSVcj2a5gxgsO+4*3 zu)FP|-S53W1JUnT!2f=;8ax@3RH*oqoKWu-2i>3*SelN@YBdOfek~OZ**~e&u+1g% z+qdu`zTCV)V($rSxOFKj<1}cE6XHZ3rt&y}X%Y-RiaP?lw@0h$XQB&cin!NZ~kR zvQW%&Sz&#|QThXJvedD8GedkruN6i74 zo-b}NAYZ-r6F?gPXn8c~@d6|kd3*f(o9FSl%%2P(Kfub#ujnyiO7wO#HA{M;HYW_?RMG!J+yD%>k|7cqYKo_Ry;2N literal 42262 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 diff --git a/vector/v.type/v.type.html b/vector/v.type/v.type.html index 8e6d5806db8..124f8f39fe0 100644 --- a/vector/v.type/v.type.html +++ b/vector/v.type/v.type.html @@ -2,6 +2,27 @@

DESCRIPTION

v.type changes the type of geometry primitives. +

+The following vector object types are defined in GRASS GIS: + +

    +
  • point: a point;
  • +
  • line: a directed sequence of connected vertices with two endpoints called nodes;
  • +
  • boundary: the border line describing an area;
  • +
  • centroid: a point within a closed ring of boundaries;
  • +
  • area: the topological composition of a closed ring of boundaries and a centroid;
  • +
  • face: a 3D area;
  • +
  • kernel: a 3D centroid in a volume (not yet implemented);
  • +
  • volume: a 3D corpus, the topological composition of faces and kernel (not yet implemented).
  • +
+

+Lines and boundaries can be composed of multiple vertices. +

+Area topology also holds information about isles. These isles are located +within that area, not touching the boundaries of the outer area. Isles +are holes inside the area, and can consist of one or more areas. They are +used internally to maintain correct topology for areas. +

EXAMPLES

Convert lines to area boundaries
From 3a95b7a4e6412510d64b4a36a0a18bd7e7843d31 Mon Sep 17 00:00:00 2001 From: Mohan Yelugoti Date: Fri, 11 Oct 2024 02:32:11 -0400 Subject: [PATCH 03/69] raster/raster3d: Initialize Cell_head structure contents before use --- raster/r.in.lidar/main.c | 6 +++--- raster/r.in.pdal/main.cpp | 6 +++--- raster/r.in.xyz/main.c | 2 +- raster3d/r3.in.lidar/main.c | 7 +++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/raster/r.in.lidar/main.c b/raster/r.in.lidar/main.c index 68d3a0fcd1b..96f562167b6 100644 --- a/raster/r.in.lidar/main.c +++ b/raster/r.in.lidar/main.c @@ -51,8 +51,8 @@ int main(int argc, char *argv[]) struct PointBinning point_binning; void *base_array; void *raster_row; - struct Cell_head region; - struct Cell_head input_region; + struct Cell_head region = {0}; + struct Cell_head input_region = {0}; int rows, last_rows, row0, cols; /* scan box size */ int row; /* counters */ @@ -100,7 +100,7 @@ int main(int argc, char *argv[]) int return_filter; const char *projstr; - struct Cell_head cellhd, loc_wind; + struct Cell_head cellhd = {0}, loc_wind = {0}; unsigned int n_filtered; diff --git a/raster/r.in.pdal/main.cpp b/raster/r.in.pdal/main.cpp index da32dcb5484..36d09558eea 100644 --- a/raster/r.in.pdal/main.cpp +++ b/raster/r.in.pdal/main.cpp @@ -69,8 +69,8 @@ int main(int argc, char *argv[]) SEGMENT base_segment; struct PointBinning point_binning; void *raster_row; - struct Cell_head region; - struct Cell_head input_region; + struct Cell_head region = {}; + struct Cell_head input_region = {}; int rows, cols; /* scan box size */ char buff[BUFFSIZE]; @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) bin_index_nodes.max_nodes = 0; bin_index_nodes.nodes = NULL; - struct Cell_head loc_wind; + struct Cell_head loc_wind = {}; G_gisinit(argv[0]); diff --git a/raster/r.in.xyz/main.c b/raster/r.in.xyz/main.c index a4c7dfde6ed..b3c3fb380cf 100644 --- a/raster/r.in.xyz/main.c +++ b/raster/r.in.xyz/main.c @@ -112,7 +112,7 @@ int main(int argc, char *argv[]) char *n_array, *min_array, *max_array, *sum_array, *sumsq_array, *index_array; void *raster_row, *ptr; - struct Cell_head region; + struct Cell_head region = {0}; int rows, last_rows, row0, cols; /* scan box size */ int row, col; /* counters */ diff --git a/raster3d/r3.in.lidar/main.c b/raster3d/r3.in.lidar/main.c index 6170a3f50ba..3cf91189d24 100644 --- a/raster3d/r3.in.lidar/main.c +++ b/raster3d/r3.in.lidar/main.c @@ -361,13 +361,12 @@ int main(int argc, char *argv[]) /* for the CRS info */ const char *projstr; - struct Cell_head current_region; - struct Cell_head file_region; - + struct Cell_head current_region = {0}; + struct Cell_head file_region = {0}; G_get_set_window(¤t_region); /* extent for all data */ - struct Cell_head data_region; + struct Cell_head data_region = {0}; long unsigned header_count = 0; int i; From b9a6b6883899e7611a2d65b63a1c02d6a50d59e4 Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Fri, 11 Oct 2024 10:21:22 -0400 Subject: [PATCH 04/69] doc: Use lowercase for 2D raster mask (#4401) On many places (more than covered here), 2D raster mask is called MASK conflating the concept (mask) and the implementation (MASK raster). Users using the r.mask tool may not interact with the underlying raster directly, so there is no reason to use MASK over mask. This is changing MASK to mask and modifies related wording. However, this is also leaving many places as they are with MASK. Some will be better revisited with or after #2390 and #2392 when a more comprehensive solution is available. This fixes and keeps in sync wording in r.null and r.external, and moves r.circle comment documenting the interface to a flag description. --- display/d.histogram/d.histogram.html | 2 +- raster/r.circle/main.c | 6 ++++-- raster/r.external/r.external.html | 8 +++++--- raster/r.null/r.null.html | 10 ++++++---- raster/r.stream.extract/r.stream.extract.html | 4 +++- raster3d/raster3dintro.html | 2 +- scripts/r.out.xyz/r.out.xyz.html | 2 +- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/display/d.histogram/d.histogram.html b/display/d.histogram/d.histogram.html index 6e99c940290..43cca2d7223 100644 --- a/display/d.histogram/d.histogram.html +++ b/display/d.histogram/d.histogram.html @@ -10,7 +10,7 @@

DESCRIPTION

NOTES

d.histogram respects the current geographic region settings -and the current MASK (if one exists). +and the current raster mask (if mask is active).

d.histogram uses the colors in the map's color look-up table (i.e., the map's colr or colr2 file). diff --git a/raster/r.circle/main.c b/raster/r.circle/main.c index 4b41a78c7c6..bd99a292f71 100644 --- a/raster/r.circle/main.c +++ b/raster/r.circle/main.c @@ -79,7 +79,9 @@ int main(int argc, char *argv[]) flag = G_define_flag(); flag->key = 'b'; - flag->description = _("Generate binary raster map"); + flag->label = _("Generate binary raster map"); + flag->description = + _("Generate binary pattern only (useful for creating mask)"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); @@ -114,7 +116,7 @@ int main(int argc, char *argv[]) "using the binary flag")); if (flag->answer) - binary = 1; /* generate binary pattern only, useful for MASK */ + binary = 1; else binary = 0; diff --git a/raster/r.external/r.external.html b/raster/r.external/r.external.html index 797cc5ea605..f20c3e059d6 100644 --- a/raster/r.external/r.external.html +++ b/raster/r.external/r.external.html @@ -17,10 +17,12 @@

NULL data handling

NULL cells are those whose value matches the value reported by the GDALGetRasterNoDataValue() function. -To apply the GDAL-linked the user need to either create a MASK (e.g. -with r.mask) and then "apply" it using e.g. r.resample, +

+To introduce additional NULL values to a computation based on a GDAL-linked +raster, the user needs to either create a mask with with r.mask and +then "apply" it using e.g. r.resample or r.mapcalc, or use r.mapcalc to create a copy with the appropriate categories -changed to NULL (if() condition). +changed to NULL (if() condition).

EXAMPLES

diff --git a/raster/r.null/r.null.html b/raster/r.null/r.null.html index 0a98907af5f..4d92b027d65 100644 --- a/raster/r.null/r.null.html +++ b/raster/r.null/r.null.html @@ -49,10 +49,12 @@

External maps

From the r.external documentation: GDAL-linked (r.external) maps do not have or use a NULL bitmap, hence r.null cannot manipulate them directly. Here NULL cells are those whose value matches -the value reported by the GDALGetRasterNoDataValue() function. To apply the -GDAL-linked the user need to either create a MASK (e.g. with r.mask) and -then "apply" it using e.g. r.resample, or use r.mapcalc to create a copy -with the appropriate categories changed to NULL (if() condition). +the value reported by the GDALGetRasterNoDataValue() function. +To introduce additional NULL values to a computation based on a GDAL-linked +raster, the user needs to either create a mask with with r.mask and +then "apply" it using e.g. r.resample or r.mapcalc, +or use r.mapcalc to create a copy with the appropriate categories +changed to NULL (if() condition).

EXAMPLES

diff --git a/raster/r.stream.extract/r.stream.extract.html b/raster/r.stream.extract/r.stream.extract.html index e1c427599e8..22877936c93 100644 --- a/raster/r.stream.extract/r.stream.extract.html +++ b/raster/r.stream.extract/r.stream.extract.html @@ -126,7 +126,9 @@

Defining a region of interest

The stream extraction procedure can be restricted to a certain region of interest, e.g. a subbasin, by setting the computational region with -g.region and/or creating a MASK. Such region of interest should +g.region and/or creating a mask +with r.mask. +Such region of interest should be a complete catchment area, complete in the sense that the complete area upstream of an outlet point is included and buffered with at least one cell. diff --git a/raster3d/raster3dintro.html b/raster3d/raster3dintro.html index ac476b974b2..b51748b4dd8 100644 --- a/raster3d/raster3dintro.html +++ b/raster3d/raster3dintro.html @@ -115,7 +115,7 @@

Conversion from 2D raster maps

2D rasters are considered as slices in this case and merged into one 3D raster map (r.to.rast3). -

3D region settings and 3D MASK

+

3D region settings and 3D mask

GRASS GIS 3D raster map processing is always performed in the current 3D region settings (see g.region, -p3 flags), i.e. diff --git a/scripts/r.out.xyz/r.out.xyz.html b/scripts/r.out.xyz/r.out.xyz.html index c9b2b6510be..e603c592e32 100644 --- a/scripts/r.out.xyz/r.out.xyz.html +++ b/scripts/r.out.xyz/r.out.xyz.html @@ -6,7 +6,7 @@

DESCRIPTION

NOTES

This module will by default not export x,y coordinates for raster cells -containing a NULL value. This includes cells masked by a raster MASK. +containing a NULL value. This includes cells masked by a raster mask. Using the flag -i also these raster cells will be included in the exported data.

From 2e0a8fa3359d062472fdf1a915be55f355e469d3 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 11 Oct 2024 10:48:51 -0400 Subject: [PATCH 05/69] tools: FIxed unused variable in imagery/ (#4487) fixed 821 --- .flake8 | 1 - imagery/i.atcorr/create_iwave.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index 313241f2d9d..1f5f4c9c040 100644 --- a/.flake8 +++ b/.flake8 @@ -21,7 +21,6 @@ per-file-ignores = # E741 ambiguous variable name 'l' __init__.py: F401, F403 man/build_html.py: E501 - imagery/i.atcorr/create_iwave.py: F632, F821, W293 doc/python/m.distance.py: E501 doc/gui/wxpython/example/dialogs.py: F401 gui/scripts/d.wms.py: E501 diff --git a/imagery/i.atcorr/create_iwave.py b/imagery/i.atcorr/create_iwave.py index a575d8089cd..21faa21ac2c 100644 --- a/imagery/i.atcorr/create_iwave.py +++ b/imagery/i.atcorr/create_iwave.py @@ -235,7 +235,7 @@ def write_cpp(bands, values, sensor, folder): while c < len(fi) - 1 and fi[c + 1] > rthresh: c += 1 max_wavelength = np.floor(li[0] * 1000 + (2.5 * c)) - print(" %s (%inm - %inm)" % (bands[b], min_wavelength, max_wavelength)) + print(" %s (%inm - %inm)" % (bands[0], min_wavelength, max_wavelength)) else: filter_f = [] From 21606ad863060c018e8b1b26f0fef4f693ae97da Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 11 Oct 2024 10:50:31 -0400 Subject: [PATCH 06/69] doc: Ignore F401 in dialogs.py (#4488) dialogs.py has an instance of F401 error for unused import of grass library. However as mentioned in the comment and post discussion with @wenzeslaus I decided it would be better to ignore this error for now in case it breaks any underlying dependencies regarding gettext.install() --- .flake8 | 1 - doc/gui/wxpython/example/dialogs.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index 1f5f4c9c040..f0c1f634e81 100644 --- a/.flake8 +++ b/.flake8 @@ -22,7 +22,6 @@ per-file-ignores = __init__.py: F401, F403 man/build_html.py: E501 doc/python/m.distance.py: E501 - doc/gui/wxpython/example/dialogs.py: F401 gui/scripts/d.wms.py: E501 gui/wxpython/image2target/*: F841, E722 gui/wxpython/image2target/g.gui.image2target.py: E501, F841 diff --git a/doc/gui/wxpython/example/dialogs.py b/doc/gui/wxpython/example/dialogs.py index 425ea57a4b2..98760e7202d 100644 --- a/doc/gui/wxpython/example/dialogs.py +++ b/doc/gui/wxpython/example/dialogs.py @@ -20,7 +20,7 @@ # So we need to import it before any of the GUI code. # NOTE: in this particular case, we don't really need the grass library; # NOTE: we import it just for the side effects of gettext.install() -import grass +import grass # noqa: F401 from core import globalvar from gui_core.dialogs import SimpleDialog From 426bf742123680c4067ab930a758cdb1ddbc9624 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 11 Oct 2024 10:51:20 -0400 Subject: [PATCH 07/69] checks: update .flake8 to reflect correct status in image2target (#4489) --- .flake8 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index f0c1f634e81..c01dc46b255 100644 --- a/.flake8 +++ b/.flake8 @@ -23,8 +23,7 @@ per-file-ignores = man/build_html.py: E501 doc/python/m.distance.py: E501 gui/scripts/d.wms.py: E501 - gui/wxpython/image2target/*: F841, E722 - gui/wxpython/image2target/g.gui.image2target.py: E501, F841 + gui/wxpython/image2target/g.gui.image2target.py: E501 gui/wxpython/modules/*: F841, E722 gui/wxpython/nviz/*: F841, E266, E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 From cbc3ff4f349d258b875a23ce2c8a92f069a79226 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 11 Oct 2024 10:51:40 -0400 Subject: [PATCH 08/69] wxGUI: FIxed F841 in colorrules.py (#4490) --- gui/wxpython/modules/colorrules.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index cad74f38c4b..3dfdde8c42b 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -318,7 +318,9 @@ def LoadRules(self): int, self.ruleslines[item][self.attributeType].split(":") ) except ValueError as e: - message = _("Bad color format. Use color format '0:0:0'") + message = ( + _("Bad color format '%s'. Use color format '0:0:0'") % e + ) self.mainPanel.FindWindowById(item + 2000).SetValue((r, g, b)) else: value = float(self.ruleslines[item][self.attributeType]) @@ -410,7 +412,6 @@ def _initLayer(self): if layer: mapLayer = self.layerTree.GetLayerInfo(layer, key="maplayer") name = mapLayer.GetName() - type = mapLayer.GetType() self.selectionInput.SetValue(name) self.inmap = name @@ -1412,7 +1413,7 @@ def AddTemporaryColumn(self, type): modul = "v.db.addcolumn" else: modul = "v.db.addcol" - ret = RunCommand( + RunCommand( modul, parent=self, map=self.inmap, @@ -1430,7 +1431,7 @@ def DeleteTemporaryColumn(self): modul = "v.db.dropcolumn" else: modul = "v.db.dropcol" - ret = RunCommand( + RunCommand( modul, map=self.inmap, layer=self.properties["layer"], @@ -1505,7 +1506,7 @@ def OnAddColumn(self, event): modul = "v.db.addcolumn" else: modul = "v.db.addcol" - ret = RunCommand( + RunCommand( modul, map=self.inmap, layer=self.properties["layer"], From 1d42e580e25d62dee5f3e2653f7bcb5241855f71 Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Fri, 11 Oct 2024 16:25:56 -0400 Subject: [PATCH 09/69] r.mask.status: Check mask status through a tool and function (#2390) Instead of using low-level test of file existence with hardcoded raster path and name, this offers a new tool to retrieve status of the raster mask. The new r.mask.status tool reports presence or absence of the 2D raster mask and provides additional details about the mask. There is one usage of this now and that's the one for a shell prompt. The prompt no longer relies on testing the file presence with the test program, but uses a GRASS tool to find out. The code goes out of its way to report both mask name (currently always MASK) and the underlying raster name if it is a reclassified (without rewriting the current C API). This is to mimic the existing C functions which are returning the underlying raster if MASK is a reclass. The tool and the new C API function return both preparing a way for using an arbitrary name for the mask while having the option to look at the underlying reclassified raster map. --- include/grass/defs/raster.h | 1 + lib/init/grass.py | 2 +- lib/raster/mask_info.c | 120 +++++++++--- raster/Makefile | 1 + raster/r.mask.status/Makefile | 10 + raster/r.mask.status/main.c | 184 ++++++++++++++++++ raster/r.mask.status/r.mask.status.html | 65 +++++++ raster/r.mask.status/tests/conftest.py | 25 +++ .../r.mask.status/tests/r_mask_status_test.py | 126 ++++++++++++ 9 files changed, 507 insertions(+), 27 deletions(-) create mode 100644 raster/r.mask.status/Makefile create mode 100644 raster/r.mask.status/main.c create mode 100644 raster/r.mask.status/r.mask.status.html create mode 100644 raster/r.mask.status/tests/conftest.py create mode 100644 raster/r.mask.status/tests/r_mask_status_test.py diff --git a/include/grass/defs/raster.h b/include/grass/defs/raster.h index c2d26ccdccc..7f358562c72 100644 --- a/include/grass/defs/raster.h +++ b/include/grass/defs/raster.h @@ -392,6 +392,7 @@ int Rast_option_to_interp_type(const struct Option *); /* mask_info.c */ char *Rast_mask_info(void); +bool Rast_mask_status(char *, char *, bool *, char *, char *); int Rast__mask_info(char *, char *); bool Rast_mask_is_present(void); diff --git a/lib/init/grass.py b/lib/init/grass.py index f489ad1fe53..d2d8301c52b 100755 --- a/lib/init/grass.py +++ b/lib/init/grass.py @@ -1667,8 +1667,8 @@ def sh_like_startup(location, location_name, grass_env_file, sh): ) ) + mask2d_test = "r.mask.status -t" # TODO: have a function and/or module to test this - mask2d_test = 'test -f "$MAPSET_PATH/cell/MASK"' mask3d_test = 'test -d "$MAPSET_PATH/grid3/RASTER3D_MASK"' specific_addition = "" diff --git a/lib/raster/mask_info.c b/lib/raster/mask_info.c index 1a11da972f8..42102de86dd 100644 --- a/lib/raster/mask_info.c +++ b/lib/raster/mask_info.c @@ -1,30 +1,17 @@ -/* - ************************************************************* - * char * Rast_mask_info () - * - * returns a printable text of mask information - * - ************************************************************ - * Rast__mask_info (name, mapset) - * - * char name[GNAME_MAX], mapset[GMAPSET_MAX]; - * - * function: - * determine the status off the automatic masking - * and the name of the cell file which forms the mask +/** + * \file lib/raster/mask_info.c * - * (the mask file is actually MASK in the current mapset, - * but is usually a reclassed cell file, and the reclass - * name and mapset are returned) + * \brief Raster Library - Get mask information * - * returns: - * -1 no masking (name, mapset undefined) - * name, mapset are undefined + * (C) 1999-2024 by Vaclav Petras and the GRASS Development Team * - * 1 mask file present, masking on - * name, mapset hold mask file name, mapset + * This program is free software under the GNU General Public + * License (>=v2). Read the file COPYING that comes with GRASS + * for details. * - ***************************************************************/ + * \author CERL + * \author Vaclav Petras, NC State University, Center for Geospatial Analytics + */ #include @@ -32,6 +19,15 @@ #include #include +/** + * @brief Get a printable text with information about raster mask + * + * Determines if 2D raster mask is present and returns textual information about + * the mask suitable for end-user display. The resulting text is translated. + * Caller is responsible for freeing the memory of the returned string. + * + * @return New string with textual information + */ char *Rast_mask_info(void) { char text[GNAME_MAX + GMAPSET_MAX + 16]; @@ -53,16 +49,88 @@ char *Rast_mask_info(void) return G_store(text); } +/** + * @brief Get raster mask status information + * + * _is_mask_reclass_ is a pointer to a bool variable which + * will be set to true if mask raster is a reclass and false otherwise. + * + * If you are not interested in the underlying reclassified raster map, + * pass NULL pointers for the three reclass parameters: + * + * ``` + * Rast_mask_status(name, mapset, NULL, NULL, NULL); + * ``` + * + * @param[out] name Name of the raster map used as mask + * @param[out] mapset Name of the mapset the raster is in + * @param[out] is_mask_reclass Will be set to true if mask raster is a reclass + * @param[out] reclass_name Name of the underlying reclassified raster map + * @param[out] reclass_mapset Name of the mapset the reclassified raster is in + * + * @return true if mask is present, false otherwise + */ +bool Rast_mask_status(char *name, char *mapset, bool *is_mask_reclass, + char *reclass_name, char *reclass_mapset) +{ + int present = Rast__mask_info(name, mapset); + + if (is_mask_reclass && reclass_name && reclass_mapset) { + if (present) { + *is_mask_reclass = Rast_is_reclass("MASK", G_mapset(), reclass_name, + reclass_mapset) > 0; + if (*is_mask_reclass) { + // The original mask values were overwritten in the initial + // info call. Put back the original values, so that we can + // report them to the caller. + strcpy(name, "MASK"); + strcpy(mapset, G_mapset()); + } + } + else { + *is_mask_reclass = false; + } + } + + if (present == 1) + return true; + else + return false; +} + +/** + * @brief Get information about the current mask + * + * Determines the status of the automatic masking and the name of the 2D + * raster which forms the mask. Typically, mask is raster called MASK in the + * current mapset, but when used with r.mask, it is usually a reclassed + * raster, and so when a MASK raster is present and it is a reclass raster, + * the name and mapset of the underlying reclassed raster are returned. + * + * The name and mapset is written to the parameter which need to be defined + * with a sufficient size, least as `char name[GNAME_MAX], mapset[GMAPSET_MAX]`. + * + * When the masking is not active, -1 is returned and name and mapset are + * undefined. When the masking is active, 1 is returned and name and mapset + * will hold the name and mapset of the underlying raster. + * + * @param[out] name Name of the raster map used as mask + * @param[out] mapset Name of the map's mapset + * + * @return 1 if mask is present, -1 otherwise + */ int Rast__mask_info(char *name, char *mapset) { char rname[GNAME_MAX], rmapset[GMAPSET_MAX]; - strcpy(name, "MASK"); - strcpy(mapset, G_mapset()); + strcpy(rname, "MASK"); + strcpy(rmapset, G_mapset()); - if (!G_find_raster(name, mapset)) + if (!G_find_raster(rname, rmapset)) return -1; + strcpy(name, rname); + strcpy(mapset, rmapset); if (Rast_is_reclass(name, mapset, rname, rmapset) > 0) { strcpy(name, rname); strcpy(mapset, rmapset); diff --git a/raster/Makefile b/raster/Makefile index bcd07660238..91ff54d0863 100644 --- a/raster/Makefile +++ b/raster/Makefile @@ -45,6 +45,7 @@ SUBDIRS = \ r.lake \ r.li \ r.mapcalc \ + r.mask.status \ r.mfilter \ r.mode \ r.neighbors \ diff --git a/raster/r.mask.status/Makefile b/raster/r.mask.status/Makefile new file mode 100644 index 00000000000..62c968d044e --- /dev/null +++ b/raster/r.mask.status/Makefile @@ -0,0 +1,10 @@ +MODULE_TOPDIR = ../.. + +PGM = r.mask.status + +LIBES = $(MANAGELIB) $(RASTERLIB) $(GISLIB) $(PARSONLIB) +DEPENDENCIES = $(MANAGEDEP) $(RASTERDEP) $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +default: cmd diff --git a/raster/r.mask.status/main.c b/raster/r.mask.status/main.c new file mode 100644 index 00000000000..5eb32300240 --- /dev/null +++ b/raster/r.mask.status/main.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * + * MODULE: r.mask.status + * AUTHORS: Vaclav Petras + * PURPOSE: Report status of raster mask + * COPYRIGHT: (C) 2024 by Vaclav Petras and the GRASS Development Team + * + * This program is free software under the GNU General Public + * License (>=v2). Read the file COPYING that comes with GRASS + * for details. + * + *****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct Parameters { + struct Option *format; + struct Flag *like_test; +}; + +void parse_parameters(struct Parameters *params, int argc, char **argv) +{ + struct GModule *module; + + module = G_define_module(); + G_add_keyword(_("raster")); + G_add_keyword(_("mask")); + G_add_keyword(_("reclassification")); + module->label = _("Reports presence or absence of a raster mask"); + module->description = + _("Provides information about the presence of a 2D raster mask" + " as text output or return code"); + + params->format = G_define_option(); + params->format->key = "format"; + params->format->type = TYPE_STRING; + params->format->required = NO; + params->format->answer = "plain"; + params->format->options = "plain,json,shell,yaml"; + params->format->descriptions = + "plain;Plain text output;" + "json;JSON (JavaScript Object Notation);" + "shell;Shell script style output;" + "yaml;YAML (human-friendly data serialization language)"; + params->format->description = _("Format for reporting"); + + params->like_test = G_define_flag(); + params->like_test->key = 't'; + params->like_test->label = + _("Return code 0 when mask present, 1 otherwise"); + params->like_test->description = + _("Behave like the test utility, 0 for true, 1 for false, no output"); + // suppress_required is not required given the default value for format. + // Both no parameters and only -t work as expected. + + if (G_parser(argc, argv)) + exit(EXIT_FAILURE); +} + +int report_status(struct Parameters *params) +{ + + char name[GNAME_MAX]; + char mapset[GMAPSET_MAX]; + char reclass_name[GNAME_MAX]; + char reclass_mapset[GMAPSET_MAX]; + + bool is_mask_reclass; + bool present = Rast_mask_status(name, mapset, &is_mask_reclass, + reclass_name, reclass_mapset); + + // This does not have to be exclusive with the printing, but leaving this + // to a different boolean flag which could do the return code and printing. + // The current implementation really behaves like the test utility which + // facilitates the primary usage of this which is prompt building + // (and there any output would be noise). + if (params->like_test->answer) { + if (present) + return 0; + return 1; + } + + // Mask raster + char *full_mask = G_fully_qualified_name(name, mapset); + // Underlying raster if applicable + char *full_underlying = NULL; + if (is_mask_reclass) + full_underlying = G_fully_qualified_name(reclass_name, reclass_mapset); + + if (strcmp(params->format->answer, "json") == 0) { + JSON_Value *root_value = json_value_init_object(); + JSON_Object *root_object = json_object(root_value); + json_object_set_boolean(root_object, "present", present); + if (present) + json_object_set_string(root_object, "full_name", full_mask); + else + json_object_set_null(root_object, "full_name"); + if (is_mask_reclass) + json_object_set_string(root_object, "is_reclass_of", + full_underlying); + else + json_object_set_null(root_object, "is_reclass_of"); + char *serialized_string = json_serialize_to_string_pretty(root_value); + puts(serialized_string); + json_free_serialized_string(serialized_string); + json_value_free(root_value); + } + else if (strcmp(params->format->answer, "shell") == 0) { + printf("present="); + if (present) + printf("1"); + else + printf("0"); + printf("\nfull_name="); + if (present) + printf("%s", full_mask); + printf("\nis_reclass_of="); + if (is_mask_reclass) + printf("%s", full_underlying); + printf("\n"); + } + else if (strcmp(params->format->answer, "yaml") == 0) { + printf("present: "); + if (present) + printf("true"); + else + printf("false"); + printf("\nfull_name: "); + if (present) + printf("|-\n %s", full_mask); + else + printf("null"); + // Null values in YAML can be an empty (no) value (rather than null), + // so we could use that, but using the explicit null as a reasonable + // starting point. + printf("\nis_reclass_of: "); + // Using block scalar with |- to avoid need for escaping. + // Alternatively, we could check mapset naming limits against YAML + // escaping needs for different types of strings and do the necessary + // escaping here. + if (is_mask_reclass) + printf("|-\n %s", full_underlying); + else + printf("null"); + printf("\n"); + } + else { + if (present) + printf(_("Mask is active")); + else + printf(_("Mask is not present")); + if (present) { + printf("\n"); + printf(_("Mask name: %s"), full_mask); + } + if (is_mask_reclass) { + printf("\n"); + printf(_("Mask is a raster reclassified from: %s"), + full_underlying); + } + printf("\n"); + } + + G_free(full_mask); + G_free(full_underlying); + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) +{ + struct Parameters params; + + G_gisinit(argv[0]); + parse_parameters(¶ms, argc, argv); + return report_status(¶ms); +} diff --git a/raster/r.mask.status/r.mask.status.html b/raster/r.mask.status/r.mask.status.html new file mode 100644 index 00000000000..248ee3ea317 --- /dev/null +++ b/raster/r.mask.status/r.mask.status.html @@ -0,0 +1,65 @@ +

DESCRIPTION

+ +The r.mask.status reports information about the 2D raster mask and its +status. If the mask is present, the tool reports a full name of the raster (name +including the mapset) which represents the mask. It can also report full name of +the underlying raster if the mask is reclassified from another raster. + +

+With the -t flag, no output is printed, instead a return code is used to +indicate presence or absence. The convention is the same same the POSIX +test utility, so r.mask.status returns 0 when the mask is +present and 1 otherwise. + +

EXAMPLES

+ +

Generate JSON output

+ +To generate JSON output in Bash, use the format option: + +
+r.mask.status format=json
+
+ +In Python, use: + +
+import grass.script as gs
+gs.parse_command("r.mask.status", format="json")
+
+ +This returns a dictionary with keys present, +full_name, and is_reclass_of. + +

Use as the test utility

+ +The POSIX test utility uses return code 0 to indicate presence +and 1 to indicate absence of a file, so testing existence of a file with +test -f gives return code 0 when the file exists. +r.mask.status can be used in the same with the the -t flag: + +
+r.mask.status -t
+
+ +In a Bash script: + +
+# Bash
+if r.mask.status -t; then
+    echo "Masking is active"
+else
+    echo "Masking is not active"
+fi
+
+ +

SEE ALSO

+ + +r.mask, +g.region + + +

AUTHORS

+ +Vaclav Petras, NC State University, Center for Geospatial Analytics diff --git a/raster/r.mask.status/tests/conftest.py b/raster/r.mask.status/tests/conftest.py new file mode 100644 index 00000000000..e8e27315845 --- /dev/null +++ b/raster/r.mask.status/tests/conftest.py @@ -0,0 +1,25 @@ +"""Fixtures for simple sessions""" + +import os +import pytest +import grass.script as gs + + +@pytest.fixture +def session_no_data(tmp_path): + """Set up a GRASS session for the tests.""" + project = "test_project" + gs.create_project(tmp_path, project) + with gs.setup.init(tmp_path / project, env=os.environ.copy()) as session: + yield session + + +@pytest.fixture +def session_with_data(tmp_path): + """Set up a GRASS session for the tests.""" + project = tmp_path / "test_project" + gs.create_project(project) + with gs.setup.init(project, env=os.environ.copy()) as session: + gs.run_command("g.region", rows=2, cols=2, env=session.env) + gs.mapcalc("a = 1", env=session.env) + yield session diff --git a/raster/r.mask.status/tests/r_mask_status_test.py b/raster/r.mask.status/tests/r_mask_status_test.py new file mode 100644 index 00000000000..deafdfb145b --- /dev/null +++ b/raster/r.mask.status/tests/r_mask_status_test.py @@ -0,0 +1,126 @@ +"""Tests of r.mask.status""" + +import pytest + +try: + import yaml +except ImportError: + yaml = None + +import grass.script as gs + + +def test_json_no_mask(session_no_data): + """Check JSON format for no mask""" + session = session_no_data + data = gs.parse_command("r.mask.status", format="json", env=session.env) + assert "present" in data + assert "full_name" in data + assert "is_reclass_of" in data + assert data["present"] is False + assert not data["full_name"] + assert not data["is_reclass_of"] + + +def test_json_with_r_mask(session_with_data): + """Check JSON format for the r.mask case""" + session = session_with_data + gs.run_command("r.mask", raster="a", env=session.env) + data = gs.parse_command("r.mask.status", format="json", env=session.env) + assert data["present"] is True + assert data["full_name"] == "MASK@PERMANENT" + assert data["is_reclass_of"] == "a@PERMANENT" + # Now remove the mask. + gs.run_command("r.mask", flags="r", env=session.env) + data = gs.parse_command("r.mask.status", format="json", env=session.env) + assert data["present"] is False + assert not data["full_name"] + assert not data["is_reclass_of"] + + +def test_json_with_g_copy(session_with_data): + """Check JSON format for the low-level g.copy case""" + session = session_with_data + gs.run_command("g.copy", raster="a,MASK", env=session.env) + data = gs.parse_command("r.mask.status", format="json", env=session.env) + assert data["present"] is True + assert data["full_name"] == "MASK@PERMANENT" + assert not data["is_reclass_of"] + # Now remove the mask. + gs.run_command("g.remove", type="raster", name="MASK", flags="f", env=session.env) + data = gs.parse_command("r.mask.status", format="json", env=session.env) + assert data["present"] is False + assert not data["full_name"] + assert not data["is_reclass_of"] + + +def test_shell(session_with_data): + """Check shell format for the r.mask case""" + session = session_with_data + gs.run_command("r.mask", raster="a", env=session.env) + data = gs.parse_command("r.mask.status", format="shell", env=session.env) + assert int(data["present"]) + assert data["full_name"] == "MASK@PERMANENT" + assert data["is_reclass_of"] == "a@PERMANENT" + # Now remove the mask. + gs.run_command("r.mask", flags="r", env=session.env) + data = gs.parse_command("r.mask.status", format="shell", env=session.env) + assert not int(data["present"]) + assert not data["full_name"] + assert not data["is_reclass_of"] + + +@pytest.mark.skipif(yaml is None, reason="PyYAML package not available") +def test_yaml(session_with_data): + """Check YAML format for the r.mask case""" + session = session_with_data + gs.run_command("r.mask", raster="a", env=session.env) + text = gs.read_command("r.mask.status", format="yaml", env=session.env) + data = yaml.safe_load(text) + assert data["present"] is True + assert data["full_name"] == "MASK@PERMANENT" + assert data["is_reclass_of"] == "a@PERMANENT" + # Now remove the mask. + gs.run_command("r.mask", flags="r", env=session.env) + text = gs.read_command("r.mask.status", format="yaml", env=session.env) + data = yaml.safe_load(text) + assert data["present"] is False + assert not data["full_name"] + assert not data["is_reclass_of"] + + +def test_plain(session_with_data): + """Check plain text format for the r.mask case""" + session = session_with_data + gs.run_command("r.mask", raster="a", env=session.env) + text = gs.read_command("r.mask.status", format="plain", env=session.env) + assert text + assert "MASK@PERMANENT" in text + assert "a@PERMANENT" in text + # Now remove the mask. + gs.run_command("r.mask", flags="r", env=session.env) + text = gs.read_command("r.mask.status", format="plain", env=session.env) + assert text + + +def test_without_parameters(session_no_data): + """Check output is generated with no parameters""" + session = session_no_data + text = gs.read_command("r.mask.status", env=session.env) + assert text + + +def test_behavior_mimicking_test_program(session_with_data): + """Check test program like behavior for the r.mask case""" + session = session_with_data + gs.run_command("r.mask", raster="a", env=session.env) + returncode = gs.run_command( + "r.mask.status", flags="t", env=session.env, errors="status" + ) + assert returncode == 0 + # Now remove the mask. + gs.run_command("r.mask", flags="r", env=session.env) + returncode = gs.run_command( + "r.mask.status", flags="t", env=session.env, errors="status" + ) + assert returncode == 1 From 0feea315328915bfc1382097805c526708f1736e Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Sat, 12 Oct 2024 04:03:51 -0400 Subject: [PATCH 10/69] i.ortho.photo: Fix Resource Leak in find_init.c (#4388) --- imagery/i.ortho.photo/lib/find_init.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/imagery/i.ortho.photo/lib/find_init.c b/imagery/i.ortho.photo/lib/find_init.c index 906203a7f90..f8cea9b9387 100644 --- a/imagery/i.ortho.photo/lib/find_init.c +++ b/imagery/i.ortho.photo/lib/find_init.c @@ -4,15 +4,19 @@ * Find the a camera initial file in the current group (if it exists) **************************************************************/ #include +#include int I_find_initial(char *group) { - char *element; - - element = (char *)G_malloc(80 * sizeof(char)); + char element[GNAME_MAX + 6]; if (group == NULL || *group == 0) return 0; - sprintf(element, "group/%s", group); + + if (snprintf(element, GNAME_MAX, "group/%s", group) >= GNAME_MAX) { + G_warning(_("Group name <%s> is too long"), group); + return 0; + } + return G_find_file(element, "INIT_EXP", G_mapset()) != NULL; } From 9df8433d50a9552ebe53ea37c45d698739bdcf4f Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Sat, 12 Oct 2024 04:06:08 -0400 Subject: [PATCH 11/69] lib/vector/Vlib: Fix copy into buffer size issue in color_read.c (#4462) --- lib/vector/Vlib/color_read.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/vector/Vlib/color_read.c b/lib/vector/Vlib/color_read.c index 0a023a89a7d..4e0b3b04837 100644 --- a/lib/vector/Vlib/color_read.c +++ b/lib/vector/Vlib/color_read.c @@ -49,7 +49,10 @@ int Vect_read_colors(const char *name, const char *mapset, if (colors) Rast_init_colors(colors); - strcpy(xname, name); + if (G_strlcpy(xname, name, sizeof(xname)) >= sizeof(xname)) { + G_warning(_("Vector map name <%s> is too long"), name); + return -1; + } mapset = G_find_vector(xname, mapset); if (!mapset) return -1; @@ -58,12 +61,12 @@ int Vect_read_colors(const char *name, const char *mapset, if (strcmp(mapset, G_mapset()) == 0) { /* look for the regular color table */ - sprintf(buf, "%s/%s", GV_DIRECTORY, name); + (void)snprintf(buf, sizeof(buf), "%s/%s", GV_DIRECTORY, name); ret = Rast__read_colors(buf, GV_COLR_ELEMENT, mapset, colors); } else { /* look for secondary color table in current mapset */ - sprintf(buf, "%s/%s", GV_COLR2_DIRECTORY, mapset); + (void)snprintf(buf, sizeof(buf), "%s/%s", GV_COLR2_DIRECTORY, mapset); ret = Rast__read_colors(buf, name, G_mapset(), colors); } if (ret == -2) From 4cf93d28d995f4a012c68914fcbe95786245b444 Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Sat, 12 Oct 2024 04:09:53 -0400 Subject: [PATCH 12/69] checks: Remove extra semicolons in r.terraflow (#4494) --- raster/r.terraflow/fill.cpp | 2 +- raster/r.terraflow/genericWindow.cpp | 2 +- raster/r.terraflow/sweep.cpp | 2 +- raster/r.terraflow/weightWindow.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/raster/r.terraflow/fill.cpp b/raster/r.terraflow/fill.cpp index ab1629a3b7f..c7b54cd0a47 100644 --- a/raster/r.terraflow/fill.cpp +++ b/raster/r.terraflow/fill.cpp @@ -518,7 +518,7 @@ void assignFinalDirections(AMI_STREAM *statstr, continue; } } -}; +} /* ********************************************************************** */ class directionElevationMerger { diff --git a/raster/r.terraflow/genericWindow.cpp b/raster/r.terraflow/genericWindow.cpp index 92b0852cd71..9b114773e2a 100644 --- a/raster/r.terraflow/genericWindow.cpp +++ b/raster/r.terraflow/genericWindow.cpp @@ -36,4 +36,4 @@ void fillPit(ElevationWindow &win) if (win.get(4) < min) { win.set(4, min); } -}; +} diff --git a/raster/r.terraflow/sweep.cpp b/raster/r.terraflow/sweep.cpp index 2f7fba8bb13..c98b844b016 100644 --- a/raster/r.terraflow/sweep.cpp +++ b/raster/r.terraflow/sweep.cpp @@ -65,7 +65,7 @@ sweepOutput::sweepOutput() #ifdef OUTPUT_TCI tci = (tci_type)nodataType::ELEVATION_NODATA; #endif -}; +} /* ------------------------------------------------------------ */ /* computes output parameters of cell (i,j) given the flow value, the diff --git a/raster/r.terraflow/weightWindow.cpp b/raster/r.terraflow/weightWindow.cpp index ccf55a82ca9..760dccc6b5c 100644 --- a/raster/r.terraflow/weightWindow.cpp +++ b/raster/r.terraflow/weightWindow.cpp @@ -229,7 +229,7 @@ void weightWindow::compute(const dimension_type i, const dimension_type j, cout << form("%3.2f ", weight.get(l)); cout << "]\n"; #endif -}; +} /* Find the dominant direction. Set corresponding weight to 1, and sets all other weights to 0. Set sumweight and sumcontour.*/ From 71066f415bfb1f85c488e61284f8b477fb7a910b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 07:27:34 -0400 Subject: [PATCH 13/69] CI(deps): Update actions/upload-artifact action to v4.4.3 (#4481) --- .github/actions/create-upload-suggestions/action.yml | 4 ++-- .github/workflows/macos.yml | 2 +- .github/workflows/osgeo4w.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/python-code-quality.yml | 4 ++-- .github/workflows/ubuntu.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/create-upload-suggestions/action.yml b/.github/actions/create-upload-suggestions/action.yml index 181babe11e9..b80c08c1b46 100644 --- a/.github/actions/create-upload-suggestions/action.yml +++ b/.github/actions/create-upload-suggestions/action.yml @@ -177,7 +177,7 @@ runs: echo "diff-file-name=${INPUT_DIFF_FILE_NAME}" >> "${GITHUB_OUTPUT}" env: INPUT_DIFF_FILE_NAME: ${{ steps.tool-name-safe.outputs.diff-file-name }} - - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 id: upload-diff if: >- ${{ (steps.files_changed.outputs.files_changed == 'true') && @@ -200,7 +200,7 @@ runs: echo 'Suggestions can only be added near to lines changed in this PR.' echo 'If any fixes can be added as code suggestions, they will be added shortly from another workflow.' } >> "${GITHUB_STEP_SUMMARY}" - - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 id: upload-changes if: >- ${{ always() && diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7b4e7eb18e2..41ac51df8ff 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -107,7 +107,7 @@ jobs: nc_spm_full_v2alpha2.tar.gz" - name: Make HTML test report available if: ${{ !cancelled() }} - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: testreport-macOS path: testreport diff --git a/.github/workflows/osgeo4w.yml b/.github/workflows/osgeo4w.yml index 180cc79ec08..a7694fa9b30 100644 --- a/.github/workflows/osgeo4w.yml +++ b/.github/workflows/osgeo4w.yml @@ -120,7 +120,7 @@ jobs: - name: Make HTML test report available if: ${{ always() }} - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: testreport-${{ matrix.os }} path: testreport diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 60ddb223074..f2a96cf41ba 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -116,7 +116,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Make python-only code coverage test report available if: ${{ !cancelled() }} - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: python-codecoverage-report-${{ matrix.os }}-${{ matrix.python-version }} path: coverage_html_report diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index 5da86464470..b8b423b2b16 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -129,7 +129,7 @@ jobs: bandit -c pyproject.toml -iii -r . -f sarif -o bandit.sarif --exit-zero - name: Upload Bandit Scan Results - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: bandit.sarif path: bandit.sarif @@ -201,7 +201,7 @@ jobs: cp -rp dist.$ARCH/docs/html/libpython sphinx-grass - name: Make Sphinx documentation available - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: sphinx-grass path: sphinx-grass diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 88ddd0d31b2..966dbfe21ab 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -149,7 +149,7 @@ jobs: - name: Make HTML test report available if: ${{ always() }} - uses: actions/upload-artifact@84480863f228bb9747b473957fcc9e309aa96097 # v4.4.2 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: testreport-${{ matrix.os }}-${{ matrix.config }}-${{ matrix.extra-include }} path: testreport From 542f3b479c6fd44477485aac26e5491bc30966a7 Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Sat, 12 Oct 2024 07:28:22 -0400 Subject: [PATCH 14/69] v.colors: Fix Resource Leak issue in read_rgb.c (#4497) --- vector/v.colors/read_rgb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/v.colors/read_rgb.c b/vector/v.colors/read_rgb.c index 99aa054138d..c6e762ca0af 100644 --- a/vector/v.colors/read_rgb.c +++ b/vector/v.colors/read_rgb.c @@ -64,4 +64,5 @@ void rgb2colr(struct Map_info *Map, int layer, const char *rgb_column, G_warning(_("%d invalid RGB color values skipped"), nskipped); db_close_database_shutdown_driver(driver); + Vect_destroy_field_info(fi); } From 779af809951d802c2ba25cc7e01582c7d20da986 Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Sat, 12 Oct 2024 07:28:58 -0400 Subject: [PATCH 15/69] v.to.db: Fix Resource Leak issue in areas.c (#4498) * Fix Resource Leak issue * Fix Resource Leak issue --- vector/v.to.db/areas.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/v.to.db/areas.c b/vector/v.to.db/areas.c index 0977890276e..232cc4894d6 100644 --- a/vector/v.to.db/areas.c +++ b/vector/v.to.db/areas.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "global.h" @@ -111,5 +112,6 @@ int read_areas(struct Map_info *Map) G_percent(area_num, nareas, 2); } + Vect_destroy_cats_struct(Cats); return 0; } From 03675b0323cfff4974c0298139d0d73199b0a5a1 Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:23:47 -0400 Subject: [PATCH 16/69] d.vect: Fix Resource Leak issue in attr.c (#4496) * fix Resource Leak issue * Update display/d.vect/attr.c --- display/d.vect/attr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/display/d.vect/attr.c b/display/d.vect/attr.c index 5a28807cbca..747b98c59af 100644 --- a/display/d.vect/attr.c +++ b/display/d.vect/attr.c @@ -35,9 +35,11 @@ int display_attr(struct Map_info *Map, int type, char *attrcol, db_init_string(&text); fi = Vect_get_field(Map, lattr->field); - if (fi == NULL) + if (fi == NULL) { + Vect_destroy_line_struct(Points); + Vect_destroy_cats_struct(Cats); return 1; - + } driver = db_start_driver_open_database(fi->driver, fi->database); if (driver == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), @@ -140,6 +142,7 @@ int display_attr(struct Map_info *Map, int type, char *attrcol, db_close_database_shutdown_driver(driver); Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(Cats); + Vect_destroy_field_info(fi); return 0; } From 3c4aa6d499bb3cb82b29e302c7cdeb7e1706243c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:55:04 +0000 Subject: [PATCH 17/69] CI(deps): Lock file maintenance (#4509) --- flake.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/flake.lock b/flake.lock index 51f61fb86f9..eacc92d3c4f 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1726153070, - "narHash": "sha256-HO4zgY0ekfwO5bX0QH/3kJ/h4KvUDFZg8YpkNwIbg1U=", + "lastModified": 1727826117, + "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "bcef6817a8b2aa20a5a6dbb19b43e63c5bf8619a", + "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", "type": "github" }, "original": { @@ -19,11 +19,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1727648392, - "narHash": "sha256-VTlVv1nSxImFxY6RPQpNZxvEOQ0u5s1wBFDgixySNDo=", + "lastModified": 1728538411, + "narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4e0c36e4dd53f35d5a6385bdae88895ec5832f70", + "rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221", "type": "github" }, "original": { @@ -35,14 +35,14 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1725233747, - "narHash": "sha256-Ss8QWLXdr2JCBPcYChJhz4xJm+h/xjl4G0c0XlP6a74=", + "lastModified": 1727825735, + "narHash": "sha256-0xHYkMkeLVQAMa7gvkddbPqpxph+hDzdu1XdGPJR+Os=", "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz" + "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" }, "original": { "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz" + "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" } }, "root": { From cb7cbab7e72f1d49bd3a761d1b0da2ee1b101646 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 04:15:36 +0000 Subject: [PATCH 18/69] CI(deps): Lock file maintenance (#4510) From ed02be59ff4129bbc3bd9fbb7545b7b73648be99 Mon Sep 17 00:00:00 2001 From: Mohan Yelugoti Date: Mon, 14 Oct 2024 07:54:32 -0400 Subject: [PATCH 19/69] ps.map: initialize variable contents before using them in get_ll_bounds (#4501) In some situations, when some conditionals fails, we would be assigning uninitialized variables to values, which is undefined behavior. Fix that by assigning a value to the variables. This was found using cppcheck tool. Signed-off-by: Mohan Yelugoti --- ps/ps.map/do_geogrid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ps/ps.map/do_geogrid.c b/ps/ps.map/do_geogrid.c index 0fac5f80cac..c22ef86379c 100644 --- a/ps/ps.map/do_geogrid.c +++ b/ps/ps.map/do_geogrid.c @@ -300,6 +300,7 @@ void get_ll_bounds(double *w, double *e, double *s, double *n) double ew, ns; int first; + east = west = north = south = 0.0; e1 = PS.w.east; w1 = PS.w.west; n1 = PS.w.north; From b5289ee0c71b666e8e1969cca07474298f44eded Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Mon, 14 Oct 2024 07:58:03 -0400 Subject: [PATCH 20/69] r.carve: Fix resource leak issue in enforce_ds.c (#4505) --- raster/r.carve/enforce_ds.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/raster/r.carve/enforce_ds.c b/raster/r.carve/enforce_ds.c index ea4d7a1ae7a..7a71dc97def 100644 --- a/raster/r.carve/enforce_ds.c +++ b/raster/r.carve/enforce_ds.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "enforce.h" #ifndef MAX @@ -487,4 +488,6 @@ static void process_line_segment(const int npts, void *rbuf, Point2 *pgxypts, prevrow = row; prevcol = col; } + Vect_destroy_line_struct(points); + Vect_destroy_cats_struct(cats); } From e139a4c0fd246bda49a9aff780a6f737306e3358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Mon, 14 Oct 2024 13:06:14 -0400 Subject: [PATCH 21/69] gui: Solve a recursion error in gui/wxpython/lmgr/giface.py (#4514) --- gui/wxpython/lmgr/giface.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gui/wxpython/lmgr/giface.py b/gui/wxpython/lmgr/giface.py index eac9a7fb2d8..67669039d5d 100644 --- a/gui/wxpython/lmgr/giface.py +++ b/gui/wxpython/lmgr/giface.py @@ -54,7 +54,9 @@ def __init__(self, tree): self._tree = tree def __len__(self): - return len(list(self)) + # The list constructor calls __len__ as an optimization if available, + # causing a RecursionError + return len([layer for layer in self]) # noqa: C416 def __iter__(self): """Iterates over the contents of the list.""" From 61b380f1c4e3163d67961448553a091642c27eda Mon Sep 17 00:00:00 2001 From: Nicklas Larsson Date: Mon, 14 Oct 2024 20:11:42 +0200 Subject: [PATCH 22/69] r.mask.status: fix null pointer dereference and false positive string overflow (#4512) Fixes two new issues reported by Coverity Scan: - Handles case of unsuccessful creation of json string - Silences false positive issue for string copy operation to buffer of size GMAPSET_MAX from G_mapset(). --- lib/raster/mask_info.c | 2 +- raster/r.mask.status/main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/raster/mask_info.c b/lib/raster/mask_info.c index 42102de86dd..317bab75b63 100644 --- a/lib/raster/mask_info.c +++ b/lib/raster/mask_info.c @@ -124,7 +124,7 @@ int Rast__mask_info(char *name, char *mapset) char rname[GNAME_MAX], rmapset[GMAPSET_MAX]; strcpy(rname, "MASK"); - strcpy(rmapset, G_mapset()); + (void)G_strlcpy(rmapset, G_mapset(), GMAPSET_MAX); if (!G_find_raster(rname, rmapset)) return -1; diff --git a/raster/r.mask.status/main.c b/raster/r.mask.status/main.c index 5eb32300240..16790adf35c 100644 --- a/raster/r.mask.status/main.c +++ b/raster/r.mask.status/main.c @@ -109,6 +109,8 @@ int report_status(struct Parameters *params) else json_object_set_null(root_object, "is_reclass_of"); char *serialized_string = json_serialize_to_string_pretty(root_value); + if (!serialized_string) + G_fatal_error(_("Failed to initialize pretty JSON string.")); puts(serialized_string); json_free_serialized_string(serialized_string); json_value_free(root_value); From 761d98a78010e34daa1d217fef433d04020ab82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:30:57 -0400 Subject: [PATCH 23/69] style: Ignore deprecated PT004 rule (#4520) Ruff rule PT004 is deprecated, so doesn't run with --preview flag, but still appears without the --preview flag. Since the only error won't be fixed, ignore that rule for the time being. --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 6147e2db897..2a2287aaaad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -176,6 +176,7 @@ ignore = [ "PLW1641", # eq-without-hash "PLW2901", # redefined-loop-name "PLW3201", # bad-dunder-method-name + "PT004", # pytest-missing-fixture-name-underscore # deprecated, so doesn't appear with --preview "PTH100", # os-path-abspath "PTH101", # os-chmod "PTH102", # os-mkdir From 3a9059b7e7bec4a302cf6455c65fbd7fea3f2f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:27:05 -0400 Subject: [PATCH 24/69] pytest: Collect code coverage in multiple workers too (#4451) * pytest: Collect code coverage in multiple workers too * utils: Handle paths that already have a .py extension in coverage_mapper * CI: Set INITIAL_GISBASE and INITIAL_PWD env vars for running pytest with multiple workers * Coverage: Omit gui/wxpython subfolders for now They are not covered at all and take some noticeable time to collect * Coverage: Remove unneeded omit patten for gui/wxpython subfolders --- .coveragerc | 1 + .github/workflows/pytest.yml | 11 +++++++++-- utils/coverage_mapper.py | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.coveragerc b/.coveragerc index 65e13c2234b..409fde55643 100644 --- a/.coveragerc +++ b/.coveragerc @@ -9,6 +9,7 @@ omit = ${INITIAL_PWD-.}/.github/* ${INITIAL_PWD-.}/bin.*/* ${INITIAL_PWD-.}/dist.*/* + **/gui/wxpython/*/** **/OBJ.*/* source = . diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index f2a96cf41ba..e1b3b84b54e 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -83,8 +83,13 @@ jobs: run: | export PYTHONPATH=`grass --config python_path`:$PYTHONPATH export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH + export INITIAL_GISBASE="$(grass --config path)" + export INITIAL_PWD="${PWD}" pytest --verbose --color=yes --durations=0 --durations-min=0.5 \ - --numprocesses auto -ra . \ + --numprocesses auto \ + --cov \ + --cov-context=test \ + -ra . \ -m 'not needs_solo_run' - name: Run pytest with a single worker (for tests marked with needs_solo_run) @@ -92,9 +97,11 @@ jobs: export PYTHONPATH=`grass --config python_path`:$PYTHONPATH export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH export INITIAL_GISBASE="$(grass --config path)" - INITIAL_PWD="${PWD}" pytest --verbose --color=yes --durations=0 --durations-min=0.5 \ + export INITIAL_PWD="${PWD}" + pytest --verbose --color=yes --durations=0 --durations-min=0.5 \ --cov \ --cov-context=test \ + --cov-append \ -ra . \ -m 'needs_solo_run' - name: Fix non-standard installed script paths in coverage data diff --git a/utils/coverage_mapper.py b/utils/coverage_mapper.py index 9a2f1389781..88fa30f9b54 100644 --- a/utils/coverage_mapper.py +++ b/utils/coverage_mapper.py @@ -22,12 +22,14 @@ def map_scripts_paths(old_path): if INITIAL_GISBASE is None or INITIAL_PWD is None: return old_path p = Path(old_path) + extension = ".py" + p_name = p.stem if p.suffix == extension else p.name temporal_base = Path(INITIAL_GISBASE) / "scripts" / "t.*" base = Path(INITIAL_GISBASE) / "scripts" / "*" if p.match(str(temporal_base)): - return str(Path(INITIAL_PWD) / "temporal" / (p.name) / (p.name)) + ".py" + return str(Path(INITIAL_PWD) / "temporal" / (p_name) / (p_name)) + extension if p.match(str(base)): - return str(Path(INITIAL_PWD) / "scripts" / (p.name) / (p.name)) + ".py" + return str(Path(INITIAL_PWD) / "scripts" / (p_name) / (p_name)) + extension return old_path From a98691f4eff03bb36ac6cd14058eab6edeace742 Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:02:46 -0400 Subject: [PATCH 25/69] v.net.timetable: Fix Resource Leak issue in main.c (#4508) * Fix Resource Leak issue * requested changes --- vector/v.net.timetable/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vector/v.net.timetable/main.c b/vector/v.net.timetable/main.c index 5fb382009bb..424d8a851bd 100644 --- a/vector/v.net.timetable/main.c +++ b/vector/v.net.timetable/main.c @@ -176,9 +176,7 @@ void write_subroute(struct segment *seg, struct line_pnts *line, int line_id) struct line_cats *Cats; struct ilist *list; - Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); - list = Vect_new_list(); r = seg->route; Vect_cat_set(Cats, 2, line_id); @@ -188,6 +186,9 @@ void write_subroute(struct segment *seg, struct line_pnts *line, int line_id) return; } + Points = Vect_new_line_struct(); + list = Vect_new_list(); + for (i = 0; i < nnodes; i++) edges[i] = 0; for (i = 0; i < lines[r]->n_values; i++) From f241532c70217d27955cdd0677d6e9cede697605 Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Mon, 14 Oct 2024 21:46:30 -0400 Subject: [PATCH 26/69] v.kernel: Fix resource Leak issue in main.c (#4506) Resource Leak --- vector/v.kernel/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/v.kernel/main.c b/vector/v.kernel/main.c index 96198a4d8f7..c1e7f77a36a 100644 --- a/vector/v.kernel/main.c +++ b/vector/v.kernel/main.c @@ -769,7 +769,9 @@ double compute_all_net_distances(struct Map_info *In, struct Map_info *Net, G_debug(3, " kk = %d", kk); } } - + Vect_destroy_line_struct(APoints); + Vect_destroy_line_struct(BPoints); + Vect_destroy_boxlist(List); return (kk); } From c5c5ec5f51d1e8fe503a3b80f5778ebc80be7efe Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Tue, 15 Oct 2024 04:25:27 -0400 Subject: [PATCH 27/69] lib/vector/Vlib: Fix Resource leak issue in geos.c (#4507) --- lib/vector/Vlib/geos.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/vector/Vlib/geos.c b/lib/vector/Vlib/geos.c index 719e0fdd270..2c68a0a6fba 100644 --- a/lib/vector/Vlib/geos.c +++ b/lib/vector/Vlib/geos.c @@ -290,7 +290,7 @@ GEOSCoordSequence *V1_read_line_geos(struct Map_info *Map, long offset, long size; double *x, *y, *z; - GEOSCoordSequence *pseq; + GEOSCoordSequence *pseq = NULL; G_debug(3, "V1_read_line_geos(): offset = %ld", offset); @@ -353,8 +353,6 @@ GEOSCoordSequence *V1_read_line_geos(struct Map_info *Map, long offset, G_debug(3, " n_points = %d dim = %d", n_points, (Map->head.with_z) ? 3 : 2); - pseq = GEOSCoordSeq_create(n_points, (Map->head.with_z) ? 3 : 2); - x = (double *)G_malloc(n_points * sizeof(double)); y = (double *)G_malloc(n_points * sizeof(double)); if (Map->head.with_z) @@ -362,17 +360,22 @@ GEOSCoordSequence *V1_read_line_geos(struct Map_info *Map, long offset, else z = NULL; - if (0 >= dig__fread_port_D(x, n_points, &(Map->dig_fp))) - return NULL; /* end of file */ + if (0 >= dig__fread_port_D(x, n_points, &(Map->dig_fp))) { + goto free_return; /* end of file */ + } - if (0 >= dig__fread_port_D(y, n_points, &(Map->dig_fp))) - return NULL; /* end of file */ + if (0 >= dig__fread_port_D(y, n_points, &(Map->dig_fp))) { + goto free_return; /* end of file */ + } if (Map->head.with_z) { - if (0 >= dig__fread_port_D(z, n_points, &(Map->dig_fp))) - return NULL; /* end of file */ + if (0 >= dig__fread_port_D(z, n_points, &(Map->dig_fp))) { + goto free_return; /* end of file */ + } } + pseq = GEOSCoordSeq_create(n_points, (Map->head.with_z) ? 3 : 2); + for (i = 0; i < n_points; i++) { GEOSCoordSeq_setX(pseq, i, x[i]); GEOSCoordSeq_setY(pseq, i, y[i]); @@ -382,6 +385,7 @@ GEOSCoordSequence *V1_read_line_geos(struct Map_info *Map, long offset, G_debug(3, " off = %ld", (long)dig_ftell(&(Map->dig_fp))); +free_return: G_free((void *)x); G_free((void *)y); if (z) From 15c5737dc601fbe71ab2bb614f14634ad17ddce0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:19:47 -0400 Subject: [PATCH 28/69] CI(deps): Update github/codeql-action action to v3.26.13 (#4518) --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/python-code-quality.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 88158341f13..6672287794c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -56,7 +56,7 @@ jobs: if: ${{ matrix.language == 'c-cpp' }} - name: Initialize CodeQL - uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -81,6 +81,6 @@ jobs: run: .github/workflows/build_ubuntu-22.04.sh "${HOME}/install" - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index b8b423b2b16..886cbe56b47 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -135,7 +135,7 @@ jobs: path: bandit.sarif - name: Upload SARIF File into Security Tab - uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13 with: sarif_file: bandit.sarif From ca171b7e53a5ae075fe4857cb8bbdcb7f764d061 Mon Sep 17 00:00:00 2001 From: Nicklas Larsson Date: Tue, 15 Oct 2024 13:29:47 +0200 Subject: [PATCH 29/69] tests: enable use of md5 bin for checksum in raster_md5test.sh (#4527) Makes the script runnable on e.g. BSD platforms, which does not ship with md5sum. In addition fixes shellcheck warnings. --- testsuite/raster/raster_md5test.sh | 52 ++++++++++++++++-------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/testsuite/raster/raster_md5test.sh b/testsuite/raster/raster_md5test.sh index 0bda0c3428c..b3281d4c505 100755 --- a/testsuite/raster/raster_md5test.sh +++ b/testsuite/raster/raster_md5test.sh @@ -14,19 +14,23 @@ if [ -z "$GISBASE" ] ; then fi #### check if we have sed -if [ ! -x "`which sed`" ] ; then +if [ ! -x "$(which sed)" ] ; then echo "$PROG: sed required, please install first" 1>&2 exit 1 fi -#### check if we have md5sum -if [ ! -x "`which md5sum`" ] ; then - echo "$PROG: md5sum required, please install first" 1>&2 - exit 1 +#### check if we have md5sum or md5 +if [ -x "$(which md5sum)" ] ; then + MD5="md5sum | cut -d' ' -f1" +elif [ -x "$(which md5)" ] ; then + MD5="md5 -q" +else + echo "$PROG: md5sum or md5 required, please install first" 1>&2 + exit 1 fi #### check if we have cut -if [ ! -x "`which cut`" ] ; then +if [ ! -x "$(which cut)" ] ; then echo "$PROG: cut required, please install first" 1>&2 exit 1 fi @@ -38,47 +42,47 @@ export LC_NUMERIC=C # enforce ZLIB export GRASS_COMPRESSOR=ZLIB -eval `g.gisenv` -: ${GISBASE?} ${GISDBASE?} ${LOCATION_NAME?} ${MAPSET?} +eval "$(g.gisenv)" +: "${GISBASE?}" "${GISDBASE?}" "${LOCATION_NAME?}" "${MAPSET?}" MAPSET_PATH=$GISDBASE/$LOCATION_NAME/$MAPSET # some definitions PIXEL=3 PID=$$ -TMPNAME="`echo ${PID}_tmp_testmap | sed 's+\.+_+g'`" +TMPNAME=$(echo ${PID}_tmp_testmap | sed 's+\.+_+g') # some functions - keep order here cleanup() { echo "Removing temporary map" - g.remove -f type=raster name=$TMPNAME > /dev/null + g.remove -f type=raster name="$TMPNAME" > /dev/null } # check if a MASK is already present: -MASKTMP=mask.$TMPNAME -USERMASK=usermask_${MASKTMP} -if test -f $MAPSET_PATH/cell/MASK +MASKTMP="mask.${TMPNAME}" +USERMASK="usermask_${MASKTMP}" +if test -f "${MAPSET_PATH}/cell/MASK" then echo "A user raster mask (MASK) is present. Saving it..." - g.rename raster=MASK,$USERMASK > /dev/null + g.rename raster=MASK,"$USERMASK" > /dev/null fi finalcleanup() { echo "Restoring user region" - g.region region=$TMPNAME - g.remove -f type=region name=$TMPNAME > /dev/null + g.region region="$TMPNAME" + g.remove -f type=region name="$TMPNAME" > /dev/null #restore user mask if present: - if test -f $MAPSET_PATH/cell/$USERMASK ; then + if test -f "${MAPSET_PATH}/cell/${USERMASK}" ; then echo "Restoring user MASK" g.remove -f type=raster name=MASK > /dev/null - g.rename raster=$USERMASK,MASK > /dev/null + g.rename raster="$USERMASK",MASK > /dev/null fi } check_exit_status() { - if [ $1 -ne 0 ] ; then + if [ "$1" -ne 0 ] ; then echo "An error occurred." cleanup ; finalcleanup exit 1 @@ -106,7 +110,7 @@ check_md5sum() } echo "Saving current & setting test region." -g.region save=$TMPNAME +g.region save="$TMPNAME" check_exit_status $? g.region s=0 n=$PIXEL w=0 e=$PIXEL res=1 tbres=1 check_exit_status $? @@ -118,8 +122,8 @@ r.mapcalc "$TMPNAME = 1" check_exit_status $? echo "MD5 checksum on output of INT/CELL test." -MD5="`r.out.ascii $TMPNAME precision=15 | md5sum | cut -d' ' -f1`" -check_md5sum "549e7dabe70df893803690571d2e1503" "$MD5" +SUM=$(r.out.ascii "$TMPNAME" precision=15 | eval "$MD5") +check_md5sum "549e7dabe70df893803690571d2e1503" "$SUM" cleanup echo "INT/CELL md5sum test successful" @@ -132,8 +136,8 @@ r.mapcalc "$TMPNAME = $VALUE" check_exit_status $? echo "MD5 checksum on output of FLOAT/FCELL test." -MD5="`r.out.ascii $TMPNAME precision=15 | md5sum | cut -d' ' -f1`" -check_md5sum "379f3d880b6d509051af6b4ccf470762" "$MD5" +SUM=$(r.out.ascii "$TMPNAME" precision=15 | eval "$MD5") +check_md5sum "379f3d880b6d509051af6b4ccf470762" "$SUM" cleanup echo "FLOAT/FCELL md5sum test successful" From f7d2ecfacca5f5bd9b0c0cd88752e7e0386b41d4 Mon Sep 17 00:00:00 2001 From: Markus Metz <33666869+metzm@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:12:15 +0200 Subject: [PATCH 30/69] lib/vector/Vlib: always write out topo files in update mode (#3459) * Vlib: always write out topo files in update mode * delete support files only when closing * fix pygrass Vect_close --------- Co-authored-by: Huidae Cho --- lib/vector/Vlib/open.c | 1 + python/grass/pygrass/vector/abstract.py | 21 ++++++++------------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/vector/Vlib/open.c b/lib/vector/Vlib/open.c index 501b31eb4cb..0008156c34a 100644 --- a/lib/vector/Vlib/open.c +++ b/lib/vector/Vlib/open.c @@ -572,6 +572,7 @@ int Vect__open_old(struct Map_info *Map, const char *name, const char *mapset, if (access(file_path, F_OK) == 0) /* fidx file exists? */ unlink(file_path); } + Map->support_updated = TRUE; } return level; diff --git a/python/grass/pygrass/vector/abstract.py b/python/grass/pygrass/vector/abstract.py index 6700dca8e4c..79307f0d354 100644 --- a/python/grass/pygrass/vector/abstract.py +++ b/python/grass/pygrass/vector/abstract.py @@ -457,14 +457,14 @@ def close(self, build=False): if hasattr(self, "table") and self.table is not None: self.table.conn.close() if self.is_open(): - if libvect.Vect_close(self.c_mapinfo) != 0: - str_err = "Error when trying to close the map with Vect_close" - raise GrassError(str_err) if ( self.c_mapinfo.contents.mode in {libvect.GV_MODE_RW, libvect.GV_MODE_WRITE} ) and build: self.build() + if libvect.Vect_close(self.c_mapinfo) != 0: + str_err = "Error when trying to close the map with Vect_close" + raise GrassError(str_err) def remove(self): """Remove vector map""" @@ -474,16 +474,11 @@ def remove(self): def build(self): """Close the vector map and build vector Topology""" - self.close() - libvect.Vect_set_open_level(1) - if libvect.Vect_open_old2(self.c_mapinfo, self.name, self.mapset, "0") != 1: - str_err = "Error when trying to open the vector map." - raise GrassError(str_err) - # Vect_build returns 1 on success and 0 on error (bool approach) - if libvect.Vect_build(self.c_mapinfo) != 1: - str_err = "Error when trying build topology with Vect_build" - raise GrassError(str_err) - libvect.Vect_close(self.c_mapinfo) + if self.is_open(): + # Vect_build returns 1 on success and 0 on error (bool approach) + if libvect.Vect_build(self.c_mapinfo) != 1: + str_err = "Error when trying build topology with Vect_build" + raise GrassError(str_err) if __name__ == "__main__": From c0c5380fb920042c9539490e21d30f9af2165b83 Mon Sep 17 00:00:00 2001 From: Anna Petrasova Date: Tue, 15 Oct 2024 09:58:35 -0400 Subject: [PATCH 31/69] r.sim.water: fix logfile writing (#4522) --- raster/r.sim/r.sim.sediment/main.c | 2 ++ raster/r.sim/r.sim.water/main.c | 4 +++- raster/r.sim/simlib/hydro.c | 3 --- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/raster/r.sim/r.sim.sediment/main.c b/raster/r.sim/r.sim.sediment/main.c index dd082fe0f81..d0197c2abb1 100644 --- a/raster/r.sim/r.sim.sediment/main.c +++ b/raster/r.sim/r.sim.sediment/main.c @@ -417,6 +417,8 @@ int main(int argc, char *argv[]) G_message(_("Using metric conversion factor %f, step=%f"), wp.conv, wp.step); + wp.observation = parm.observation->answer; + wp.logfile = parm.logfile->answer; init_library_globals(&wp); if ((wp.tc == NULL) && (wp.et == NULL) && (wp.conc == NULL) && diff --git a/raster/r.sim/r.sim.water/main.c b/raster/r.sim/r.sim.water/main.c index 61f128f5504..209be3e33d9 100644 --- a/raster/r.sim/r.sim.water/main.c +++ b/raster/r.sim/r.sim.water/main.c @@ -220,7 +220,7 @@ int main(int argc, char *argv[]) parm.logfile->required = NO; parm.logfile->description = _("Name for sampling points output text file. For each observation " - "vector point the time series of sediment transport is stored."); + "vector point the time series of water discharge is stored."); parm.logfile->guisection = _("Output"); parm.nwalk = G_define_option(); @@ -525,6 +525,8 @@ int main(int argc, char *argv[]) G_message(_("Using metric conversion factor %f, step=%f"), wp.conv, wp.step); + wp.observation = parm.observation->answer; + wp.logfile = parm.logfile->answer; init_library_globals(&wp); if ((wp.depth == NULL) && (wp.disch == NULL) && (wp.err == NULL)) diff --git a/raster/r.sim/simlib/hydro.c b/raster/r.sim/simlib/hydro.c index 74145ec9bff..eb7649763e9 100644 --- a/raster/r.sim/simlib/hydro.c +++ b/raster/r.sim/simlib/hydro.c @@ -151,9 +151,6 @@ void main_loop(void) maxwa = maxwa / nblock; } - /* Create the observation points */ - create_observation_points(); - G_debug(2, " maxwa, nblock %d %d", maxwa, nblock); for (iblock = 1; iblock <= nblock; iblock++) { From f22c9a2767960598ba99113eff595fda43bbfb8d Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Tue, 15 Oct 2024 10:02:36 -0400 Subject: [PATCH 32/69] doc: Use lowercase for 2D raster mask and other masks (#4495) Similarly to #4401, this replaces usage of MASK by mask on additional places. It also improves wording of a warning in i.fft. --- imagery/i.fft/main.c | 5 +++-- imagery/i.pca/i.pca.html | 2 +- lib/ogsf/gk.c | 4 ++-- lib/ogsf/gvd.c | 2 +- raster/r.fill.dir/r.fill.dir.html | 8 ++++---- raster/r.li/TODO | 7 ++++--- raster/r.univar/r.univar.html | 2 +- 7 files changed, 16 insertions(+), 14 deletions(-) diff --git a/imagery/i.fft/main.c b/imagery/i.fft/main.c index ad9a87a7890..051428b77ef 100644 --- a/imagery/i.fft/main.c +++ b/imagery/i.fft/main.c @@ -105,8 +105,9 @@ int main(int argc, char *argv[]) inputfd = Rast_open_old(Cellmap_orig, ""); if (Rast_maskfd() >= 0) - G_warning(_("Raster MASK found, consider to remove " - "(see man-page). Will continue...")); + G_warning(_("Raster mask active, consider removing it" + " and running again without it (see documentation for" + " details). This current process will now continue...")); G_get_set_window(&window); /* get the current window for later */ diff --git a/imagery/i.pca/i.pca.html b/imagery/i.pca/i.pca.html index 17b3f5ed163..6fee184c618 100644 --- a/imagery/i.pca/i.pca.html +++ b/imagery/i.pca/i.pca.html @@ -11,7 +11,7 @@

DESCRIPTION

principal component with the highest importance.

-The current geographic region definition and MASK settings are +The current geographic region definition and raster mask settings are respected when reading the input raster map layers. When the rescale option is used, the output files are rescaled to fit the min,max range. diff --git a/lib/ogsf/gk.c b/lib/ogsf/gk.c index 3390598960a..b4fea635cc4 100644 --- a/lib/ogsf/gk.c +++ b/lib/ogsf/gk.c @@ -172,8 +172,8 @@ void gk_follow_frames(Viewnode *view, int numsteps, Keylist *keys, int step, GS_get_from(tmp); G_debug(3, "gk_follow_frames():"); - G_debug(3, " MASK: %lx", mask); - G_debug(3, " FROM: %f %f %f", tmp[X], tmp[Y], tmp[Z]); + G_debug(3, " mask: %lx", mask); + G_debug(3, " from: %f %f %f", tmp[X], tmp[Y], tmp[Z]); /* ACS 1 line: was GS_get_focus(tmp); with this kanimator works also for flythrough navigation diff --git a/lib/ogsf/gvd.c b/lib/ogsf/gvd.c index 6a6176526a2..84867123c5e 100644 --- a/lib/ogsf/gvd.c +++ b/lib/ogsf/gvd.c @@ -201,7 +201,7 @@ int gvd_vect(geovect *gv, geosurf *gs, int do_fast) } gsd_endline(); } - /* need to handle MASK! */ + /* need to handle mask! */ else if (src == CONST_ATT) { /* for now - but later, do seg intersect maskedge */ if (gs_point_is_masked(gs, bgn) || diff --git a/raster/r.fill.dir/r.fill.dir.html b/raster/r.fill.dir/r.fill.dir.html index 6ad8eb8019c..17173ea3dd3 100644 --- a/raster/r.fill.dir/r.fill.dir.html +++ b/raster/r.fill.dir/r.fill.dir.html @@ -69,11 +69,11 @@

DESCRIPTION

attributes required by other hydrological models.

-As any GRASS GIS module, r.fill.dir is sensitive to the -computational region settings. Thus +As any GRASS GIS module, r.fill.dir respects the +computational region settings. Thus, the module can be used to generate a flow direction map for any -sub-area within the full map layer. Also, r.fill.dir is -sensitive to any raster MASK in effect. +sub-area within the full raster map layer. Also, r.fill.dir +will take into account an active raster mask.

NOTES

diff --git a/raster/r.li/TODO b/raster/r.li/TODO index 61ddd6b0941..382195402a6 100644 --- a/raster/r.li/TODO +++ b/raster/r.li/TODO @@ -24,12 +24,13 @@ d.vect forests type=boundary ######## TODO: CHECK THIS: -# MASK test -g.copy rast=fields,MASK +# Test with raster mask +r.mask raster=fields r.li.patchdensity forests conf=movwindow7 output=forests_p_dens7mask --o d.erase d.rast.leg forests_p_dens7mask -# -> no negative values! but MASK is respected +r.mask -r +# -> no negative values! but mask is respected # zero data test r.mapcalc "forests = 0" diff --git a/raster/r.univar/r.univar.html b/raster/r.univar/r.univar.html index 5220bc64a44..debde03a1d6 100644 --- a/raster/r.univar/r.univar.html +++ b/raster/r.univar/r.univar.html @@ -53,7 +53,7 @@

PERFORMANCE

r.univar supports parallel processing using OpenMP. The user can specify the number of threads to be used with the nprocs parameter. -However, parallelization is disabled when the MASK is set. +However, parallelization is disabled when the raster mask is set.

Due to the differences in summation order, users may encounter small floating points From ec2bc8a7df27b1984c878b7a0a209bad9e977acd Mon Sep 17 00:00:00 2001 From: Mohan Yelugoti Date: Tue, 15 Oct 2024 11:35:11 -0400 Subject: [PATCH 33/69] r3.in.v5d: Prevent integer overflow by changing literal constant type on Cray (#4363) When the code is being compiled for CRAY HPC machines, a macro and a function to convert IEEE single precision floating point number to CRAY number are defined. To adjust the base, '16258' constant is being used, which according to C rules (C99, section 6.4.4.1, subsection semantics) fits into an integer. Right shifting that integer, which is of 32 bits, by 48 results in integer overflow. Avoid this by defining the literal constant with the long data type. This comes with an extended discussion in PR #4363 and an idea to remove the code completely. Signed-off-by: Mohan Yelugoti --- raster3d/r3.in.v5d/binio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/raster3d/r3.in.v5d/binio.c b/raster3d/r3.in.v5d/binio.c index f8582e97313..b47723a2929 100644 --- a/raster3d/r3.in.v5d/binio.c +++ b/raster3d/r3.in.v5d/binio.c @@ -147,7 +147,7 @@ static void if_to_c(long *t, const long *f) { if (*f != 0) { *t = (((*f & 0x8000000000000000) | - ((*f & 0x7f80000000000000) >> 7) + (16258 << 48)) | + ((*f & 0x7f80000000000000) >> 7) + (16258L << 48)) | (((*f & 0x007fffff00000000) >> 8) | (0x0000800000000000))); if ((*f << 1) == 0) *t = 0; @@ -160,7 +160,7 @@ static void if_to_c(long *t, const long *f) #define IF_TO_C(T, F) \ if (F != 0) { \ T = (((F & 0x8000000000000000) | \ - ((F & 0x7f80000000000000) >> 7) + (16258 << 48)) | \ + ((F & 0x7f80000000000000) >> 7) + (16258L << 48)) | \ (((F & 0x007fffff00000000) >> 8) | (0x0000800000000000))); \ if ((F << 1) == 0) \ T = 0; \ From 1adbd2ced8411fcc1e375ac6d6d124c419e497f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:59:46 -0400 Subject: [PATCH 34/69] CI: Assign milestone on merged PRs (#4414) * CI: Create a workflow to assign milestones * Add GH_TOKEN for gh cli * CI: Add GH_REPO for gh cli * CI: View PR from gh cli using html_url * CI: Download and parse version file * CI: Show version file * CI: Download and parse version file using a pipe * Show version file output Clean up * Pipe version file env to head * Rename variables to milestone and title * Edit PR with milestone * Get milestone from gh cli * Add comment on why API call is used for getting milestone * Show if the PR has a milestone set or not * Do not run steps if a milestone is already set * Add pull_request_target closed trigger * Add ref as url parameter * Remove debugging steps * CI: Handle RC followed by numbers in sed pattern replacement --- .github/workflows/milestones.yml | 70 ++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/milestones.yml diff --git a/.github/workflows/milestones.yml b/.github/workflows/milestones.yml new file mode 100644 index 00000000000..e2ade4eb091 --- /dev/null +++ b/.github/workflows/milestones.yml @@ -0,0 +1,70 @@ +--- +name: Assign Milestone + +on: + pull_request_target: + types: [closed] + +jobs: + assign-milestone: + runs-on: ubuntu-latest + if: github.event.pull_request.merged + steps: + # Retreiving the current milestoone from API instead of github context, + # so up-to-date information is used when running after being queued or for reruns + # Otherwise, the information should be available using + # ${{ github.event.pull_request.milestone.title }} + - name: Get current milestone title + id: current-milestone + run: | + echo "milestone<> "${GITHUB_OUTPUT}" + gh pr view ${{ github.event.pull_request.html_url }} --json milestone \ + --jq .milestone.title >> "${GITHUB_OUTPUT}" + echo 'EOF' >> "${GITHUB_OUTPUT}" + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + - name: PR already has a milestone + run: echo "PR already has a milestone" + if: ${{ steps.current-milestone.outputs.milestone }} + - name: PR does not have a milestone + run: echo "PR does not have a milestone" + if: ${{ !steps.current-milestone.outputs.milestone }} + - name: Get VERSION file + if: ${{ !steps.current-milestone.outputs.milestone }} + id: version-file + run: | + echo "version<> "${GITHUB_OUTPUT}" + gh api \ + -H "Accept: application/vnd.github.raw" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/{owner}/{repo}/contents/include/VERSION?ref=${{ github.sha }}" >> "${GITHUB_OUTPUT}" + echo "EOF" >> "${GITHUB_OUTPUT}" + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + - name: Show version file + if: ${{ !steps.current-milestone.outputs.milestone }} + run: echo "${VERSIONFILE}" + env: + VERSIONFILE: ${{ steps.version-file.outputs.version }} + - name: Get milestone title from VERSION file + if: ${{ !steps.current-milestone.outputs.milestone }} + id: milestone + run: | + version=$(echo "$VERSIONFILE" | head -n 3 | xargs | sed 's/ /./g; s/\(RC[0-9]*\|dev\)//g') + echo "title=$version" >> "${GITHUB_OUTPUT}" + env: + VERSIONFILE: ${{ steps.version-file.outputs.version }} + - name: Show milestone title + if: ${{ !steps.current-milestone.outputs.milestone }} + run: echo "${MILESTONE}" + env: + MILESTONE: ${{ steps.milestone.outputs.title }} + - name: Set PR milestone + if: ${{ !steps.current-milestone.outputs.milestone }} + run: gh pr edit ${{ github.event.pull_request.html_url }} --milestone "${MILESTONE}" + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + MILESTONE: ${{ steps.milestone.outputs.title }} From 9a79aa4a9a637b7467cdfd7e0b2a2193f623f8a5 Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Tue, 15 Oct 2024 19:09:57 -0400 Subject: [PATCH 35/69] tests: Revise content of the root testsuite dir (#4516) * Remove Makefiles. * Move the functioning test to the testsuite directory for the gunittest to pick it up. * Remove the extended example how to run gunittest. Point to the CI in the README instead. * Remove hemisphere generator because it does not test anything by itself (without further processing and a human). * Remove GPS import tests as the tools are not in core. * Remove division into subdirectories. The directories with the code should be used instead. * Improve the test for gunittest loader function with some duplication but now creating an overview of .py and .sh tests. --- python/grass/gunittest/loader.py | 16 +- testsuite/Makefile | 8 - testsuite/README.md | 44 +++--- .../test_framework_GRASS_GIS_with_NC.conf | 29 ---- .../test_framework_GRASS_GIS_with_NC.sh | 144 ------------------ testsuite/raster/Makefile | 3 - testsuite/raster/README | 1 - testsuite/raster/rhemisphere.sh | 48 ------ testsuite/{raster => }/raster_md5test.sh | 0 testsuite/vector/v.in.gps_test.sh | 26 ---- 10 files changed, 42 insertions(+), 277 deletions(-) delete mode 100644 testsuite/Makefile delete mode 100644 testsuite/examples/test_framework_GRASS_GIS_with_NC.conf delete mode 100755 testsuite/examples/test_framework_GRASS_GIS_with_NC.sh delete mode 100644 testsuite/raster/Makefile delete mode 100644 testsuite/raster/README delete mode 100755 testsuite/raster/rhemisphere.sh rename testsuite/{raster => }/raster_md5test.sh (100%) delete mode 100755 testsuite/vector/v.in.gps_test.sh diff --git a/python/grass/gunittest/loader.py b/python/grass/gunittest/loader.py index f01467ef1ba..50fa368f62a 100644 --- a/python/grass/gunittest/loader.py +++ b/python/grass/gunittest/loader.py @@ -235,4 +235,18 @@ def discover(self, start_dir, pattern="test*.py", top_level_dir=None): if __name__ == "__main__": - GrassTestLoader().discover() + for expression in [r".*\.py$", r".*\.sh$"]: + modules = discover_modules( + start_dir=".", + grass_location="all", + file_regexp=expression, + skip_dirs=GrassTestLoader.skip_dirs, + testsuite_dir=GrassTestLoader.testsuite_dir, + all_locations_value=GrassTestLoader.all_tests_value, + universal_location_value=GrassTestLoader.universal_tests_value, + import_modules=False, + exclude=None, + ) + print("Expression:", expression) + print(len(modules)) + print([module.file_path for module in modules]) diff --git a/testsuite/Makefile b/testsuite/Makefile deleted file mode 100644 index 7ed92b67442..00000000000 --- a/testsuite/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -MODULE_TOPDIR = .. - -SUBDIRS = \ - raster - -include $(MODULE_TOPDIR)/include/Make/Dir.make - -default: parsubdirs diff --git a/testsuite/README.md b/testsuite/README.md index 491fa4597af..36dda7d3da2 100644 --- a/testsuite/README.md +++ b/testsuite/README.md @@ -1,29 +1,39 @@ # Test suite -This directory contains scripts to check some functionality of GRASS GIS. +Tests are in directories `tests` and `testsuite` under each directory which has tests. +This directory contains additional scripts and information to test functionality +without a focus on a specific part of the code. -GRASS GIS testsuite documentation: +There are two testing mechanism in place, _pytest_ which is the modern way of testing +GRASS GIS. Tests using _pytest_ are written just as any other Python tests. -## Simple test data +In parallel, there is also custom unittest-based framework centered around +_grass.gunittest_ package. These tests run in the NC sample datasets and can be +executed using _pytest_ or directly. The unittest-based adds a number of custom +assert methods to accommodate different data and outputs typical in GRASS GIS. +_grass.gunittest_ documentation: + -Some tests may be launched in the location `../demolocation/`: +## Running tests + +Tests can be executed using _pytest_: ```bash -# create new mapset for test -grass ../demolocation/user1 -c -# run the test -make +# Setup the Python environment (if not set up already). +# Replace grass by path to the executable if not installed on path. +export PYTHONPATH=\$(grass --config python_path):\$PYTHONPATH +export LD_LIBRARY_PATH=\$(grass --config path)/lib:\$LD_LIBRARY_PATH +# Run the test. +pytest ``` -## Extended test data - -Most tests require the North Carolina Sample dataset, available from - +## Test data -## Notes +To test manually or to write tests, you may need to use the North Carolina +Sample dataset, available from +. -Since 2020: For a more advanced test suite, see - +## CI -Until 2019: For a more advanced test suite, see - +Most tests run in the CI. See the `.github` directory for details and +use it as a reference. diff --git a/testsuite/examples/test_framework_GRASS_GIS_with_NC.conf b/testsuite/examples/test_framework_GRASS_GIS_with_NC.conf deleted file mode 100644 index 6256108f6a8..00000000000 --- a/testsuite/examples/test_framework_GRASS_GIS_with_NC.conf +++ /dev/null @@ -1,29 +0,0 @@ -### CONFIGURATION -# -# name of binary: -GRASSBIN=grass -# source code directory as full path: -GRASSSRC="$(realpath ../../)" -# temporary grassdata directory -GRASSDATA="$HOME/grassdata" - -# leave 1 or more CPU free for other usage than testing -FREECPU=1 - -# Python binary to be used (python|python3) -PYTHON=python - -# here we suppose default compilation settings of GRASS GIS and no 'make install' -# may be no|yes -COMPILE="no" -# configure metascript with compiler flags: -CONFIGURE="${GRASSSRC}/conf_grass8.sh" - -# directory to store reports, e.g. in a subdirectory -REPORTS="testreports" - -# publish report on WWW Server (not needed for local tests) -# may be no|yes -PUBLISH="no" -# upload WWW dir on server for report publication (not used for local tests) -SERVERDIR="/var/www/html/grassgistestreports" diff --git a/testsuite/examples/test_framework_GRASS_GIS_with_NC.sh b/testsuite/examples/test_framework_GRASS_GIS_with_NC.sh deleted file mode 100755 index 808b4b9c716..00000000000 --- a/testsuite/examples/test_framework_GRASS_GIS_with_NC.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash -############################################################################ -# -# MODULE: Example script to run testsuite -# AUTHOR(S): Markus Neteler, Sören Gebbert, Vaclav Petras -# PURPOSE: Test GRASS GIS using the test framework -# Documentation: -# https://trac.osgeo.org/grass/wiki/GSoC/2014/TestingFrameworkForGRASS -# https://grass.osgeo.org/grass-devel/manuals/libpython/gunittest_running_tests.html#example-bash-script-to-run-be-used-as-a-cron-job -# -# Data: -# We use the full NC dataset (nc_spm_full_v2_alpha.tar.gz) -# -# COPYRIGHT: (C) 2019-2021 by Markus Neteler, and the GRASS Development Team -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -############################################################################ - -### Fetch CONFIGURATION - -CONF="test_framework_GRASS_GIS_with_NC.conf" - -usage_msg(){ -echo "Usage: - $0 [conf_file] - -Example: - $0 ./${CONF} -" -} - -if [ ! -z "$1" ] ; then - case "$1" in - -h | --h | -help | --help) - usage_msg - exit 0 - ;; - *) - if [ -f ${1} ] ; then - CONF="$1" - else - echo "ERROR: $1 is not a file" - exit 1 - fi - ;; - esac -else - usage_msg - exit 0 -fi - -source ${CONF} - -######### nothing to change below - -set -e # fail fast - -# computer architecture: -ARCH=`${GRASSBIN} --config arch` - -# here we suppose default compilation settings of GRASS GIS and no make install -GRASSBIN="$GRASSSRC/bin.${ARCH}/${GRASSBIN}" -GRASSDIST="$GRASSSRC/dist.${ARCH}" - -# necessary hardcoded GRASS paths -GRASSDIST_PYTHON="$GRASSDIST/etc/python" -GRASS_MULTI_RUNNER="$GRASSSRC/python/grass/gunittest/multirunner.py" -GRASS_MULTI_REPORTER="$GRASSSRC/python/grass/gunittest/multireport.py" - -DATE_FLAGS="--utc +%Y-%m-%d-%H-%M" -NOW=$(date $DATE_FLAGS) - -# get number of processors of current machine -MYNPROC=`getconf _NPROCESSORS_ONLN` -# leave some free for other tasks -GCCTHREADS=`expr $MYNPROC - $FREECPU` -if [ $GCCTHREADS -lt 1 ] ; then - GCCTHREADS=1 -fi - -# contains last executed command stdout and stderr -# here were rely on reports being absolute -OUTPUT_LOGFILE="$REPORTS/output-$NOW.txt" - -# these are relative to REPORTS -CURRENT_REPORT_BASENAME="reports_for_date-" -FINAL_REPORT_DIR="summary_report" -CURRENT_REPORTS_DIR="$CURRENT_REPORT_BASENAME$NOW" -LOGFILE="$REPORTS/runs.log" - -mkdir -p $REPORTS/$CURRENT_REPORTS_DIR -mkdir -p $GRASSDATA - -# fetch sample data -SAMPLEDATA=nc_spm_full_v2alpha -(cd $GRASSDATA ; wget -c https://grass.osgeo.org/sampledata/north_carolina/$SAMPLEDATA.tar.gz ; tar xfz $SAMPLEDATA.tar.gz --strip-components 2) - -set -x - -echo "Testing of GRASS GIS started: $NOW" >> ${LOGFILE} - -if [ "$COMPILE" = "yes" ] ; then - ## compile current source code from scratch - cd $GRASSSRC - make distclean -j$GCCTHREADS - git pull - ./$CONFIGURE ... # configure meta script containing all the compiler flags - make -j$GCCTHREADS -fi - -# run tests for the current source code -cd $REPORTS/$CURRENT_REPORTS_DIR -$PYTHON $GRASS_MULTI_RUNNER \ - --grassbin $GRASSBIN \ - --grasssrc $GRASSSRC \ - --grassdata $GRASSDATA \ - --location $SAMPLEDATA --location-type nc # \ -# --location other_location --location-type other_type - -# create overall report of all so far executed tests -# the script depends on GRASS but just Python part is enough -export PYTHONPATH="$GRASSDIST_PYTHON:$PYTHONPATH" -$PYTHON $GRASS_MULTI_REPORTER --output $FINAL_REPORT_DIR \ - $CURRENT_REPORT_BASENAME*/* - -# publish on Web site -if [ "$PUBLISH" = "yes" ] ; then - ## although we cannot be sure the tests were executed was successfully - ## so publish or archive results - rsync -rtvu --delete $REPORTS/ $SERVERDIR -fi - -echo "Nightly ($NOW) GRASS GIS test finished: $(date $DATE_FLAGS)" >> ${LOGFILE} - -exit 0 diff --git a/testsuite/raster/Makefile b/testsuite/raster/Makefile deleted file mode 100644 index 21c1f8eb6c0..00000000000 --- a/testsuite/raster/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -all: - ./raster_md5test.sh - ./rmapcalc_test.sh diff --git a/testsuite/raster/README b/testsuite/raster/README deleted file mode 100644 index bc5b0940789..00000000000 --- a/testsuite/raster/README +++ /dev/null @@ -1 +0,0 @@ -Raster map tests go here diff --git a/testsuite/raster/rhemisphere.sh b/testsuite/raster/rhemisphere.sh deleted file mode 100755 index e312f7b36d1..00000000000 --- a/testsuite/raster/rhemisphere.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -# Markus Neteler, 2006 -# This program is free software under the GNU General Public -# License (>=v2). Read the file COPYING that comes with GRASS -# for details. -# Test cases for 2D raster data -# generate a hemisphere to test slope, aspect, curvatures - -# some definitions: -BOXLENGTH=1000 # side length of test area -RADIUS=500 # half BOXLENGTH - -############ - -if [ -z "$GISBASE" ] ; then - echo "You must be in GRASS GIS to run this program." >&2 - exit 1 -fi - -# some functions - keep order here -TMP="disk.$$" - -cleanup() -{ - echo "Removing temporary map" - g.remove --q -f type=raster name=$TMP > /dev/null -} - -######################## - -g.region n=$BOXLENGTH s=0 w=0 e=$BOXLENGTH -p res=1 - -X="(col() - $RADIUS)" -Y="($RADIUS - row())" -r="sqrt($X^2 + $Y^2)" - -#Mask out unwanted parts (check for <= ??): -r.mapcalc "$TMP = if($r<$RADIUS,$r,null())" - -ALPHA="acos ($TMP/$RADIUS)" -HEIGHT="$RADIUS * sin($ALPHA)" - - -r.mapcalc "hemisphere = $HEIGHT" -cleanup -g.message "Generated raster map " -#echo "Now generate aspect + slope on " diff --git a/testsuite/raster/raster_md5test.sh b/testsuite/raster_md5test.sh similarity index 100% rename from testsuite/raster/raster_md5test.sh rename to testsuite/raster_md5test.sh diff --git a/testsuite/vector/v.in.gps_test.sh b/testsuite/vector/v.in.gps_test.sh deleted file mode 100755 index 62b2f5b651c..00000000000 --- a/testsuite/vector/v.in.gps_test.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# v.in.garmin and v.in.gpsbabel test script -# by Hamish Bowman 18 May 2007 ; public domain -# assumes downloading from a garmin on port /dev/gps - -for PGM in garmin gpsbabel ; do - for DO_PTS in pts lines ; do - for TASK in w t r ; do - if [ $TASK = w ] && [ $DO_PTS = "lines" ] ; then - continue - fi - if [ $DO_PTS = "pts" ] ; then - PTFLAG="-p" - else - PTFLAG="" - fi - MAPNAME="test_${PGM}_${TASK}_${DO_PTS}_$$" - echo "-- Running [v.in.$PGM] for [$TASK] download as [$DO_PTS] into <$MAPNAME> --" - v.in.$PGM -$TASK $PTFLAG out="$MAPNAME" - if [ $? -ne 0 ] ; then - exit 1 - fi - awk 'BEGIN {printf("\n\n\n\n")}' - done - done -done From bc9cb2a3f9540b031a6b8e8e7d7257ca01492d3e Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Tue, 15 Oct 2024 19:17:08 -0400 Subject: [PATCH 36/69] doc: Use lowercase for mask (#4529) Again, use lowercase mask and other wording instead of MASK when talking about masking, similar to #4401 and #4495. It also adjusts the wording in r.topidx and i.segment. --- imagery/i.segment/i.segment.html | 2 +- imagery/i.segment/iseg.h | 2 +- ps/ps.map/r_instructions.c | 2 +- raster/r.resamp.interp/r.resamp.interp.html | 2 +- raster/r.topidx/r.topidx.html | 8 +++++--- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/imagery/i.segment/i.segment.html b/imagery/i.segment/i.segment.html index 1e2596c1d7e..e30f21d3743 100644 --- a/imagery/i.segment/i.segment.html +++ b/imagery/i.segment/i.segment.html @@ -118,7 +118,7 @@

Mean shift

Boundary Constraints

Boundary constraints limit the adjacency of pixels and segments. Each unique value present in the bounds raster are -considered as a MASK. Thus no segments in the final segmentated map +considered as a mask. Thus, no segments in the final segmented map will cross a boundary, even if their spectral data is very similar.

Minimum Segment Size

diff --git a/imagery/i.segment/iseg.h b/imagery/i.segment/iseg.h index 1e301d2cefa..a8dfb5542c3 100644 --- a/imagery/i.segment/iseg.h +++ b/imagery/i.segment/iseg.h @@ -118,7 +118,7 @@ struct globals { /* processing flags */ FLAG *candidate_flag, - *null_flag; /*TODO, need some way to remember MASK/NULL values. Was + *null_flag; /*TODO, need some way to remember mask/NULL values. Was using -1, 0, 1 in int array. Better to use 2 FLAG structures, better readability? */ diff --git a/ps/ps.map/r_instructions.c b/ps/ps.map/r_instructions.c index 0e2c012fd92..87a2e4bbfcf 100644 --- a/ps/ps.map/r_instructions.c +++ b/ps/ps.map/r_instructions.c @@ -29,7 +29,7 @@ static char *help[] = { "read unix-file eps Encapsulated PostScript file", "border [y|n] mapinfo map information", "window region definition region region definition", - "maskcolor MASK color", + "maskcolor mask color", "rectangle east north east north", "scale 1:#|# inches|# panels|1 inch = # miles", "outline map composition outline", diff --git a/raster/r.resamp.interp/r.resamp.interp.html b/raster/r.resamp.interp/r.resamp.interp.html index e4b77ac0d34..3c3eecc68a9 100644 --- a/raster/r.resamp.interp/r.resamp.interp.html +++ b/raster/r.resamp.interp/r.resamp.interp.html @@ -28,7 +28,7 @@

NOTES

Note that for bilinear, bicubic and lanczos interpolation, cells of the output raster that cannot be bounded by the appropriate number of input cell centers are set to NULL (NULL propagation). This could occur -due to the input cells being outside the current region, being NULL or MASKed. +due to the input cells being outside the current region, being NULL or masked.

For longitude-latitude coordinate reference systems, diff --git a/raster/r.topidx/r.topidx.html b/raster/r.topidx/r.topidx.html index 56dd001f20a..75938e6a231 100644 --- a/raster/r.topidx/r.topidx.html +++ b/raster/r.topidx/r.topidx.html @@ -10,12 +10,14 @@

DESCRIPTION

the local surface topographic slope (delta vertical) / (delta horizontal).
-

Input maps may have NULL values. For example, if you have a MASK for a -watershed (basin map from r.water.outlet), the following command will -create a masked elevation map (belev): +

Input maps may have NULL values. For example, if you have a raster mask set +for a watershed (using basin map from r.water.outlet), the following +command will create a masked elevation map (belev): +

 r.mapcalc "belev = if(isnull(basin), basin, elev)"
 
+

r.stats -Anc prints out averaged statistics for topographic index. From 241589424d9612b913ef7f5502839ee6ab2151bc Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Wed, 16 Oct 2024 04:08:22 -0400 Subject: [PATCH 37/69] r.in.gridatb: check if opening of file succeeds (#4532) --- raster/r.in.gridatb/file_io.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/raster/r.in.gridatb/file_io.c b/raster/r.in.gridatb/file_io.c index 256f9869473..52ad174df4d 100644 --- a/raster/r.in.gridatb/file_io.c +++ b/raster/r.in.gridatb/file_io.c @@ -12,6 +12,9 @@ void rdwr_gridatb(void) float idx; fp = fopen(file, "r"); + if (!fp) { + G_fatal_error(_("Unable to open file: %s"), file); + } buf[0] = 0; if (fscanf(fp, "%[^\n]", buf) != 1) From 362bee3ae66cec995805e355bb40cffe75c838f7 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Wed, 16 Oct 2024 09:27:43 -0400 Subject: [PATCH 38/69] grass.script: Fixed E722 in v.what.shrds/ (#4530) --- .flake8 | 2 +- scripts/v.what.strds/v.what.strds.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index c01dc46b255..6bfcc1e5527 100644 --- a/.flake8 +++ b/.flake8 @@ -115,7 +115,7 @@ per-file-ignores = scripts/r.in.srtm/r.in.srtm.py: E722 scripts/r.fillnulls/r.fillnulls.py: E722 scripts/d.rast.edit/d.rast.edit.py: E722 - scripts/v.what.strds/v.what.strds.py: E722, E501 + scripts/v.what.strds/v.what.strds.py: E501 # Line too long (esp. module interface definitions) scripts/*/*.py: E501 temporal/t.rast.to.vect/t.rast.to.vect.py: E501 diff --git a/scripts/v.what.strds/v.what.strds.py b/scripts/v.what.strds/v.what.strds.py index 0e1bf893f98..8be00f3536d 100644 --- a/scripts/v.what.strds/v.what.strds.py +++ b/scripts/v.what.strds/v.what.strds.py @@ -225,7 +225,7 @@ def main(): pymap = Vector(output) try: pymap.open("r") - except: + except Exception: dbif.close() gs.fatal(_("Unable to create vector map <%s>") % output) From 39ff021208e8cbca0615c3545ffa9d191e149e88 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 17 Oct 2024 10:49:45 -0400 Subject: [PATCH 39/69] wxGUI: Fixed F841 in mapwindow.py (#4538) --- gui/wxpython/nviz/mapwindow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gui/wxpython/nviz/mapwindow.py b/gui/wxpython/nviz/mapwindow.py index 8cf972704e2..1eea5b278a9 100644 --- a/gui/wxpython/nviz/mapwindow.py +++ b/gui/wxpython/nviz/mapwindow.py @@ -412,7 +412,7 @@ def OnPaint(self, event): Debug.msg(1, "GLCanvas.OnPaint()") self.render["overlays"] = True - dc = wx.PaintDC(self) + wx.PaintDC(self) self.DoPaint() def DoPaint(self): @@ -1438,7 +1438,7 @@ def UnloadDataLayers(self, force=False): GError(parent=self, message=e.value) if force and self.baseId > 0: # unload base surface when quitting - ret = self._display.UnloadSurface(self.baseId) + self._display.UnloadSurface(self.baseId) self.baseId = -1 if update: self.lmgr.nviz.UpdateSettings() @@ -2134,10 +2134,10 @@ def UpdateVolumeProperties(self, id, data, isosurfId=None): # sliceId = 0 for slice in data["slice"]: - ret = self._display.AddSlice(id, slice_id=sliceId) + self._display.AddSlice(id, slice_id=sliceId) if "update" in slice["position"]: pos = slice["position"] - ret = self._display.SetSlicePosition( + self._display.SetSlicePosition( id, sliceId, pos["x1"], From a740da1d4a638c0e129ac95e7c298961f06f3111 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 17 Oct 2024 10:51:50 -0400 Subject: [PATCH 40/69] wxGUI: Added TypeError to lmgr/ (#4537) --- gui/wxpython/lmgr/frame.py | 6 +++--- gui/wxpython/lmgr/layertree.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gui/wxpython/lmgr/frame.py b/gui/wxpython/lmgr/frame.py index 2413d3b7c4a..963a36e3a58 100644 --- a/gui/wxpython/lmgr/frame.py +++ b/gui/wxpython/lmgr/frame.py @@ -1135,7 +1135,7 @@ def GetMenuCmd(self, event): layer = self.GetLayerTree().layer_selected name = self.GetLayerTree().GetLayerInfo(layer, key="maplayer").name type = self.GetLayerTree().GetLayerInfo(layer, key="type") - except AttributeError: + except (AttributeError, TypeError): layer = None if layer and len(cmdlist) == 1: # only if no parameters given @@ -1183,7 +1183,7 @@ def OnVDigit(self, event): # available only for vector map layers try: mapLayer = tree.GetLayerInfo(layer, key="maplayer") - except AttributeError: + except (AttributeError, TypeError): mapLayer = None if not mapLayer or mapLayer.GetType() != "vector": @@ -1860,7 +1860,7 @@ def OnShowAttributeTable(self, event, selection=None): # available only for vector map layers try: maptype = tree.GetLayerInfo(layer, key="maplayer").type - except AttributeError: + except (AttributeError, TypeError): maptype = None if not maptype or maptype != "vector": diff --git a/gui/wxpython/lmgr/layertree.py b/gui/wxpython/lmgr/layertree.py index 86531bcb5ad..855896e35ab 100644 --- a/gui/wxpython/lmgr/layertree.py +++ b/gui/wxpython/lmgr/layertree.py @@ -1758,7 +1758,7 @@ def OnDeleteLayer(self, event): try: if self.GetLayerInfo(item, key="type") != "group": self.Map.DeleteLayer(self.GetLayerInfo(item, key="maplayer")) - except AttributeError: + except (AttributeError, TypeError): pass # redraw map if auto-rendering is enabled @@ -2399,7 +2399,7 @@ def __FindSubItemByName(self, item, value): while item and item.IsOk(): try: itemLayer = self.GetLayerInfo(item, key="maplayer") - except KeyError: + except (KeyError, TypeError): return None if itemLayer and value == itemLayer.GetName(): From 4e8b0bf5e890f398b528f630c112b86b5a6d9471 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 17 Oct 2024 11:01:06 -0400 Subject: [PATCH 41/69] wxGUI: Fixed F841 in modules/ (#4528) --- .flake8 | 2 +- gui/wxpython/modules/histogram.py | 1 - gui/wxpython/modules/import_export.py | 11 ++--------- gui/wxpython/modules/mapsets_picker.py | 2 +- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.flake8 b/.flake8 index 6bfcc1e5527..dfc22985b42 100644 --- a/.flake8 +++ b/.flake8 @@ -24,7 +24,7 @@ per-file-ignores = doc/python/m.distance.py: E501 gui/scripts/d.wms.py: E501 gui/wxpython/image2target/g.gui.image2target.py: E501 - gui/wxpython/modules/*: F841, E722 + gui/wxpython/modules/*: E722 gui/wxpython/nviz/*: F841, E266, E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 diff --git a/gui/wxpython/modules/histogram.py b/gui/wxpython/modules/histogram.py index 92510406ac7..c8001858dff 100644 --- a/gui/wxpython/modules/histogram.py +++ b/gui/wxpython/modules/histogram.py @@ -496,7 +496,6 @@ def SaveToFile(self, event): def PrintMenu(self, event): """Print options and output menu""" - point = wx.GetMousePosition() printmenu = Menu() # Add items to the menu setup = wx.MenuItem(printmenu, id=wx.ID_ANY, text=_("Page setup")) diff --git a/gui/wxpython/modules/import_export.py b/gui/wxpython/modules/import_export.py index f2f70e47831..a0bd17e289c 100644 --- a/gui/wxpython/modules/import_export.py +++ b/gui/wxpython/modules/import_export.py @@ -461,7 +461,6 @@ def OnRun(self, event): dsn = self.dsnInput.GetDsn() if not dsn: return - ext = self.dsnInput.GetFormatExt() for layer, output, listId in data: userData = {} @@ -613,7 +612,7 @@ def OnRun(self, event): return if not data: - GMessage(_("No layers selected. Operation canceled."), parent=self) + GMessage(parent=self, message=_("No layers selected. Operation canceled.")) return if not self._validateOutputMapName(): @@ -644,13 +643,7 @@ def OnRun(self, event): if ext and layer.rfind(ext) > -1: layer = layer.replace("." + ext, "") if "|" in layer: - layer, geometry = layer.split("|", 1) - else: - geometry = None - - # TODO: v.import has no geometry option - # if geometry: - # cmd.append('geometry=%s' % geometry) + layer = layer.split("|", 1)[0] cmd = self.getSettingsPageCmd() cmd.append("input=%s" % dsn) diff --git a/gui/wxpython/modules/mapsets_picker.py b/gui/wxpython/modules/mapsets_picker.py index e7ea7a3e40a..73df8fde3cc 100755 --- a/gui/wxpython/modules/mapsets_picker.py +++ b/gui/wxpython/modules/mapsets_picker.py @@ -12,7 +12,7 @@ def main(): - app = wx.App() + wx.App() dlg = MapsetAccess(parent=None) dlg.CenterOnScreen() From 941b52f87c44e6f19b3be960553d37deb7c0f1e8 Mon Sep 17 00:00:00 2001 From: Anna Petrasova Date: Thu, 17 Oct 2024 11:02:44 -0400 Subject: [PATCH 42/69] GUI: fix crashing due to File menu translation issues (#4513) --- gui/wxpython/lmgr/workspace.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/gui/wxpython/lmgr/workspace.py b/gui/wxpython/lmgr/workspace.py index 774c22bf4ed..b1e7aa400f0 100644 --- a/gui/wxpython/lmgr/workspace.py +++ b/gui/wxpython/lmgr/workspace.py @@ -519,12 +519,20 @@ def CreateRecentFilesMenu(self, menu=None): :return None """ if menu: - file_menu = menu.GetMenu( - menuIndex=menu.FindMenu(title=_("File")), - ) - workspace_item = file_menu.FindItem( - id=file_menu.FindItem(itemString=_("Workspace")), - )[0] + menu_index = menu.FindMenu(_("File")) + if menu_index == wx.NOT_FOUND: + # try untranslated version + menu_index = menu.FindMenu("File") + if menu_index == wx.NOT_FOUND: + return + file_menu = menu.GetMenu(menu_index) + workspace_index = file_menu.FindItem(_("Workspace")) + if workspace_index == wx.NOT_FOUND: + workspace_index = file_menu.FindItem("Workspace") + if workspace_index == wx.NOT_FOUND: + return + workspace_item = file_menu.FindItemById(workspace_index) + self._recent_files = RecentFilesMenu( app_name="main", parent_menu=workspace_item.GetSubMenu(), From fd347b9e837a6903d1f917bd56edd3aa8a9995ba Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 17 Oct 2024 14:25:48 -0400 Subject: [PATCH 43/69] wxGUI: Fixed F841 in tools.py (#4539) --- .flake8 | 4 ++-- gui/wxpython/nviz/tools.py | 21 +++------------------ 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/.flake8 b/.flake8 index dfc22985b42..afe61c74642 100644 --- a/.flake8 +++ b/.flake8 @@ -24,8 +24,8 @@ per-file-ignores = doc/python/m.distance.py: E501 gui/scripts/d.wms.py: E501 gui/wxpython/image2target/g.gui.image2target.py: E501 - gui/wxpython/modules/*: E722 - gui/wxpython/nviz/*: F841, E266, E722, F403, F405 + gui/wxpython/modules/*: F841, E722 + gui/wxpython/nviz/*: E266, E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 gui/wxpython/psmap/*: F841, E266, E722, F405, F403 diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py index 20b1df1ffbd..153f8ffef86 100644 --- a/gui/wxpython/nviz/tools.py +++ b/gui/wxpython/nviz/tools.py @@ -667,7 +667,6 @@ def _createAnimationPage(self): parent=panel, id=wx.ID_ANY, label=" %s " % (_("Save image sequence")) ) boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL) - vSizer = wx.BoxSizer(wx.VERTICAL) gridSizer = wx.GridBagSizer(vgap=5, hgap=10) pwd = str(Path.cwd()) @@ -2817,7 +2816,6 @@ def OnAnimationFinished(self, mode): self.UpdateFrameIndex(index=0) slider = self.FindWindowById(self.win["anim"]["frameIndex"]["slider"]) - text = self.FindWindowById(self.win["anim"]["frameIndex"]["text"]) if mode == "record": count = anim.GetFrameCount() @@ -2922,7 +2920,7 @@ def OnConstantSelection(self, event): layerIdx = self.FindWindowById(self.win["constant"]["surface"]).GetSelection() if layerIdx == wx.NOT_FOUND: return - name = _("constant#") + str(layerIdx + 1) + data = self.mapWindow.constants[layerIdx] for attr, value in data["constant"].items(): if attr == "color": @@ -3123,8 +3121,6 @@ def _createIsosurfacePanel(self, parent): def _createSlicePanel(self, parent): panel = wx.Panel(parent=parent, id=wx.ID_ANY) - vSizer = wx.BoxSizer(wx.HORIZONTAL) - box = StaticBox( parent=panel, id=wx.ID_ANY, label=" %s " % (_("Slice attributes")) ) @@ -3412,12 +3408,11 @@ def OnSetSurface(self, event): """Surface selected, currently used for fringes""" name = event.GetString() try: - data = self._getLayerPropertiesByName(name, mapType="raster")["surface"] + self._getLayerPropertiesByName(name, mapType="raster")["surface"] except: self.EnablePage("fringe", False) return - layer = self._getMapLayerByName(name, mapType="raster") self.EnablePage("fringe", True) def OnSetRaster(self, event): @@ -3425,7 +3420,7 @@ def OnSetRaster(self, event): name = event.GetString() try: data = self._getLayerPropertiesByName(name, mapType="raster")["surface"] - except TypeError as e: + except TypeError: self.EnablePage("surface", False) return @@ -4590,10 +4585,6 @@ def OnVolumeSelect(self, event): if not winUp.IsEnabled(): winUp.Enable() - # update dialog - name = self.FindWindowById(self.win["volume"]["map"]).GetValue() - layer = self._getMapLayerByName(name, mapType="raster_3d") - if mode == "isosurf": data = self.GetLayerData("volume")["volume"]["isosurface"][selection] self.UpdateVolumeIsosurfPage(data) @@ -4694,8 +4685,6 @@ def OnVolumeDelete(self, event): if list.GetCount() > 0: list.SetSelection(list.GetCount() - 1) - name = self.FindWindowById(self.win["volume"]["map"]).GetValue() - layer = self._getMapLayerByName(name, mapType="raster_3d") data = self.GetLayerData("volume")["volume"] vid = data["object"]["id"] @@ -4736,8 +4725,6 @@ def OnVolumeMoveUp(self, event): if sel < 1: return # this should not happen - name = self.FindWindowById(self.win["volume"]["map"]).GetValue() - layer = self._getMapLayerByName(name, mapType="raster_3d") data = self.GetLayerData("volume")["volume"] id = data["object"]["id"] @@ -4776,8 +4763,6 @@ def OnVolumeMoveDown(self, event): if sel >= list.GetCount() - 1: return # this should not happen - name = self.FindWindowById(self.win["volume"]["map"]).GetValue() - layer = self._getMapLayerByName(name, mapType="raster_3d") data = self.GetLayerData("volume")["volume"] id = data["object"]["id"] From daee9896da48bced7d59cfb998952f7ff6e2245b Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 17 Oct 2024 14:27:05 -0400 Subject: [PATCH 44/69] wxGUI: Fixed F405 in psmap/ (#4541) --- .flake8 | 2 +- gui/wxpython/psmap/dialogs.py | 53 +++++++++++++++++++++------ gui/wxpython/psmap/frame.py | 57 +++++++++++++++++++++--------- gui/wxpython/psmap/instructions.py | 20 ++++++++--- 4 files changed, 100 insertions(+), 32 deletions(-) diff --git a/.flake8 b/.flake8 index afe61c74642..5c23d51bd36 100644 --- a/.flake8 +++ b/.flake8 @@ -28,7 +28,7 @@ per-file-ignores = gui/wxpython/nviz/*: E266, E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 - gui/wxpython/psmap/*: F841, E266, E722, F405, F403 + gui/wxpython/psmap/*: F841, E266, E722 gui/wxpython/vdigit/*: F841, E722, F405, F403 gui/wxpython/vnet/*: F841 gui/wxpython/wxgui.py: F841 diff --git a/gui/wxpython/psmap/dialogs.py b/gui/wxpython/psmap/dialogs.py index 66ac66d9348..0bbe779818a 100644 --- a/gui/wxpython/psmap/dialogs.py +++ b/gui/wxpython/psmap/dialogs.py @@ -42,9 +42,8 @@ import wx import wx.lib.agw.floatspin as fs -from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin - from core import globalvar +from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin if globalvar.wxPythonPhoenix: from wx import Validator @@ -52,24 +51,25 @@ from wx import PyValidator as Validator import grass.script as gs - -from core.utils import PilImageToWxImage +from core.gcmd import GError, GMessage, RunCommand +from core.utils import PilImageToWxImage, cmp from dbmgr.vinfo import VectorDBInfo -from gui_core.gselect import Select -from core.gcmd import RunCommand, GError, GMessage from gui_core.dialogs import SymbolDialog +from gui_core.gselect import Select from gui_core.wrap import ( BitmapButton, BitmapComboBox, BitmapFromImage, Button, CheckBox, + CheckListCtrlMixin, Choice, ClientDC, ColourPickerCtrl, Dialog, DirBrowseButton, EmptyBitmap, + EmptyImage, ExpandoTextCtrl, FileBrowseButton, FloatSpin, @@ -86,11 +86,44 @@ StaticText, TextCtrl, TextEntryDialog, - EmptyImage, - CheckListCtrlMixin, ) -from psmap.utils import * -from psmap.instructions import * + +# Explicit imports from psmap.instructions +from psmap.instructions import ( + Image, + Labels, + Line, + MapFrame, + Mapinfo, + NewId, + NorthArrow, + Point, + Raster, + RasterLegend, + Rectangle, + Scalebar, + Text, + Vector, + VectorLegend, + VProperties, +) + +# Explicit imports from psmap.utils +from psmap.utils import ( + AutoAdjust, + BBoxAfterRotation, + ComputeSetRegion, + PaperMapCoordinates, + PILImage, + Rect2D, + Rect2DPP, + SetResolution, + UnitConversion, + convertRGB, + getRasterType, + havePILImage, + projInfo, +) # grass.set_raise_on_error(True) diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index b3196d348fa..13fdc91a984 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -16,10 +16,9 @@ """ import os -import sys - import queue as Queue -from math import sin, cos, pi, sqrt +import sys +from math import cos, pi, sin, sqrt import wx @@ -29,25 +28,51 @@ import wx.lib.flatnotebook as FN import grass.script as gs - from core import globalvar -from gui_core.menu import Menu -from core.gconsole import CmdThread, EVT_CMD_DONE -from psmap.toolbars import PsMapToolbar -from core.gcmd import RunCommand, GError, GMessage +from core.gcmd import GError, GMessage, RunCommand +from core.gconsole import EVT_CMD_DONE, CmdThread from core.settings import UserSettings from core.utils import PilImageToWxImage -from gui_core.forms import GUI -from gui_core.widgets import GNotebook from gui_core.dialogs import HyperlinkDialog +from gui_core.forms import GUI from gui_core.ghelp import ShowAboutDialog -from gui_core.wrap import ClientDC, PseudoDC, Rect, StockCursor, EmptyBitmap -from psmap.menudata import PsMapMenuData +from gui_core.menu import Menu from gui_core.toolbars import ToolSwitcher - -from psmap.dialogs import * -from psmap.instructions import * -from psmap.utils import * +from gui_core.widgets import GNotebook +from gui_core.wrap import ClientDC, EmptyBitmap, PseudoDC, Rect, StockCursor + +from psmap.dialogs import ( + ImageDialog, + LabelsDialog, + LegendDialog, + MainVectorDialog, + MapDialog, + MapinfoDialog, + NorthArrowDialog, + PageSetupDialog, + PointDialog, + RasterDialog, + RectangleDialog, + ScalebarDialog, + TextDialog, +) +from psmap.instructions import InitMap, Instruction, NewId, SetResolution, PageSetup +from psmap.menudata import PsMapMenuData +from psmap.toolbars import PsMapToolbar +from psmap.utils import ( + AutoAdjust, + ComputeSetRegion, + GetMapBounds, + PaperMapCoordinates, + PILImage, + Rect2D, + Rect2DPP, + Rect2DPS, + UnitConversion, + convertRGB, + havePILImage, + projInfo, +) class PsMapFrame(wx.Frame): diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py index 9db64679422..845e99b2e6a 100644 --- a/gui/wxpython/psmap/instructions.py +++ b/gui/wxpython/psmap/instructions.py @@ -35,17 +35,27 @@ import os import string from math import ceil -from time import strftime, localtime +from time import localtime, strftime -import wx import grass.script as gs -from grass.script.task import cmdlist_to_tuple - +import wx from core.gcmd import GError, GMessage, GWarning from core.utils import GetCmdString from dbmgr.vinfo import VectorDBInfo +from grass.script.task import cmdlist_to_tuple from gui_core.wrap import NewId as wxNewId -from psmap.utils import * + +from psmap.utils import ( # Add any additional required names from psmap.utils here + BBoxAfterRotation, + GetMapBounds, + PaperMapCoordinates, + Rect2D, + Rect2DPP, + SetResolution, + UnitConversion, + getRasterType, + projInfo, +) def NewId(): From 0adc4dc2ec42e07c82012fb948b0b9cac4b4afb3 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Thu, 17 Oct 2024 14:29:38 -0400 Subject: [PATCH 45/69] wxGUI: Fixed unused variable F841 (#4542) --- .flake8 | 1 - gui/wxpython/wxgui.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index 5c23d51bd36..92611007661 100644 --- a/.flake8 +++ b/.flake8 @@ -31,7 +31,6 @@ per-file-ignores = gui/wxpython/psmap/*: F841, E266, E722 gui/wxpython/vdigit/*: F841, E722, F405, F403 gui/wxpython/vnet/*: F841 - gui/wxpython/wxgui.py: F841 gui/wxpython/animation/g.gui.animation.py: E501 gui/wxpython/tplot/frame.py: F841, E722 gui/wxpython/tplot/g.gui.tplot.py: E501 diff --git a/gui/wxpython/wxgui.py b/gui/wxpython/wxgui.py index 447821c6724..8fac39c4d5a 100644 --- a/gui/wxpython/wxgui.py +++ b/gui/wxpython/wxgui.py @@ -164,7 +164,7 @@ def main(argv=None): app = GMApp(workspaceFile) # suppress wxPython logs - q = wx.LogNull() + wx.LogNull() set_raise_on_error(True) # register GUI PID From e540efc76618837947fefca21d8b141913ff6376 Mon Sep 17 00:00:00 2001 From: Ivan Mincik Date: Thu, 17 Oct 2024 19:48:24 +0000 Subject: [PATCH 46/69] nix: Fix locales in development environment (#4540) This fixes locales in nix provided development environment by setting environment variable. Closes #4503 --- flake.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flake.nix b/flake.nix index 51174e1da74..a105607417f 100644 --- a/flake.nix +++ b/flake.nix @@ -34,6 +34,8 @@ pytest ]; + LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive"; + shellHook = '' function dev-help { echo -e "\nWelcome to a GRASS development environment !" From 9dbc8c96b05eaff6df9dc2ffd55c7e8f45fa25e9 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Thu, 17 Oct 2024 23:33:50 +0200 Subject: [PATCH 47/69] docs: add intro text to imageryintro.html (#4536) This PR adds an overview text to imageryintro.html including a link to addons. (aside, addons URL fix in g.gui.gmodeler.html) Co-authored-by: Nicklas Larsson Co-authored-by: Vaclav Petras --- gui/wxpython/gmodeler/g.gui.gmodeler.html | 2 +- imagery/imageryintro.html | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gui/wxpython/gmodeler/g.gui.gmodeler.html b/gui/wxpython/gmodeler/g.gui.gmodeler.html index 631c06de9d8..a840768abeb 100644 --- a/gui/wxpython/gmodeler/g.gui.gmodeler.html +++ b/gui/wxpython/gmodeler/g.gui.gmodeler.html @@ -466,7 +466,7 @@

SEE ALSO

See also selected user models available from -GRASS Addons repository. +GRASS Addons repository.

See also diff --git a/imagery/imageryintro.html b/imagery/imageryintro.html index 4b80951af9e..9018b4871ae 100644 --- a/imagery/imageryintro.html +++ b/imagery/imageryintro.html @@ -2,6 +2,21 @@

Image processing in general

+GRASS GIS provides a powerful suite of tools for the processing and +analysis of geospatial raster data, including satellite imagery and +aerial photography. Its image processing capabilities encompass a broad +range of preprocessing operations, such as data import, georeferencing, +radiometric calibration, and atmospheric correction. It is particularly +suited for handling Earth observation data, enabling the analysis of +multispectral and temporal datasets. GRASS GIS supports advanced +functionalities such as image classification, sensor fusion, and point +cloud statistics. The calculation of vegetation indices further enables +analyses of environmental, agricultural, and land cover dynamics. An +extensive collection of +addons +further enhances its image processing capabilities, particularly in the +context of Earth observation and remote sensing applications. + Digital numbers and physical values (reflection/radiance-at-sensor):

Satellite imagery is commonly stored in Digital Numbers (DN) for From 37d40827fce95fc0e1231616d621f6bb496172ba Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Thu, 17 Oct 2024 23:44:17 +0200 Subject: [PATCH 48/69] GUI: EPSG code source: replace epsg.io with spatialreference.org (#4535) As epsg.io is partially outdated (see [source](https://github.com/maptiler/epsg.io/issues/171) and related) and PROJ is our engine anyway, this PR switches the references in the GUI to https://spatialreference.org. * "See also" section: added URLs to CRS Explorer and EPSG Geodetic Parameter Dataset Co-authored-by: Vaclav Petras --- gui/wxpython/location_wizard/wizard.py | 11 +++++++---- lib/init/helptext.html | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py index d8b6b4180ba..1f8de66dda6 100644 --- a/gui/wxpython/location_wizard/wizard.py +++ b/gui/wxpython/location_wizard/wizard.py @@ -1604,9 +1604,12 @@ def __init__(self, wizard, parent): self, data=None, columns=[_("Code"), _("Description"), _("Parameters")] ) - # epsg.io hyperlink + # A hyperlink to a CRS database (PROJ related) self.tlink = HyperlinkCtrl( - self, id=wx.ID_ANY, label="epsg.io", url="https://epsg.io/" + self, + id=wx.ID_ANY, + label="spatialreference.org", + url="https://spatialreference.org/", ) self.tlink.SetNormalColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)) self.tlink.SetVisitedColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)) @@ -1688,14 +1691,14 @@ def EnableNext(self, enable=True): def OnTextChange(self, event): value = self.searchb.GetValue() if value == "": - self.tlink.SetURL("https://epsg.io/") + self.tlink.SetURL("https://spatialreference.org/") self.epsgcode = None self.epsgdesc = self.epsgparams = "" self.searchb.ChangeValue("") self.OnBrowseCodes(None) self.EnableNext(False) else: - self.tlink.SetURL(str("https://epsg.io/?q={0}".format(value))) + self.tlink.SetURL(f"https://spatialreference.org/ref/?&search={value}") data = self.epsglist.Search(index=[0, 1, 2], pattern=value, firstOnly=False) if data: index = 0 diff --git a/lib/init/helptext.html b/lib/init/helptext.html index d988b6b0376..4a14dd52df1 100644 --- a/lib/init/helptext.html +++ b/lib/init/helptext.html @@ -62,7 +62,7 @@

GRASS started in the default project, now what?

Creating a New project with the Project Wizard

If you know the CRS of your data or study area, -you can fill EPSG code +you can fill EPSG code or description and Project Wizard finds appropriate CRS from a predefined list of projections. @@ -97,4 +97,6 @@

See also

- List of EPSG codes (Database of worldwide coordinate systems) + List of EPSG codes (Database of worldwide coordinate systems), + CRS Explorer - PROJ codes, and + EPSG Geodetic Parameter Dataset From 3c678251df9b4dbe30c6cef2f075eeea18efa1df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 01:47:57 +0000 Subject: [PATCH 49/69] CI(deps): Update ruff to v0.7.0 (#4544) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * CI(deps): Update ruff to v0.7.0 * style: Fix FURB156: Use of hardcoded string charset --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Edouard Choinière <27212526+echoix@users.noreply.github.com> --- .github/workflows/python-code-quality.yml | 2 +- .pre-commit-config.yaml | 2 +- gui/wxpython/core/utils.py | 3 ++- gui/wxpython/gui_core/goutput.py | 3 ++- python/grass/imaging/images2ims.py | 3 ++- scripts/d.rast.edit/d.rast.edit.py | 4 +++- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index 886cbe56b47..9f71c28e922 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -36,7 +36,7 @@ jobs: # renovate: datasource=pypi depName=bandit BANDIT_VERSION: "1.7.10" # renovate: datasource=pypi depName=ruff - RUFF_VERSION: "0.6.9" + RUFF_VERSION: "0.7.0" runs-on: ${{ matrix.os }} permissions: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2c136da40ff..4c82e138950 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: ) - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.6.9 + rev: v0.7.0 hooks: # Run the linter. - id: ruff diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index 3c1b4a7dd14..2b1f3f4997a 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -20,6 +20,7 @@ import re import inspect import operator +from string import digits from grass.script import core as grass from grass.script import task as gtask @@ -936,7 +937,7 @@ def SetAddOnPath(addonPath=None, key="PATH"): def color_resolve(color): - if len(color) > 0 and color[0] in "0123456789": + if len(color) > 0 and color[0] in digits: rgb = tuple(map(int, color.split(":"))) label = color else: diff --git a/gui/wxpython/gui_core/goutput.py b/gui/wxpython/gui_core/goutput.py index 3c8927f2233..6676eb69935 100644 --- a/gui/wxpython/gui_core/goutput.py +++ b/gui/wxpython/gui_core/goutput.py @@ -20,6 +20,7 @@ """ import textwrap +from string import digits import wx from wx import stc @@ -624,7 +625,7 @@ def AddStyledMessage(self, message, style=None): self.linePos = self.GetCurrentPos() if c != " ": last_c = c - if last_c not in ("0123456789"): + if last_c not in (digits): self.AddTextWrapped("\n", wrap=None) self.linePos = -1 else: diff --git a/python/grass/imaging/images2ims.py b/python/grass/imaging/images2ims.py index a5cee9b49de..d86a2247952 100644 --- a/python/grass/imaging/images2ims.py +++ b/python/grass/imaging/images2ims.py @@ -32,6 +32,7 @@ import os from operator import itemgetter +from string import digits try: import numpy as np @@ -117,7 +118,7 @@ def _getSequenceNumber(filename, part1, part2): # Get all numeric chars seq2 = "" for c in seq: - if c in "0123456789": + if c in digits: seq2 += c else: break diff --git a/scripts/d.rast.edit/d.rast.edit.py b/scripts/d.rast.edit/d.rast.edit.py index 6519d10c7a1..ea6cc1e46bf 100755 --- a/scripts/d.rast.edit/d.rast.edit.py +++ b/scripts/d.rast.edit/d.rast.edit.py @@ -77,6 +77,8 @@ import sys import math import atexit +from string import digits + import grass.script as gs from grass.script.setup import set_gui_path @@ -448,7 +450,7 @@ def OnClose(self, ev): def OnReturn(self, ev): self.app.brush = self.newval.GetValue() - if self.app.brush != "*" and self.app.brush.strip("0123456789") != "": + if self.app.brush != "*" and self.app.brush.strip(digits) != "": self.app.brush = "*" self.brush_update() From d788eee193b3e3a4d10194775cec9d4429802403 Mon Sep 17 00:00:00 2001 From: Mohan Yelugoti Date: Fri, 18 Oct 2024 00:31:28 -0400 Subject: [PATCH 50/69] i.atcorr: fix out of bound access in trunca, os and iso (#4493) * i.atcorr: fix out of bound access in trunca, os and iso In trunca(), under 2 if conditionals (if rumu[1] > 0.8 and rmu[1] > 0.94), k and kk values are set to -1 respectively. When these values are used to access an array, it leads to out of bound access, which is undefined behavior in c++. Similarly in os() and iso(), if `taup < h[i]` for all values, iplane would still be -1 and we would be accessing an array with this as an index, which is undefined behavior. In both cases, to avoid that, set that index to zero. This was found using cppcheck tool. Signed-off-by: Mohan Yelugoti * Update imagery/i.atcorr/computations.cpp When plane layer couldn't be determined, throw out an error and exit. Co-authored-by: Markus Metz <33666869+metzm@users.noreply.github.com> * Update imagery/i.atcorr/computations.cpp When plane layer couldn't be determined, throw out an error and exit. Co-authored-by: Markus Metz <33666869+metzm@users.noreply.github.com> * Fix clang-format issues Signed-off-by: Mohan Yelugoti --------- Signed-off-by: Mohan Yelugoti Co-authored-by: Markus Metz <33666869+metzm@users.noreply.github.com> --- imagery/i.atcorr/computations.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/imagery/i.atcorr/computations.cpp b/imagery/i.atcorr/computations.cpp index 53f8664ee06..6e5a38c5b07 100644 --- a/imagery/i.atcorr/computations.cpp +++ b/imagery/i.atcorr/computations.cpp @@ -102,14 +102,14 @@ double trunca() for (i = 0; i < 83; i++) { if (rmu[i] > 0.8) break; - k = i - 1; + k = i; } int kk = 0; for (i = 0; i < 83; i++) { if (rmu[i] > 0.94) break; - kk = i - 1; + kk = i; } double aa = @@ -118,7 +118,7 @@ double trunca() double x1 = (double)(log10(sixs_trunc.pha[kk])); double x2 = (double)acos(rmu[kk]); - for (i = kk + 1; i < 83; i++) { + for (i = kk; i < 83; i++) { double a; if (fabs(rmu[i] - 1) <= 1e-08) a = x1 - aa * x2; @@ -445,9 +445,14 @@ void os(const double tamoy, const double trmoy, const double pizmoy, /* compute position of the plane layer */ double taup = tap + trp; iplane = -1; - for (int i = 0; i <= ntp; i++) + for (int i = 0; i <= ntp; i++) { if (taup >= h[i]) iplane = i; + } + if (iplane == -1) { + G_fatal_error( + _("Position of the plane layer could not be determined")); + } /* update the layer from the end to the position to update if necessary */ @@ -1006,9 +1011,14 @@ void iso(const double tamoy, const double trmoy, const double pizmoy, /* compute position of the plane layer */ double taup = tap + trp; iplane = -1; - for (int i = 0; i <= ntp; i++) + for (int i = 0; i <= ntp; i++) { if (taup >= h[i]) iplane = i; + } + if (iplane == -1) { + G_fatal_error( + _("Position of the plane layer could not be determined")); + } /* update the layer from the end to the position to update if necessary */ From 0cb20eb612b933dc914461f6c541510213bc71e0 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 18 Oct 2024 09:18:53 -0400 Subject: [PATCH 51/69] wxGUI: Fixed F841 in vnet/ (#4543) --- .flake8 | 1 - gui/wxpython/vnet/dialogs.py | 2 -- gui/wxpython/vnet/toolbars.py | 1 - gui/wxpython/vnet/vnet_core.py | 18 ------------------ gui/wxpython/vnet/vnet_data.py | 2 +- gui/wxpython/vnet/vnet_utils.py | 1 - gui/wxpython/vnet/widgets.py | 2 -- 7 files changed, 1 insertion(+), 26 deletions(-) diff --git a/.flake8 b/.flake8 index 92611007661..306a11fe02b 100644 --- a/.flake8 +++ b/.flake8 @@ -30,7 +30,6 @@ per-file-ignores = gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 gui/wxpython/psmap/*: F841, E266, E722 gui/wxpython/vdigit/*: F841, E722, F405, F403 - gui/wxpython/vnet/*: F841 gui/wxpython/animation/g.gui.animation.py: E501 gui/wxpython/tplot/frame.py: F841, E722 gui/wxpython/tplot/g.gui.tplot.py: E501 diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index 39cf2e4ae84..8d24b08df91 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -1245,8 +1245,6 @@ def __init__( wx.Dialog.__init__(self, parent, id, title, pos, size, style) self.vnet_mgr = vnet_mgr - - maxValue = 1e8 self.parent = parent self.settings = {} diff --git a/gui/wxpython/vnet/toolbars.py b/gui/wxpython/vnet/toolbars.py index 5f80e50cd9d..d31313091fe 100644 --- a/gui/wxpython/vnet/toolbars.py +++ b/gui/wxpython/vnet/toolbars.py @@ -235,6 +235,5 @@ def __init__(self, parent, vnet_mgr): self.Realize() def _toolbarData(self): - icons = {} return self._getToolbarData(()) diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index 8dda73b6770..2e98aa2ee8f 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -459,11 +459,6 @@ def _vnetPathRunAn(self, analysis, output, params, flags, catPts): return False mapName, mapSet = ParseMapStr(self.tmpTurnAn.GetVectMapName()) - cmdCopy = [ - "g.copy", - "vector=%s,%s" % (params["input"], mapName), - "--overwrite", - ] cmdParams.append("input=" + self.tmpTurnAn.GetVectMapName()) ret, msg, err = RunCommand( @@ -550,11 +545,6 @@ def _runTurnsAn(self, analysis, output, params, flags, catPts): # create and run commands which goes to analysis thread mapName, mapSet = ParseMapStr(self.tmpTurnAn.GetVectMapName()) - cmdCopy = [ - "g.copy", - "vector=%s,%s" % (params["input"], mapName), - "--overwrite", - ] cmdParams.append("input=" + self.tmpTurnAn.GetVectMapName()) ret, msg, err = RunCommand( @@ -580,14 +570,6 @@ def _updateTtbByGlobalCosts(self, vectMapName, tlayer): # TODO get layer number do not use it directly intervals = self.turnsData["global"].GetData() - cmdUpdGlob = [ - "v.db.update", - "map=", - self.inputData["input"].GetValue(), - "layer=%d" % tlayer, - "column=cost", - ] - dbInfo = VectorDBInfo(vectMapName) table = dbInfo.GetTable(tlayer) driver, database = dbInfo.GetDbSettings(tlayer) diff --git a/gui/wxpython/vnet/vnet_data.py b/gui/wxpython/vnet/vnet_data.py index 3adc5fa64e9..f2f17b0bfb5 100644 --- a/gui/wxpython/vnet/vnet_data.py +++ b/gui/wxpython/vnet/vnet_data.py @@ -1377,7 +1377,7 @@ def SetValue(self, value, line, col): def SetUTurns(self, value): """Checked if checeBox is checed""" - useUTurns = value + self.useUTurns = value def AppendRow(self, values): self.turn_data.append(values) diff --git a/gui/wxpython/vnet/vnet_utils.py b/gui/wxpython/vnet/vnet_utils.py index f0a354691bc..e3cc11aee17 100644 --- a/gui/wxpython/vnet/vnet_utils.py +++ b/gui/wxpython/vnet/vnet_utils.py @@ -133,7 +133,6 @@ def GetNearestNodeCat(e, n, layer, tresh, vectMap): vectlib.Vect_select_lines_by_box(openedMap, byref(box), vectlib.GV_POINT, List) found = 0 - dcost = 0 Cats = POINTER(vectlib.line_cats) Cats = vectlib.Vect_new_cats_struct() diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py index ed1f2aa514c..71fcd0e0739 100644 --- a/gui/wxpython/vnet/widgets.py +++ b/gui/wxpython/vnet/widgets.py @@ -217,7 +217,6 @@ def GetCellValue(self, key, colName): if colNum < 0: return None - iColEd = self.dataTypes["colEditable"] if self.selIdxs[key][colNum] != -1: return self.selIdxs[key][colNum] @@ -230,7 +229,6 @@ def GetCellSelIdx(self, key, colName): :return: -1 if column does not has values to choose """ colNum = self._getColumnNum(colName) - iColEd = self.dataTypes["colEditable"] return self.selIdxs[key][colNum] def EditCellIndex(self, index, colName, cellData): From 6fd21a886dad53a02cbfb73fafe70eb9914b65be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 18 Oct 2024 09:39:56 -0400 Subject: [PATCH 52/69] tests: Call t.remove and g.remove once with multiple inputs as list (#4523) * t.rast.accumulate: Call t.remove with multiple inputs in test_accumulation * t.rast.accdetect: Call t.remove with multiple inputs * t.rast.univar: Call t.remove once with multiple inputs * tests: Call g.remove once with multiple names to remove One call per type, when all other arguments are the same * benchmark: Call g.remove once with multiple names to remove One call per type, when all other arguments are the same * utils/thumbnails: Call g.remove once with multiple names to remove * Use tuple for supplying multiple input maps --- imagery/i.gensig/testsuite/test_i_gensig.py | 10 +++-- imagery/i.maxlik/testsuite/test_i_maxlik.py | 11 +++-- imagery/i.vi/testsuite/test_vi.py | 14 +++---- lib/imagery/testsuite/test_imagery_sigfile.py | 9 ++-- .../testsuite/test_imagery_sigsetfile.py | 9 ++-- raster/r.contour/testsuite/test_r_contour.py | 7 ++-- .../testsuite/test_r_in_pdal_binning.py | 8 +++- .../testsuite/test_r_in_pdal_selection.py | 8 +++- raster/r.kappa/testsuite/test_r_kappa.py | 15 ++++--- .../benchmark/benchmark_r_mfilter_nprocs.py | 3 +- .../benchmark/benchmark_r_neighbors_nprocs.py | 3 +- raster/r.random/testsuite/test_r_random.py | 28 ++++++------- .../benchmark/benchmark_r_resamp_filter.py | 3 +- .../benchmark/benchmark_r_resamp_interp.py | 3 +- .../r.series/benchmark/benchmark_r_series.py | 3 +- .../benchmark/benchmark_r_slope_aspect.py | 12 +++--- .../benchmark_r_slope_aspect_memory.py | 11 +++-- raster/r.tile/testsuite/test_r_tile.py | 42 +++++-------------- .../r.univar/benchmark/benchmark_r_univar.py | 3 +- raster/r.univar/testsuite/test_r_univar.py | 11 ++--- raster3d/r3.null/testsuite/test.r3.null.sh | 9 +--- .../testsuite/test_rmapcalcsimple.py | 5 ++- .../testsuite/test_r_reclass_area.py | 8 +++- .../testsuite/test_v_rast_stats.py | 11 ++--- .../t.rast.accdetect/testsuite/test_simple.py | 3 +- .../testsuite/test_accumulation.py | 4 +- .../t.rast.series/testsuite/test_series.py | 24 +++++++---- .../testsuite/test_t_rast_univar.py | 3 +- .../t.topology/test.t.topology.reltime.sh | 3 +- .../t.vect.extract/test.t.vect.extract.sh | 3 +- utils/thumbnails.py | 9 ++-- vector/v.random/testsuite/test_v_random.py | 5 ++- .../benchmark/benchmark_v_surf_rst.py | 3 +- .../benchmark/benchmark_v_surf_rst_cv.py | 3 +- 34 files changed, 151 insertions(+), 155 deletions(-) diff --git a/imagery/i.gensig/testsuite/test_i_gensig.py b/imagery/i.gensig/testsuite/test_i_gensig.py index d75e3da2af4..836550fd1e6 100644 --- a/imagery/i.gensig/testsuite/test_i_gensig.py +++ b/imagery/i.gensig/testsuite/test_i_gensig.py @@ -92,9 +92,13 @@ def tearDownClass(cls): """Remove the temporary region and generated data""" cls.del_temp_region() shutil.rmtree(cls.sig_dir1, ignore_errors=True) - cls.runModule("g.remove", flags="f", type="raster", name=cls.b1, quiet=True) - cls.runModule("g.remove", flags="f", type="raster", name=cls.b2, quiet=True) - cls.runModule("g.remove", flags="f", type="raster", name=cls.train, quiet=True) + cls.runModule( + "g.remove", + flags="f", + type="raster", + name=(cls.b1, cls.b2, cls.train), + quiet=True, + ) def test_creation(self): """Test creating a signature""" diff --git a/imagery/i.maxlik/testsuite/test_i_maxlik.py b/imagery/i.maxlik/testsuite/test_i_maxlik.py index e7fbf6c1a79..2245d0d6d58 100644 --- a/imagery/i.maxlik/testsuite/test_i_maxlik.py +++ b/imagery/i.maxlik/testsuite/test_i_maxlik.py @@ -163,13 +163,12 @@ def tearDownClass(cls): cls.del_temp_region() shutil.rmtree(cls.sig_dir1, ignore_errors=True) shutil.rmtree(cls.sig_dir2, ignore_errors=True) - cls.runModule("g.remove", flags="f", type="raster", name=cls.b1, quiet=True) - cls.runModule("g.remove", flags="f", type="raster", name=cls.b2, quiet=True) cls.runModule( - "g.remove", flags="f", type="raster", name=cls.v1_class, quiet=True - ) - cls.runModule( - "g.remove", flags="f", type="raster", name=cls.v2_class, quiet=True + "g.remove", + flags="f", + type="raster", + name=(cls.b1, cls.b2, cls.v1_class, cls.v2_class), + quiet=True, ) cls.runModule("g.remove", flags="f", type="group", name=cls.group, quiet=True) diff --git a/imagery/i.vi/testsuite/test_vi.py b/imagery/i.vi/testsuite/test_vi.py index 0c383417257..b2160f924ed 100644 --- a/imagery/i.vi/testsuite/test_vi.py +++ b/imagery/i.vi/testsuite/test_vi.py @@ -26,14 +26,12 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - cls.runModule("g.remove", flags="f", type="raster", name="ipvi") - cls.runModule("g.remove", flags="f", type="raster", name="ndwi") - cls.runModule("g.remove", flags="f", type="raster", name="dvi") - cls.runModule("g.remove", flags="f", type="raster", name="sr") - cls.runModule("g.remove", flags="f", type="raster", name="evi") - cls.runModule("g.remove", flags="f", type="raster", name="evi2") - cls.runModule("g.remove", flags="f", type="raster", name="gari") - cls.runModule("g.remove", flags="f", type="raster", name="gemi") + cls.runModule( + "g.remove", + flags="f", + type="raster", + name="ipvi,ndwi,dvi,sr,evi,evi2,gari,gemi", + ) cls.del_temp_region() def test_vinameipvi(self): diff --git a/lib/imagery/testsuite/test_imagery_sigfile.py b/lib/imagery/testsuite/test_imagery_sigfile.py index 8d0e288561d..731ef047063 100644 --- a/lib/imagery/testsuite/test_imagery_sigfile.py +++ b/lib/imagery/testsuite/test_imagery_sigfile.py @@ -349,9 +349,12 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.del_temp_region() - cls.runModule("g.remove", flags="f", type="raster", name=cls.map1) - cls.runModule("g.remove", flags="f", type="raster", name=cls.map2) - cls.runModule("g.remove", flags="f", type="raster", name=cls.map3) + cls.runModule( + "g.remove", + flags="f", + type="raster", + name=(cls.map1, cls.map2, cls.map3), + ) def test_symmetric_complete_difference(self): # Prepare imagery group reference struct diff --git a/lib/imagery/testsuite/test_imagery_sigsetfile.py b/lib/imagery/testsuite/test_imagery_sigsetfile.py index d526e920885..80be7c0d3a5 100644 --- a/lib/imagery/testsuite/test_imagery_sigsetfile.py +++ b/lib/imagery/testsuite/test_imagery_sigsetfile.py @@ -242,9 +242,12 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.del_temp_region() - cls.runModule("g.remove", flags="f", type="raster", name=cls.map1) - cls.runModule("g.remove", flags="f", type="raster", name=cls.map2) - cls.runModule("g.remove", flags="f", type="raster", name=cls.map3) + cls.runModule( + "g.remove", + flags="f", + type="raster", + name=(cls.map1, cls.map2, cls.map3), + ) def test_symmetric_complete_difference(self): # Prepare imagery group reference struct diff --git a/raster/r.contour/testsuite/test_r_contour.py b/raster/r.contour/testsuite/test_r_contour.py index c9ee4c9876a..49617ef043d 100644 --- a/raster/r.contour/testsuite/test_r_contour.py +++ b/raster/r.contour/testsuite/test_r_contour.py @@ -32,10 +32,11 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - cls.runModule("g.remove", type="vector", flags="f", name=cls.output) - cls.runModule("g.remove", type="vector", flags="f", name=cls.output + "_cut") cls.runModule( - "g.remove", type="vector", flags="f", name=cls.output + "_cut_flag_t" + "g.remove", + type="vector", + flags="f", + name=(cls.output, cls.output + "_cut", cls.output + "_cut_flag_t"), ) if os.path.isfile("testReport"): diff --git a/raster/r.in.pdal/testsuite/test_r_in_pdal_binning.py b/raster/r.in.pdal/testsuite/test_r_in_pdal_binning.py index a8a793f5bc7..c256224590d 100644 --- a/raster/r.in.pdal/testsuite/test_r_in_pdal_binning.py +++ b/raster/r.in.pdal/testsuite/test_r_in_pdal_binning.py @@ -68,8 +68,12 @@ def tearDown(self): This is executed after each test run. """ - self.runModule("g.remove", flags="f", type="raster", name=self.bin_raster) - self.runModule("g.remove", flags="f", type="raster", name=self.ref_raster) + self.runModule( + "g.remove", + flags="f", + type="raster", + name=(self.bin_raster, self.ref_raster), + ) @unittest.skipIf(shutil.which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_n(self): diff --git a/raster/r.in.pdal/testsuite/test_r_in_pdal_selection.py b/raster/r.in.pdal/testsuite/test_r_in_pdal_selection.py index b7d5acd6b28..4796702d2f6 100644 --- a/raster/r.in.pdal/testsuite/test_r_in_pdal_selection.py +++ b/raster/r.in.pdal/testsuite/test_r_in_pdal_selection.py @@ -67,8 +67,12 @@ def tearDown(self): This is executed after each test run. """ - self.runModule("g.remove", flags="f", type="raster", name=self.imp_raster) - self.runModule("g.remove", flags="f", type="raster", name=self.ref_raster) + self.runModule( + "g.remove", + flags="f", + type="raster", + name=(self.imp_raster, self.ref_raster), + ) try: self.runModule("g.remove", flags="f", type="raster", name=self.base_raster) except AttributeError: diff --git a/raster/r.kappa/testsuite/test_r_kappa.py b/raster/r.kappa/testsuite/test_r_kappa.py index 620a4f4979b..ff11f477925 100644 --- a/raster/r.kappa/testsuite/test_r_kappa.py +++ b/raster/r.kappa/testsuite/test_r_kappa.py @@ -51,8 +51,9 @@ def setUpClass(cls): def tearDownClass(cls): """Remove temporary data""" cls.del_temp_region() - cls.runModule("g.remove", flags="f", type="raster", name=cls.ref_1) - cls.runModule("g.remove", flags="f", type="raster", name=cls.class_1) + cls.runModule( + "g.remove", flags="f", type="raster", name=(cls.ref_1, cls.class_1) + ) def test_m(self): """Test printing matrix only @@ -119,8 +120,9 @@ def setUpClass(cls): def tearDownClass(cls): """Remove temporary data""" cls.del_temp_region() - cls.runModule("g.remove", flags="f", type="raster", name=cls.ref_1) - cls.runModule("g.remove", flags="f", type="raster", name=cls.class_1) + cls.runModule( + "g.remove", flags="f", type="raster", name=(cls.ref_1, cls.class_1) + ) def match(self, pat, ref): if pat == "NA" or ref == "NA": @@ -233,8 +235,9 @@ def setUpClass(cls): def tearDownClass(cls): """Remove temporary data""" cls.del_temp_region() - cls.runModule("g.remove", flags="f", type="raster", name=cls.ref_1) - cls.runModule("g.remove", flags="f", type="raster", name=cls.class_1) + cls.runModule( + "g.remove", flags="f", type="raster", name=(cls.ref_1, cls.class_1) + ) def match(self, pat, ref): if pat == "NA" or ref == "NA": diff --git a/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py b/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py index 2dc85b411d8..9a0591f7cfc 100644 --- a/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py +++ b/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py @@ -55,8 +55,7 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(rows, cols, fname): diff --git a/raster/r.neighbors/benchmark/benchmark_r_neighbors_nprocs.py b/raster/r.neighbors/benchmark/benchmark_r_neighbors_nprocs.py index d355792a734..e7b3196c246 100644 --- a/raster/r.neighbors/benchmark/benchmark_r_neighbors_nprocs.py +++ b/raster/r.neighbors/benchmark/benchmark_r_neighbors_nprocs.py @@ -38,8 +38,7 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(rows, cols, fname): diff --git a/raster/r.random/testsuite/test_r_random.py b/raster/r.random/testsuite/test_r_random.py index ce12c719c8e..16aae357ebf 100644 --- a/raster/r.random/testsuite/test_r_random.py +++ b/raster/r.random/testsuite/test_r_random.py @@ -28,30 +28,30 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - cls.runModule("g.remove", type="raster", flags="f", name=cls.raster) - cls.runModule("g.remove", type="raster", flags="f", name=cls.raster + "_null") - cls.runModule( - "g.remove", type="raster", flags="f", name=cls.raster + "_without_topology" - ) - cls.runModule("g.remove", type="raster", flags="f", name=cls.raster + "_3D") cls.runModule( "g.remove", type="raster", flags="f", - name=cls.raster + "_cover_landcover_1m", + name=( + cls.raster, + cls.raster + "_null", + cls.raster + "_without_topology", + cls.raster + "_3D", + cls.raster + "_cover_landcover_1m", + ), ) - cls.runModule("g.remove", type="vector", flags="f", name=cls.vector) - cls.runModule("g.remove", type="vector", flags="f", name=cls.vector + "_null") - cls.runModule( - "g.remove", type="vector", flags="f", name=cls.vector + "_without_topology" - ) - cls.runModule("g.remove", type="vector", flags="f", name=cls.vector + "_3D") cls.runModule( "g.remove", type="vector", flags="f", - name=cls.vector + "_cover_landcover_1m", + name=( + cls.vector, + cls.vector + "_null", + cls.vector + "_without_topology", + cls.vector + "_3D", + cls.vector + "_cover_landcover_1m", + ), ) def test_random_raster(self): diff --git a/raster/r.resamp.filter/benchmark/benchmark_r_resamp_filter.py b/raster/r.resamp.filter/benchmark/benchmark_r_resamp_filter.py index 8c7799e74fc..9ec46132c81 100644 --- a/raster/r.resamp.filter/benchmark/benchmark_r_resamp_filter.py +++ b/raster/r.resamp.filter/benchmark/benchmark_r_resamp_filter.py @@ -40,8 +40,7 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=8, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(rows, cols, fname): diff --git a/raster/r.resamp.interp/benchmark/benchmark_r_resamp_interp.py b/raster/r.resamp.interp/benchmark/benchmark_r_resamp_interp.py index 20196bc44bc..616dc045aa3 100644 --- a/raster/r.resamp.interp/benchmark/benchmark_r_resamp_interp.py +++ b/raster/r.resamp.interp/benchmark/benchmark_r_resamp_interp.py @@ -38,8 +38,7 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(rows, cols, fname): diff --git a/raster/r.series/benchmark/benchmark_r_series.py b/raster/r.series/benchmark/benchmark_r_series.py index ecf4432f2dd..72c9c3bd23c 100644 --- a/raster/r.series/benchmark/benchmark_r_series.py +++ b/raster/r.series/benchmark/benchmark_r_series.py @@ -37,8 +37,7 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(rows, cols, fname): diff --git a/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect.py b/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect.py index 220b813e323..522a938f26c 100644 --- a/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect.py +++ b/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect.py @@ -42,11 +42,13 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=slope) - Module("g.remove", quiet=True, flags="f", type="raster", name=aspect) - Module("g.remove", quiet=True, flags="f", type="raster", name=pcurv) - Module("g.remove", quiet=True, flags="f", type="raster", name=tcurv) + Module( + "g.remove", + quiet=True, + flags="f", + type="raster", + name=(reference, slope, aspect, pcurv, tcurv), + ) def generate_map(rows, cols, fname): diff --git a/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect_memory.py b/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect_memory.py index c8f5ac09f00..31824233bbc 100644 --- a/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect_memory.py +++ b/raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect_memory.py @@ -46,10 +46,13 @@ def benchmark(memory, label, results, reference): ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=20, repeat=10)) - Module("g.remove", quiet=True, flags="f", type="raster", name=slope) - Module("g.remove", quiet=True, flags="f", type="raster", name=aspect) - Module("g.remove", quiet=True, flags="f", type="raster", name=pcurv) - Module("g.remove", quiet=True, flags="f", type="raster", name=tcurv) + Module( + "g.remove", + quiet=True, + flags="f", + type="raster", + name=(slope, aspect, pcurv, tcurv), + ) def generate_map(rows, cols, fname): diff --git a/raster/r.tile/testsuite/test_r_tile.py b/raster/r.tile/testsuite/test_r_tile.py index f1dd3afcd3b..c2e62b60dd2 100644 --- a/raster/r.tile/testsuite/test_r_tile.py +++ b/raster/r.tile/testsuite/test_r_tile.py @@ -28,42 +28,20 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.del_temp_region() - cls.runModule( - "g.remove", type="raster", flags="f", name=cls.output_prefix + "-000-000" - ) - cls.runModule( - "g.remove", type="raster", flags="f", name=cls.output_prefix + "-000-001" - ) - cls.runModule( - "g.remove", type="raster", flags="f", name=cls.output_prefix + "-001-000" - ) - cls.runModule( - "g.remove", type="raster", flags="f", name=cls.output_prefix + "-001-001" - ) - - cls.runModule( - "g.remove", - type="raster", - flags="f", - name=cls.output_prefix + "overlap" + "-000-000", - ) - cls.runModule( - "g.remove", - type="raster", - flags="f", - name=cls.output_prefix + "overlap" + "-000-001", - ) - cls.runModule( - "g.remove", - type="raster", - flags="f", - name=cls.output_prefix + "overlap" + "-001-000", - ) cls.runModule( "g.remove", type="raster", flags="f", - name=cls.output_prefix + "overlap" + "-001-001", + name=( + cls.output_prefix + "-000-000", + cls.output_prefix + "-000-001", + cls.output_prefix + "-001-000", + cls.output_prefix + "-001-001", + cls.output_prefix + "overlap" + "-000-000", + cls.output_prefix + "overlap" + "-000-001", + cls.output_prefix + "overlap" + "-001-000", + cls.output_prefix + "overlap" + "-001-001", + ), ) def test_raster_tile(self): diff --git a/raster/r.univar/benchmark/benchmark_r_univar.py b/raster/r.univar/benchmark/benchmark_r_univar.py index 507e6b4b23e..58d607645c7 100644 --- a/raster/r.univar/benchmark/benchmark_r_univar.py +++ b/raster/r.univar/benchmark/benchmark_r_univar.py @@ -35,8 +35,7 @@ def benchmark(size, label, results): overwrite=True, ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(rows, cols, fname): diff --git a/raster/r.univar/testsuite/test_r_univar.py b/raster/r.univar/testsuite/test_r_univar.py index de28f0753d5..c2ae6669df6 100644 --- a/raster/r.univar/testsuite/test_r_univar.py +++ b/raster/r.univar/testsuite/test_r_univar.py @@ -23,11 +23,12 @@ def tearDownClass(cls): cls.del_temp_region() def tearDown(self): - self.runModule("g.remove", flags="f", type="raster", name="map_a") - self.runModule("g.remove", flags="f", type="raster", name="map_b") - self.runModule("g.remove", flags="f", type="raster", name="map_negative") - self.runModule("g.remove", flags="f", type="raster", name="zone_map") - self.runModule("g.remove", flags="f", type="raster", name="zone_map_with_gap") + self.runModule( + "g.remove", + flags="f", + type="raster", + name="map_a,map_b,map_negative,zone_map,zone_map_with_gap", + ) def setUp(self): """Create input data""" diff --git a/raster3d/r3.null/testsuite/test.r3.null.sh b/raster3d/r3.null/testsuite/test.r3.null.sh index 1cf93110b24..d6a6ec35810 100755 --- a/raster3d/r3.null/testsuite/test.r3.null.sh +++ b/raster3d/r3.null/testsuite/test.r3.null.sh @@ -56,14 +56,7 @@ diff data/test_volume_double_null_1.ref test_volume_double_null_1.txt diff data/test_volume_double_null_2.ref test_volume_double_null_2.txt # Cleanup -g.remove -f type=raster_3d name=test_volume_float_1 -g.remove -f type=raster_3d name=test_volume_float_2 -g.remove -f type=raster_3d name=test_volume_float_null_1 -g.remove -f type=raster_3d name=test_volume_float_null_2 -g.remove -f type=raster_3d name=test_volume_double_1 -g.remove -f type=raster_3d name=test_volume_double_2 -g.remove -f type=raster_3d name=test_volume_double_null_1 -g.remove -f type=raster_3d name=test_volume_double_null_2 +g.remove -f type=raster_3d name=test_volume_float_1,test_volume_float_2,test_volume_float_null_1,test_volume_float_null_2,test_volume_double_1,test_volume_double_2,test_volume_double_null_1,test_volume_double_null_2 rm test_volume_float_1.txt rm test_volume_float_2.txt rm test_volume_float_null_1.txt diff --git a/scripts/r.mapcalc.simple/testsuite/test_rmapcalcsimple.py b/scripts/r.mapcalc.simple/testsuite/test_rmapcalcsimple.py index d400ccc7980..f133da22f7d 100644 --- a/scripts/r.mapcalc.simple/testsuite/test_rmapcalcsimple.py +++ b/scripts/r.mapcalc.simple/testsuite/test_rmapcalcsimple.py @@ -24,8 +24,9 @@ def setUpClass(cls): def tearDownClass(cls): map_output1 = "test1" map_output2 = "test2" - cls.runModule("g.remove", flags="f", type="raster", name=map_output1) - cls.runModule("g.remove", flags="f", type="raster", name=map_output2) + cls.runModule( + "g.remove", flags="f", type="raster", name=(map_output1, map_output2) + ) cls.del_temp_region() def test_rmapcalcsimple(self): diff --git a/scripts/r.reclass.area/testsuite/test_r_reclass_area.py b/scripts/r.reclass.area/testsuite/test_r_reclass_area.py index c8009ce5a1d..96c922bda05 100644 --- a/scripts/r.reclass.area/testsuite/test_r_reclass_area.py +++ b/scripts/r.reclass.area/testsuite/test_r_reclass_area.py @@ -26,8 +26,12 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.del_temp_region() - cls.runModule("g.remove", type="raster", flags="f", name=cls.output + "Greater") - cls.runModule("g.remove", type="raster", flags="f", name=cls.output + "Lesser") + cls.runModule( + "g.remove", + type="raster", + flags="f", + name=(cls.output + "Greater", cls.output + "Lesser"), + ) def test_reclassaeaGreater(self): """Testing r.reclass.area with greater""" diff --git a/scripts/v.rast.stats/testsuite/test_v_rast_stats.py b/scripts/v.rast.stats/testsuite/test_v_rast_stats.py index 56acbce5964..01ae6d4a7d2 100644 --- a/scripts/v.rast.stats/testsuite/test_v_rast_stats.py +++ b/scripts/v.rast.stats/testsuite/test_v_rast_stats.py @@ -24,11 +24,12 @@ def tearDownClass(cls): cls.del_temp_region() def tearDown(self): - self.runModule("g.remove", flags="f", type="raster", name="map_a") - self.runModule("g.remove", flags="f", type="raster", name="map_b") - self.runModule("g.remove", flags="f", type="raster", name="zone_map") - self.runModule("g.remove", flags="f", type="raster", name="row_map") - self.runModule("g.remove", flags="f", type="raster", name="test_line") + self.runModule( + "g.remove", + flags="f", + type="raster", + name="map_a,map_b,zone_map,row_map,test_line", + ) def setUp(self): """Create input data""" diff --git a/temporal/t.rast.accdetect/testsuite/test_simple.py b/temporal/t.rast.accdetect/testsuite/test_simple.py index 522c13f93e4..d67537487d5 100644 --- a/temporal/t.rast.accdetect/testsuite/test_simple.py +++ b/temporal/t.rast.accdetect/testsuite/test_simple.py @@ -62,8 +62,7 @@ def tearDownClass(cls): def tearDown(self): """Remove generated data""" - self.runModule("t.remove", flags="df", type="strds", inputs="B") - self.runModule("t.remove", flags="df", type="strds", inputs="C") + self.runModule("t.remove", flags="df", type="strds", inputs="B,C") def test_simple(self): self.assertModule( diff --git a/temporal/t.rast.accumulate/testsuite/test_accumulation.py b/temporal/t.rast.accumulate/testsuite/test_accumulation.py index f5bf6dcf5d7..566c1971f99 100644 --- a/temporal/t.rast.accumulate/testsuite/test_accumulation.py +++ b/temporal/t.rast.accumulate/testsuite/test_accumulation.py @@ -95,9 +95,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): """Remove the temporary region""" - cls.runModule("t.remove", flags="df", type="strds", inputs="A") - cls.runModule("t.remove", flags="df", type="strds", inputs="Lower") - cls.runModule("t.remove", flags="df", type="strds", inputs="Upper") + cls.runModule("t.remove", flags="df", type="strds", inputs="A,Lower,Upper") cls.del_temp_region() def tearDown(self): diff --git a/temporal/t.rast.series/testsuite/test_series.py b/temporal/t.rast.series/testsuite/test_series.py index 99fe69d4352..e936e10e0e7 100644 --- a/temporal/t.rast.series/testsuite/test_series.py +++ b/temporal/t.rast.series/testsuite/test_series.py @@ -61,11 +61,15 @@ def tearDownClass(cls): type="raster", maps="series_average,series_maximum,series_minimum,series_minimum_2", ) - cls.runModule("g.remove", flags="f", type="raster", name="series_average") - cls.runModule("g.remove", flags="f", type="raster", name="series_maximum") - cls.runModule("g.remove", flags="f", type="raster", name="series_minimum") - cls.runModule("g.remove", flags="f", type="raster", name="series_minimum_2") - cls.runModule("g.remove", flags="f", type="raster", name="series_quantile") + cls.runModule( + "g.remove", + flags="f", + type="raster", + name=( + "series_average,series_maximum" + + ",series_minimum,series_minimum_2,series_quantile" + ), + ) def test_time_stamp(self): self.assertModule( @@ -206,10 +210,12 @@ def tearDownClass(cls): type="raster", maps="series_average,series_maximum,series_minimum,series_minimum_2", ) - cls.runModule("g.remove", flags="f", type="raster", name="series_average") - cls.runModule("g.remove", flags="f", type="raster", name="series_maximum") - cls.runModule("g.remove", flags="f", type="raster", name="series_minimum") - cls.runModule("g.remove", flags="f", type="raster", name="series_minimum_2") + cls.runModule( + "g.remove", + flags="f", + type="raster", + name="series_average,series_maximum,series_minimum,series_minimum_2", + ) def test_average(self): self.assertModule( diff --git a/temporal/t.rast.univar/testsuite/test_t_rast_univar.py b/temporal/t.rast.univar/testsuite/test_t_rast_univar.py index dca870d6a98..17831b9b5b9 100644 --- a/temporal/t.rast.univar/testsuite/test_t_rast_univar.py +++ b/temporal/t.rast.univar/testsuite/test_t_rast_univar.py @@ -147,8 +147,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): """Remove the temporary region""" - cls.runModule("t.remove", flags="df", type="strds", inputs="A") - cls.runModule("t.remove", flags="df", type="strds", inputs="B") + cls.runModule("t.remove", flags="df", type="strds", inputs="A,B") cls.runModule("g.remove", flags="f", type="raster", name="zones") cls.del_temp_region() diff --git a/temporal/t.topology/test.t.topology.reltime.sh b/temporal/t.topology/test.t.topology.reltime.sh index 847289c4b2f..60e49355e9a 100755 --- a/temporal/t.topology/test.t.topology.reltime.sh +++ b/temporal/t.topology/test.t.topology.reltime.sh @@ -96,6 +96,5 @@ cat "${n5}" t.topology input=precip_rel_y t.topology -m input=precip_rel_y -t.remove type=strds input=precip_rel_d -t.remove type=strds input=precip_rel_y +t.remove type=strds input=precip_rel_d,precip_rel_y t.unregister type=raster file="${n1}" diff --git a/temporal/t.vect.extract/test.t.vect.extract.sh b/temporal/t.vect.extract/test.t.vect.extract.sh index b5cd6882e94..8b176dcc8ed 100755 --- a/temporal/t.vect.extract/test.t.vect.extract.sh +++ b/temporal/t.vect.extract/test.t.vect.extract.sh @@ -44,5 +44,4 @@ t.vect.list input=soil_abs3 columns=name,start_time,end_time,primitives # @postprocess t.unregister type=vector maps=soil_1,soil_2,soil_3,soil_4,soil_5,soil_6,soil_7,soil_8 t.remove type=stvds input=soil_abs1,soil_abs2,soil_abs3 -g.remove -f type=vector name=soil_1,soil_2,soil_3,soil_4,soil_5,soil_6,soil_7,soil_8 -g.remove -f type=vector name=new_vect_1,new_vect_2,new_vect_3,new_vect_4,new_vect_5,new_vect_6 +g.remove -f type=vector name=soil_1,soil_2,soil_3,soil_4,soil_5,soil_6,soil_7,soil_8,new_vect_1,new_vect_2,new_vect_3,new_vect_4,new_vect_5,new_vect_6 diff --git a/utils/thumbnails.py b/utils/thumbnails.py index ee9bd5e17ab..181a16aa666 100755 --- a/utils/thumbnails.py +++ b/utils/thumbnails.py @@ -23,13 +23,14 @@ def cleanup(): + names = [] if tmp_grad_rel: - gs.run_command( - "g.remove", flags="f", type="raster", name=tmp_grad_rel, quiet=True - ) + names.append(tmp_grad_rel) if tmp_grad_abs: + names.append(tmp_grad_abs) + if len(names) > 0: gs.run_command( - "g.remove", flags="f", type="raster", name=tmp_grad_abs, quiet=True + "g.remove", flags="f", type="raster", name=",".join(names), quiet=True ) diff --git a/vector/v.random/testsuite/test_v_random.py b/vector/v.random/testsuite/test_v_random.py index e5cc95a93db..d11faf458f9 100644 --- a/vector/v.random/testsuite/test_v_random.py +++ b/vector/v.random/testsuite/test_v_random.py @@ -31,8 +31,9 @@ def tearDownClass(cls): cls.del_temp_region() def tearDown(cls): - cls.runModule("g.remove", type="vector", flags="f", name=cls.output) - cls.runModule("g.remove", type="vector", flags="f", name=cls.output2) + cls.runModule( + "g.remove", type="vector", flags="f", name=(cls.output, cls.output2) + ) def test_num_points(self): """Checking if number of points equals 100""" diff --git a/vector/v.surf.rst/benchmark/benchmark_v_surf_rst.py b/vector/v.surf.rst/benchmark/benchmark_v_surf_rst.py index 91fd784e0b3..ac69b441010 100644 --- a/vector/v.surf.rst/benchmark/benchmark_v_surf_rst.py +++ b/vector/v.surf.rst/benchmark/benchmark_v_surf_rst.py @@ -36,8 +36,7 @@ def benchmark(size, label, results): ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=8, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(npoints, rows, cols, fname): diff --git a/vector/v.surf.rst/benchmark/benchmark_v_surf_rst_cv.py b/vector/v.surf.rst/benchmark/benchmark_v_surf_rst_cv.py index 21a3c7459eb..f140ee67b8a 100644 --- a/vector/v.surf.rst/benchmark/benchmark_v_surf_rst_cv.py +++ b/vector/v.surf.rst/benchmark/benchmark_v_surf_rst_cv.py @@ -37,8 +37,7 @@ def benchmark(size, label, results): ) results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=8, repeat=3)) - Module("g.remove", quiet=True, flags="f", type="raster", name=reference) - Module("g.remove", quiet=True, flags="f", type="raster", name=output) + Module("g.remove", quiet=True, flags="f", type="raster", name=(reference, output)) def generate_map(npoints, rows, cols, fname): From 62b001b1318fb331334d6a9bab3ec0f6fba60360 Mon Sep 17 00:00:00 2001 From: ww2406 <57472892+ww2406@users.noreply.github.com> Date: Fri, 18 Oct 2024 07:41:20 -0700 Subject: [PATCH 53/69] gui: Add fix for wxGUI Data import Python error (#4504) This fixes #648 by adding a command tracker queue. When the queue is not empty, closing the dialog is prevented to ensure the completion callback can still access UI elements. --- gui/wxpython/modules/import_export.py | 47 +++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/gui/wxpython/modules/import_export.py b/gui/wxpython/modules/import_export.py index a0bd17e289c..c3106d0467b 100644 --- a/gui/wxpython/modules/import_export.py +++ b/gui/wxpython/modules/import_export.py @@ -18,9 +18,11 @@ @author Martin Landa @author Anna Kratochvilova (GroupDialog, SymbolDialog) +@author William Welch (commands running queue) """ import os +from collections import deque from pathlib import Path @@ -60,6 +62,8 @@ def __init__( self.commandId = -1 # id of running command + self._commands_running = deque() + wx.Dialog.__init__( self, parent, id, title, style=style, name="MultiImportDialog" ) @@ -122,8 +126,9 @@ def __init__( # buttons # # cancel + self._DEFAULT_CLOSE_BTN_TEXT = _("Close dialog") self.btn_close = CloseButton(parent=self.panel) - self.btn_close.SetToolTip(_("Close dialog")) + self.btn_close.SetToolTip(_(self._DEFAULT_CLOSE_BTN_TEXT)) self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose) # run self.btn_run = Button(parent=self.panel, id=wx.ID_OK, label=_("&Import")) @@ -131,7 +136,7 @@ def __init__( self.btn_run.SetDefault() self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) - self.Bind(wx.EVT_CLOSE, lambda evt: self.Destroy()) + self.Bind(wx.EVT_CLOSE, self._handleCloseEvent) self.notebook = GNotebook(parent=self, style=globalvar.FNPageDStyle) @@ -270,6 +275,33 @@ def _validateOutputMapName(self): return False return True + def _handleCloseEvent(self, event: wx.CloseEvent): + if event.CanVeto() and len(self._commands_running) > 0: + # prevent dialog close while async commands are running + event.Veto() + return + self.Destroy() + + def _addToCommandQueue(self): + self._commands_running.append(True) + + # disable the dialog close button + self.btn_close.SetToolTip( + _("Dialog cannot be closed while command is running.") + ) + self.btn_close.Disable() + + def _removeFromCommandQueue(self): + try: + self._commands_running.pop() + except IndexError: + pass + finally: + if len(self._commands_running) == 0: + # enable the dialog close button + self.btn_close.Enable() + self.btn_close.SetToolTip(self._DEFAULT_CLOSE_BTN_TEXT) + def OnClose(self, event=None): """Close dialog""" self.Close() @@ -518,6 +550,7 @@ def OnRun(self, event): ): cmd.append("--overwrite") + self._addToCommandQueue() # run in Layer Manager self._giface.RunCmd( cmd, onDone=self.OnCmdDone, userData=userData, addLayer=False @@ -526,9 +559,11 @@ def OnRun(self, event): def OnCmdDone(self, event): """Load layers and close if required""" if not hasattr(self, "AddLayers"): + self._removeFromCommandQueue() return self.AddLayers(event.returncode, event.cmd, event.userData) + self._removeFromCommandQueue() if event.returncode == 0 and self.closeOnFinish.IsChecked(): self.Close() @@ -663,6 +698,7 @@ def OnRun(self, event): ): cmd.append("--overwrite") + self._addToCommandQueue() # run in Layer Manager self._giface.RunCmd( cmd, onDone=self.OnCmdDone, userData=userData, addLayer=False @@ -671,10 +707,13 @@ def OnRun(self, event): def OnCmdDone(self, event): """Load layers and close if required""" if not hasattr(self, "AddLayers"): + self._removeFromCommandQueue() return self.AddLayers(event.returncode, event.cmd, event.userData) + self._removeFromCommandQueue() + if self.popOGR: os.environ.pop("GRASS_VECTOR_OGR") @@ -873,16 +912,20 @@ def OnRun(self, event): ): cmd.append("--overwrite") + self._commands_running.append(True) # run in Layer Manager self._giface.RunCmd(cmd, onDone=self.OnCmdDone, addLayer=False) def OnCmdDone(self, event): """Load layers and close if required""" if not hasattr(self, "AddLayers"): + self._removeFromCommandQueue() return self.AddLayers(event.returncode, event.cmd) + self._removeFromCommandQueue() + if self.closeOnFinish.IsChecked(): self.Close() From 5cff700eb5bcaa9adcba7cb67c790d16407acaf1 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 18 Oct 2024 16:35:35 -0400 Subject: [PATCH 54/69] docs: Fixed E721 in gunittest/ (#4549) --- .flake8 | 3 --- python/grass/gunittest/invoker.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.flake8 b/.flake8 index 306a11fe02b..a5588997635 100644 --- a/.flake8 +++ b/.flake8 @@ -66,7 +66,6 @@ per-file-ignores = # TODO: Is this really needed? python/grass/pygrass/vector/__init__.py: E402 python/grass/pygrass/raster/__init__.py: E402 - python/grass/gunittest/invoker.py: E721 python/grass/pygrass/vector/__init__.py: E402 python/grass/pygrass/modules/interface/*.py: F401 python/grass/pygrass/modules/grid/*.py: F401 @@ -82,13 +81,11 @@ per-file-ignores = python/grass/temporal/temporal_granularity.py: E722 python/grass/temporal/temporal_raster_base_algebra.py: E722 python/grass/temporal/temporal_topology_dataset_connector.py: E722 - python/grass/temporal/univar_statistics.py: E231 # Current benchmarks/tests are changing sys.path before import. # Possibly, a different approach should be taken there anyway. python/grass/pygrass/tests/benchmark.py: E402, F401, F821 # Configuration file for Sphinx: # Ignoring import/code mix and line length. - python/grass/docs/conf.py: E402 # Files not managed by Black python/grass/imaging/images2gif.py: E226 # Unused imports in init files diff --git a/python/grass/gunittest/invoker.py b/python/grass/gunittest/invoker.py index f07e8dd5a84..2fe9c898b8b 100644 --- a/python/grass/gunittest/invoker.py +++ b/python/grass/gunittest/invoker.py @@ -244,7 +244,7 @@ def try_decode(data, encodings): Path(stdout_path).write_text(stdout) with open(stderr_path, "w") as stderr_file: - if type(stderr) == "bytes": + if isinstance(stderr, bytes): stderr_file.write(decode(stderr)) elif isinstance(stderr, str): stderr_file.write(stderr) From 2a0ad5f1057ad66f716f044bc13bc4d6a7be5d95 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Fri, 18 Oct 2024 16:52:08 -0400 Subject: [PATCH 55/69] wxGUI: Fixed E266 in nviz/ (#4547) --- .flake8 | 2 +- gui/wxpython/nviz/tools.py | 46 -------------------------------------- 2 files changed, 1 insertion(+), 47 deletions(-) diff --git a/.flake8 b/.flake8 index a5588997635..5d2d792b0c3 100644 --- a/.flake8 +++ b/.flake8 @@ -25,7 +25,7 @@ per-file-ignores = gui/scripts/d.wms.py: E501 gui/wxpython/image2target/g.gui.image2target.py: E501 gui/wxpython/modules/*: F841, E722 - gui/wxpython/nviz/*: E266, E722, F403, F405 + gui/wxpython/nviz/*: E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 gui/wxpython/psmap/*: F841, E266, E722 diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py index 153f8ffef86..7ced7d157e1 100644 --- a/gui/wxpython/nviz/tools.py +++ b/gui/wxpython/nviz/tools.py @@ -1196,33 +1196,6 @@ def _createSurfacePage(self, parent): flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=3, ) - # - # mask - # - # box = wx.StaticBox (parent = panel, id = wx.ID_ANY, - # label = " %s " % (_("Mask"))) - ## boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL) - ## gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5) - ## - # gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY, - # label = _("Mask zeros:")), - # pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL) - ## - # elev = wx.CheckBox(parent = panel, id = wx.ID_ANY, - # label = _("by elevation")) - # elev.Enable(False) # TODO: not implemented yet - ## gridSizer.Add(item = elev, pos = (0, 1)) - ## - # color = wx.CheckBox(parent = panel, id = wx.ID_ANY, - # label = _("by color")) - # color.Enable(False) # TODO: not implemented yet - ## gridSizer.Add(item = color, pos = (0, 2)) - ## - # boxSizer.Add(item = gridSizer, proportion = 1, - # flag = wx.ALL | wx.EXPAND, border = 3) - # pageSizer.Add(item = boxSizer, proportion = 0, - ## flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, - # border = 3) panel.SetSizer(pageSizer) @@ -1852,24 +1825,6 @@ def _createVectorPage(self, parent): icolor.Bind(csel.EVT_COLOURSELECT, self.OnVectorPoints) gridSizer.Add(icolor, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, pos=(0, 4)) - # icon width - seems to do nothing - # gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY, - # label = _("width")), - # pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL | - # wx.ALIGN_RIGHT) - ## - # iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), - ## initial = 1, - ## min = 1, - # max = 1e6) - # iwidth.SetName('value') - # iwidth.SetValue(100) - ## self.win['vector']['points']['width'] = iwidth.GetId() - ## iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints) - ## iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints) - # gridSizer.Add(item = iwidth, pos = (1, 2), - # flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT) - # icon symbol gridSizer.Add( StaticText(parent=panel, id=wx.ID_ANY, label=_("symbol:")), pos=(0, 5), @@ -3084,7 +3039,6 @@ def _createIsosurfacePanel(self, parent): ) value.Bind(wx.EVT_TEXT_ENTER, self.OnVolumeIsosurfMap) value.Bind(wx.EVT_KILL_FOCUS, self.OnVolumeIsosurfMap) - ## value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap) else: size = (65, -1) value = SpinCtrl(parent=panel, id=wx.ID_ANY, size=size, initial=0) From 1a803b41615713e89d4b531e204ee76e22318255 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 19 Oct 2024 06:14:44 -0400 Subject: [PATCH 56/69] CI(deps): Update ubuntu:22.04 Docker digest to 0e5e4a5 (#4553) --- Dockerfile | 2 +- docker/ubuntu/Dockerfile | 2 +- docker/ubuntu_wxgui/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 41fb3264c07..a5c6ab1ee1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ ARG GUI=without -FROM ubuntu:22.04@sha256:58b87898e82351c6cf9cf5b9f3c20257bb9e2dcf33af051e12ce532d7f94e3fe as common_start +FROM ubuntu:22.04@sha256:0e5e4a57c2499249aafc3b40fcd541e9a456aab7296681a3994d631587203f97 as common_start LABEL authors="Carmen Tawalika,Markus Neteler,Anika Weinmann,Stefan Blumentrath" LABEL maintainer="tawalika@mundialis.de,neteler@mundialis.de,weinmann@mundialis.de" diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 41fb3264c07..a5c6ab1ee1d 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -5,7 +5,7 @@ ARG GUI=without -FROM ubuntu:22.04@sha256:58b87898e82351c6cf9cf5b9f3c20257bb9e2dcf33af051e12ce532d7f94e3fe as common_start +FROM ubuntu:22.04@sha256:0e5e4a57c2499249aafc3b40fcd541e9a456aab7296681a3994d631587203f97 as common_start LABEL authors="Carmen Tawalika,Markus Neteler,Anika Weinmann,Stefan Blumentrath" LABEL maintainer="tawalika@mundialis.de,neteler@mundialis.de,weinmann@mundialis.de" diff --git a/docker/ubuntu_wxgui/Dockerfile b/docker/ubuntu_wxgui/Dockerfile index e15d5dcf478..0d1ead788a3 100644 --- a/docker/ubuntu_wxgui/Dockerfile +++ b/docker/ubuntu_wxgui/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04@sha256:58b87898e82351c6cf9cf5b9f3c20257bb9e2dcf33af051e12ce532d7f94e3fe +FROM ubuntu:22.04@sha256:0e5e4a57c2499249aafc3b40fcd541e9a456aab7296681a3994d631587203f97 LABEL authors="Carmen Tawalika,Markus Neteler,Anika Weinmann,Tomas Zigo" LABEL maintainer="tawalika@mundialis.de,neteler@mundialis.de,weinmann@mundialis.de" From 7fbaa7e5a1b7cfe4fa3701a4ecfef51547843269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 20 Oct 2024 10:52:45 -0400 Subject: [PATCH 57/69] style: Enable checking for pep8-naming (N) rules with ruff, fix N804, N805 and N813 (#4556) * style: Enable checking for pep8-naming (N) rules with Ruff Rules already respected: - dunder-function-name (N807) - constant-imported-as-non-constant (N811) - camelcase-imported-as-acronym (N817) * style: Fix invalid-first-argument-name-for-class-method (N804) Ruff rule: https://docs.astral.sh/ruff/rules/invalid-first-argument-name-for-class-method/ Two files had class methods that didn't use cls as their first argument * style: Fix camelcase-imported-as-lowercase (N813) Ruff rule: https://docs.astral.sh/ruff/rules/camelcase-imported-as-lowercase/ One instance only in a pytest file * style: Fix invalid-first-argument-name-for-method (N805) Ruff rule: https://docs.astral.sh/ruff/rules/invalid-first-argument-name-for-method/ Three instances in gui/wxpython/mapswipe/frame.py were ignored, as an inner class is defined using self2 and also references self from the containing class. --- gui/wxpython/mapswipe/frame.py | 6 ++--- pyproject.toml | 11 +++++++++ .../interface/testsuite/test_modules.py | 4 ++-- python/grass/script/tests/test_script_task.py | 6 ++--- raster/r.basins.fill/testsuite/testrbf.py | 4 ++-- raster/r.series/testsuite/test_r_series.py | 6 ++--- .../r.terraflow/testsuite/test_r_terraflow.py | 24 +++++++++---------- raster/r.to.vect/testsuite/test_r_to_vect.py | 4 ++-- .../r.viewshed/testsuite/test_r_viewshed.py | 4 ++-- scripts/r.import/testsuite/test_r_import.py | 4 ++-- scripts/r.reclass.area/testsuite/testrra.py | 4 ++-- scripts/v.import/testsuite/test_v_import.py | 4 ++-- vector/v.extract/testsuite/test_v_extract.py | 4 ++-- vector/v.net/testsuite/test_v_net.py | 4 ++-- vector/v.random/testsuite/test_v_random.py | 6 ++--- vector/v.select/testsuite/test_v_select.py | 4 ++-- vector/v.to.3d/testsuite/test_vto3d.py | 9 ++++--- 17 files changed, 61 insertions(+), 47 deletions(-) diff --git a/gui/wxpython/mapswipe/frame.py b/gui/wxpython/mapswipe/frame.py index a7dd0df8f56..b7b81636605 100644 --- a/gui/wxpython/mapswipe/frame.py +++ b/gui/wxpython/mapswipe/frame.py @@ -545,15 +545,15 @@ class _onDone: we are pasting together 2 rendered images, so we need to know when both are finished.""" - def __init__(self2): + def __init__(self2): # noqa: N805 self2.called = 0 - def __call__(self2): + def __call__(self2): # noqa: N805 self2.called += 1 if self2.called == 2: self2.process() - def process(self2): + def process(self2): # noqa: N805 # create empty white image - needed for line im = wx.Image(width, height) im.Replace(0, 0, 0, 255, 255, 255) diff --git a/pyproject.toml b/pyproject.toml index 2a2287aaaad..ed9cd2255a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ select = [ "INT", # flake8-gettext (INT) "ISC", # flake8-implicit-str-concat (ISC) "LOG", # flake8-logging (LOG) + "N", # pep8-naming (N) "NPY", # NumPy-specific rules (NPY) "PERF", # Perflint (PERF) "PGH", # pygrep-hooks (PGH) @@ -145,6 +146,16 @@ ignore = [ "FBT003", # boolean-positional-value-in-call "I001", # unsorted-imports "ISC003", # explicit-string-concatenation + "N801", # invalid-class-name + "N802", # invalid-function-name + "N803", # invalid-argument-name + "N806", # non-lowercase-variable-in-function + "N812", # lowercase-imported-as-non-lowercase + "N814", # camelcase-imported-as-constant + "N815", # mixed-case-variable-in-class-scope + "N816", # mixed-case-variable-in-global-scope + "N818", # error-suffix-on-exception-name + "N999", # invalid-module-name "PERF203", # try-except-in-loop "PERF401", # manual-list-comprehension "PERF402", # manual-list-copy diff --git a/python/grass/pygrass/modules/interface/testsuite/test_modules.py b/python/grass/pygrass/modules/interface/testsuite/test_modules.py index 3318154f87d..ee005498692 100644 --- a/python/grass/pygrass/modules/interface/testsuite/test_modules.py +++ b/python/grass/pygrass/modules/interface/testsuite/test_modules.py @@ -21,7 +21,7 @@ class ModulesMeta(type): - def __new__(mcs, name, bases, dict): + def __new__(cls, name, bases, dict): def gen_test(cmd): def test(self): Module(cmd) @@ -36,7 +36,7 @@ def test(self): for cmd in cmds: test_name = "test__%s" % cmd.replace(".", "_") dict[test_name] = gen_test(cmd) - return type.__new__(mcs, name, bases, dict) + return type.__new__(cls, name, bases, dict) class TestModules(TestCase, metaclass=ModulesMeta): diff --git a/python/grass/script/tests/test_script_task.py b/python/grass/script/tests/test_script_task.py index 6799885761e..cae8735827e 100644 --- a/python/grass/script/tests/test_script_task.py +++ b/python/grass/script/tests/test_script_task.py @@ -1,11 +1,11 @@ -from grass.script.task import grassTask as gtask +from grass.script.task import grassTask def test_mapcalc_simple_e_name(): - gt = gtask("r.mapcalc.simple") + gt = grassTask("r.mapcalc.simple") assert gt.get_param("e")["name"] == "e" def test_mapcalc_simple_expession_name(): - gt = gtask("r.mapcalc.simple") + gt = grassTask("r.mapcalc.simple") assert gt.get_param("expression")["name"] == "expression" diff --git a/raster/r.basins.fill/testsuite/testrbf.py b/raster/r.basins.fill/testsuite/testrbf.py index b9937b05689..eaa57388150 100644 --- a/raster/r.basins.fill/testsuite/testrbf.py +++ b/raster/r.basins.fill/testsuite/testrbf.py @@ -47,8 +47,8 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): - cls.runModule("g.remove", flags="f", type="raster", name=cls.output) + def tearDown(self): + self.runModule("g.remove", flags="f", type="raster", name=self.output) def test_no1(self): lakes = "lakes" diff --git a/raster/r.series/testsuite/test_r_series.py b/raster/r.series/testsuite/test_r_series.py index 93bfd129242..e067a26e1da 100644 --- a/raster/r.series/testsuite/test_r_series.py +++ b/raster/r.series/testsuite/test_r_series.py @@ -18,13 +18,13 @@ def setUpClass(cls): call_module("r.mapcalc", expression=f"{cls.sum_mapcalc} = {cls.elevation} * 4") @classmethod - def tearDownClass(self): - self.del_temp_region() + def tearDownClass(cls): + cls.del_temp_region() call_module( "g.remove", flags="f", type_="raster", - name=self.sum_mapcalc, + name=cls.sum_mapcalc, ) def tearDown(self): diff --git a/raster/r.terraflow/testsuite/test_r_terraflow.py b/raster/r.terraflow/testsuite/test_r_terraflow.py index 62ee0eee15d..4085151a337 100644 --- a/raster/r.terraflow/testsuite/test_r_terraflow.py +++ b/raster/r.terraflow/testsuite/test_r_terraflow.py @@ -23,25 +23,25 @@ def tearDownClass(cls): """!Remove the temporary region""" cls.del_temp_region() - def setUp(cls): + def setUp(self): """Create input data for steady state groundwater flow computation""" - if not os.path.exists(cls.testdir): - os.mkdir(cls.testdir) + if not os.path.exists(self.testdir): + os.mkdir(self.testdir) - def test_univar_mfd(cls): + def test_univar_mfd(self): # compute a steady state groundwater flow - cls.assertModule( + self.assertModule( "r.terraflow", overwrite=True, verbose=True, - elevation=cls.elevation, + elevation=self.elevation, filled="terra_flooded", direction="terra_flowdir", swatershed="terra_sink", accumulation="terra_flowaccum", tci="terra_tci", - directory=cls.testdir, - stats=cls.teststats, + directory=self.testdir, + stats=self.teststats, ) # Output of r.univar -g @@ -111,16 +111,16 @@ def test_univar_mfd(cls): sum=8341670.75914752""" # cls.assertRasterFitsUnivar(raster="terra_flooded", reference=terra_flooded_univar, precision=3) - cls.assertRasterFitsUnivar( + self.assertRasterFitsUnivar( raster="terra_flowdir", reference=terra_flowdir_univar, precision=3 ) - cls.assertRasterFitsUnivar( + self.assertRasterFitsUnivar( raster="terra_sink", reference=terra_sink_univar, precision=3 ) - cls.assertRasterFitsUnivar( + self.assertRasterFitsUnivar( raster="terra_flowaccum", reference=terra_flowaccum_univar, precision=3 ) - cls.assertRasterFitsUnivar( + self.assertRasterFitsUnivar( raster="terra_tci", reference=terra_tci_univar, precision=3 ) diff --git a/raster/r.to.vect/testsuite/test_r_to_vect.py b/raster/r.to.vect/testsuite/test_r_to_vect.py index fbd27af6a33..7826bf44084 100644 --- a/raster/r.to.vect/testsuite/test_r_to_vect.py +++ b/raster/r.to.vect/testsuite/test_r_to_vect.py @@ -28,8 +28,8 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): - cls.runModule("g.remove", type="vector", flags="f", name=cls.output) + def tearDown(self): + self.runModule("g.remove", type="vector", flags="f", name=self.output) def test_flags(self): """Testing flag s""" diff --git a/raster/r.viewshed/testsuite/test_r_viewshed.py b/raster/r.viewshed/testsuite/test_r_viewshed.py index b6825c62018..2b136abd551 100644 --- a/raster/r.viewshed/testsuite/test_r_viewshed.py +++ b/raster/r.viewshed/testsuite/test_r_viewshed.py @@ -15,10 +15,10 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): + def tearDown(self): """Remove viewshed map after each test method""" # TODO: eventually, removing maps should be handled through testing framework functions - cls.runModule("g.remove", flags="f", type="raster", name=cls.viewshed) + self.runModule("g.remove", flags="f", type="raster", name=self.viewshed) def test_limits(self): """Test if results is in expected limits""" diff --git a/scripts/r.import/testsuite/test_r_import.py b/scripts/r.import/testsuite/test_r_import.py index 0e4ec3839e5..075b3a363cf 100755 --- a/scripts/r.import/testsuite/test_r_import.py +++ b/scripts/r.import/testsuite/test_r_import.py @@ -13,9 +13,9 @@ class TestRImportRegion(TestCase): def setUpClass(cls): cls.runModule("g.region", raster="elevation") - def tearDown(cls): + def tearDown(self): """Remove imported map after each test method""" - cls.runModule("g.remove", flags="f", type="raster", name=cls.imported) + self.runModule("g.remove", flags="f", type="raster", name=self.imported) def test_import_estimate(self): """Test e flag""" diff --git a/scripts/r.reclass.area/testsuite/testrra.py b/scripts/r.reclass.area/testsuite/testrra.py index e6e2300875b..8270c122129 100644 --- a/scripts/r.reclass.area/testsuite/testrra.py +++ b/scripts/r.reclass.area/testsuite/testrra.py @@ -26,8 +26,8 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): - cls.runModule("g.remove", type="raster", flags="f", name=cls.output) + def tearDown(self): + self.runModule("g.remove", type="raster", flags="f", name=self.output) def test_flag_c(self): """Testing flag c""" diff --git a/scripts/v.import/testsuite/test_v_import.py b/scripts/v.import/testsuite/test_v_import.py index d8dd6b85887..90934bbb3e6 100755 --- a/scripts/v.import/testsuite/test_v_import.py +++ b/scripts/v.import/testsuite/test_v_import.py @@ -18,9 +18,9 @@ class TestVImport(TestCase): imported = "test_v_import_imported" - def tearDown(cls): + def tearDown(self): """Remove imported map after each test method""" - cls.runModule("g.remove", flags="f", type="vector", name=cls.imported) + self.runModule("g.remove", flags="f", type="vector", name=self.imported) def test_import_same_proj_gpkg(self): """Import GPKG in same proj, default params""" diff --git a/vector/v.extract/testsuite/test_v_extract.py b/vector/v.extract/testsuite/test_v_extract.py index d266e8ad649..7f067c5723e 100644 --- a/vector/v.extract/testsuite/test_v_extract.py +++ b/vector/v.extract/testsuite/test_v_extract.py @@ -54,8 +54,8 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): - cls.runModule("g.remove", flags="f", type="vector", name=cls.output) + def tearDown(self): + self.runModule("g.remove", flags="f", type="vector", name=self.output) def test_flagd(self): """Testing flag d""" diff --git a/vector/v.net/testsuite/test_v_net.py b/vector/v.net/testsuite/test_v_net.py index 469ac127f47..50bb047628f 100644 --- a/vector/v.net/testsuite/test_v_net.py +++ b/vector/v.net/testsuite/test_v_net.py @@ -6,10 +6,10 @@ class TestVNet(TestCase): network = "test_vnet" - def tearDown(cls): + def tearDown(self): """Remove viewshed map after each test method""" # TODO: eventually, removing maps should be handled through testing framework functions - cls.runModule("g.remove", flags="f", type="vector", name=cls.network) + self.runModule("g.remove", flags="f", type="vector", name=self.network) def test_nodes(self): """Test""" diff --git a/vector/v.random/testsuite/test_v_random.py b/vector/v.random/testsuite/test_v_random.py index d11faf458f9..7b68434f46b 100644 --- a/vector/v.random/testsuite/test_v_random.py +++ b/vector/v.random/testsuite/test_v_random.py @@ -30,9 +30,9 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): - cls.runModule( - "g.remove", type="vector", flags="f", name=(cls.output, cls.output2) + def tearDown(self): + self.runModule( + "g.remove", type="vector", flags="f", name=(self.output, self.output2) ) def test_num_points(self): diff --git a/vector/v.select/testsuite/test_v_select.py b/vector/v.select/testsuite/test_v_select.py index b8564505a6a..c72aac8c4cc 100644 --- a/vector/v.select/testsuite/test_v_select.py +++ b/vector/v.select/testsuite/test_v_select.py @@ -17,8 +17,8 @@ class TestRasterReport(TestCase): ainput = "geology" output = "testvselect" - def tearDown(cls): - cls.runModule("g.remove", type="vector", flags="f", name=cls.output) + def tearDown(self): + self.runModule("g.remove", type="vector", flags="f", name=self.output) def test_opo(self): """Testing operator overlap""" diff --git a/vector/v.to.3d/testsuite/test_vto3d.py b/vector/v.to.3d/testsuite/test_vto3d.py index bfa982ddd87..2297ec3a174 100644 --- a/vector/v.to.3d/testsuite/test_vto3d.py +++ b/vector/v.to.3d/testsuite/test_vto3d.py @@ -15,10 +15,13 @@ def setUpClass(cls): def tearDownClass(cls): cls.del_temp_region() - def tearDown(cls): + def tearDown(self): """Remove contours map after each test method""" - cls.runModule( - "g.remove", flags="f", type="vector", name=[cls.contours2d, cls.contours3d] + self.runModule( + "g.remove", + flags="f", + type="vector", + name=[self.contours2d, self.contours3d], ) def test_contours(self): From 884fc6f93d9b2090b5fcff149376dd4eeda3f6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 20 Oct 2024 11:13:19 -0400 Subject: [PATCH 58/69] style: Fix multi-value-repeated-key-literal (F601) (Pylint W0109) (#4557) Ruff rule: https://docs.astral.sh/ruff/rules/multi-value-repeated-key-literal/ Pylint : https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/duplicate-key.html --- gui/wxpython/gmodeler/model.py | 1 - pyproject.toml | 1 - python/grass/script/raster.py | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 23e308037ff..fdf6ac63b36 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -2285,7 +2285,6 @@ def _processComments(self): "size": size, "text": text, "id": int(node.get("id", -1)), - "text": text, } ) diff --git a/pyproject.toml b/pyproject.toml index ed9cd2255a1..6aa9e062c29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -136,7 +136,6 @@ ignore = [ "F401", # unused-import "F403", # undefined-local-with-import-star "F405", # undefined-local-with-import-star-usage - "F601", # multi-value-repeated-key-literal "F811", # redefined-while-unused "F821", # undefined-name "F822", # undefined-export diff --git a/python/grass/script/raster.py b/python/grass/script/raster.py index bcaab7ef596..54c1219dbaf 100644 --- a/python/grass/script/raster.py +++ b/python/grass/script/raster.py @@ -66,7 +66,7 @@ def raster_history(map, overwrite=False, env=None): "Unable to write history for <%(map)s>. " "Raster map <%(map)s> not found in current mapset." ) - % {"map": map, "map": map} + % {"map": map} ) return False From 32723e04f5edddf4ccca280efa05afbb122929d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 20 Oct 2024 11:34:46 -0400 Subject: [PATCH 59/69] style: Fix if-else-block-instead-of-dict-get (SIM401) (#4558) Ruff rule: https://docs.astral.sh/ruff/rules/if-else-block-instead-of-dict-get/ Python docs: https://docs.python.org/3/library/stdtypes.html#dict.get The get method never raises a KeyError. --- gui/wxpython/iclass/frame.py | 2 +- gui/wxpython/mapdisp/frame.py | 2 +- gui/wxpython/vnet/dialogs.py | 5 +---- gui/wxpython/vnet/vnet_core.py | 5 +---- pyproject.toml | 1 - python/grass/temporal/register.py | 5 +---- scripts/i.pansharpen/i.pansharpen.py | 5 +---- 7 files changed, 6 insertions(+), 19 deletions(-) diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py index 606c364c76f..b19d8d7d3ac 100644 --- a/gui/wxpython/iclass/frame.py +++ b/gui/wxpython/iclass/frame.py @@ -515,7 +515,7 @@ def ActivateSecondMap(self, event=None): def GetMapToolbar(self): """Returns toolbar with zooming tools""" - return self.toolbars["iClassMap"] if "iClassMap" in self.toolbars else None + return self.toolbars.get("iClassMap", None) def GetClassColor(self, cat): """Get class color as string diff --git a/gui/wxpython/mapdisp/frame.py b/gui/wxpython/mapdisp/frame.py index c9b5d86e4ba..0a1660ff06a 100644 --- a/gui/wxpython/mapdisp/frame.py +++ b/gui/wxpython/mapdisp/frame.py @@ -1569,7 +1569,7 @@ def SetProperties( def GetMapToolbar(self): """Returns toolbar with zooming tools""" - return self.toolbars["map"] if "map" in self.toolbars else None + return self.toolbars.get("map", None) def GetDialog(self, name): """Get selected dialog if exist""" diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index 8d24b08df91..ee553a0b741 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -1015,10 +1015,7 @@ def OnAnalysisChanged(self, event): attrCols = an_props["cmdParams"]["cols"] for col in attrCols.keys(): - if "inputField" in attrCols[col]: - colInptF = attrCols[col]["inputField"] - else: - colInptF = col + colInptF = attrCols[col].get("inputField", col) if col in skip: continue diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index 2e98aa2ee8f..f55550e65e2 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -744,10 +744,7 @@ def _setInputParams(self, analysis, params, flags): inParams = [] for col, v in self.data.GetAnalysisProperties()["cmdParams"]["cols"].items(): - if "inputField" in v: - colInptF = v["inputField"] - else: - colInptF = col + colInptF = v.get("inputField", col) inParams.append(col + "=" + params[colInptF]) diff --git a/pyproject.toml b/pyproject.toml index 6aa9e062c29..eeffbc0ec95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -249,7 +249,6 @@ ignore = [ "SIM116", # if-else-block-instead-of-dict-lookup "SIM118", # in-dict-keys "SIM223", # expr-and-false - "SIM401", # if-else-block-instead-of-dict-get "SLF001", # private-member-access "TRY002", # raise-vanilla-class "TRY003", # raise-vanilla-args diff --git a/python/grass/temporal/register.py b/python/grass/temporal/register.py index 8b7852ab557..92be36a3547 100644 --- a/python/grass/temporal/register.py +++ b/python/grass/temporal/register.py @@ -264,10 +264,7 @@ def register_maps_in_space_time_dataset( end = row["end"] # Use the semantic label from file - if "semantic_label" in row: - semantic_label = row["semantic_label"] - else: - semantic_label = None + semantic_label = row.get("semantic_label", None) is_in_db = map_object.is_in_db(dbif, mapset) diff --git a/scripts/i.pansharpen/i.pansharpen.py b/scripts/i.pansharpen/i.pansharpen.py index bb271c07deb..e78581c8845 100755 --- a/scripts/i.pansharpen/i.pansharpen.py +++ b/scripts/i.pansharpen/i.pansharpen.py @@ -750,10 +750,7 @@ def matchhist(original, target, matched): ) for n in range(256): - if str(n) in stats_dict: - num_cells = stats_dict[str(n)] - else: - num_cells = 0 + num_cells = stats_dict.get(str(n), 0) cum_cells += num_cells From e523163b16c24df62d23c7e5bf149846ae2d42d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 20 Oct 2024 16:02:11 -0400 Subject: [PATCH 60/69] style: Enable checking for E ruff rules from pycodestyle, fixing simple issues (#4560) * style: Fix missing-whitespace (E231) * style: Fix mixed-spaces-and-tabs (E101) Ruff rule: https://docs.astral.sh/ruff/rules/mixed-spaces-and-tabs/ * style: Enable checking for E ruff rules from pycodestyle * style: Fix multiple-leading-hashes-for-block-comment (E266) Ruff rule: https://docs.astral.sh/ruff/rules/multiple-leading-hashes-for-block-comment/ For gui/wxpython/psmap/frame.py, the commented code was present since it was moved from addons to the main repo 13 years ago. At the time, both pair of lines had the same indentation, before PEP8 only formatted the second lines. File temporal/t.rast.what/t.rast.what.py is ignored for E265 and E266, as it is being addressed in #4550 --- gui/wxpython/psmap/dialogs.py | 2 +- gui/wxpython/psmap/frame.py | 4 ---- pyproject.toml | 8 +++----- python/grass/temporal/univar_statistics.py | 4 ++-- raster/r.basins.fill/testsuite/testrbf.py | 4 ++-- .../r.in.ascii/testsuite/test_r_in_ascii.py | 4 ++-- raster/r.proj/testsuite/test_rproj.py | 20 +++++++++---------- raster/r.reclass/testsuite/test_r_reclass.py | 4 ++-- raster/r.tile/testsuite/testrt.py | 4 ++-- raster/r.what/testsuite/testrw.py | 4 ++-- scripts/r.reclass.area/testsuite/testrra.py | 4 ++-- vector/v.extract/testsuite/test_v_extract.py | 4 ++-- .../v.vect.stats/testsuite/test_vect_stats.py | 4 ++-- 13 files changed, 32 insertions(+), 38 deletions(-) diff --git a/gui/wxpython/psmap/dialogs.py b/gui/wxpython/psmap/dialogs.py index 0bbe779818a..c4784525cc9 100644 --- a/gui/wxpython/psmap/dialogs.py +++ b/gui/wxpython/psmap/dialogs.py @@ -3619,7 +3619,7 @@ def _rasterLegend(self, notebook): self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend) self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete) self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous) - ## self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize) + # self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize) self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range) self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster) diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index 13fdc91a984..1d937483123 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -780,8 +780,6 @@ def OnAddRaster(self, event): if not self._checkMapFrameExists(type_id=id): return - ## dlg = RasterDialog(self, id = id, settings = self.instruction) - # dlg.ShowModal() if "mapNotebook" in self.openDialogs: self.openDialogs["mapNotebook"].notebook.ChangeSelection(1) else: @@ -800,8 +798,6 @@ def OnAddVect(self, event): if not self._checkMapFrameExists(type_id=id): return - ## dlg = MainVectorDialog(self, id = id, settings = self.instruction) - # dlg.ShowModal() if "mapNotebook" in self.openDialogs: self.openDialogs["mapNotebook"].notebook.ChangeSelection(2) else: diff --git a/pyproject.toml b/pyproject.toml index eeffbc0ec95..4b7856bab3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,9 +34,7 @@ select = [ "COM", # flake8-commas (COM) "D", # pydocstyle (D) "DTZ", # flake8-datetimez (DTZ) - "E4", # pycodestyle (E, W) - "E7", # pycodestyle (E, W) - "E9", # pycodestyle (E, W) + "E", # pycodestyle (E, W) "F", # Pyflakes (F) "FA", # flake8-future-annotations (FA) "FBT", # flake8-boolean-trap (FBT) @@ -127,8 +125,8 @@ ignore = [ "DTZ006", # call-datetime-fromtimestamp "DTZ007", # call-datetime-strptime-without-zone "DTZ011", # call-date-today - "E401", # multiple-imports-on-one-line "E402", # module-import-not-at-top-of-file + "E501", # line-too-long "E721", # type-comparison "E722", # bare-except "E731", # lambda-assignment @@ -366,7 +364,7 @@ ignore = [ "temporal/t.rast.algebra/testsu*/*_algebra_arithmetic.py" = ["FLY002"] "temporal/t.rast.colors/t.rast.colors.py" = ["SIM115"] "temporal/t.rast.series/t.rast.series.py" = ["SIM115"] -"temporal/t.rast.what/t.rast.what.py" = ["SIM115"] +"temporal/t.rast.what/t.rast.what.py" = ["E265", "E266", "SIM115"] "temporal/t.register/testsu*/*_raster_different_local.py" = ["FLY002"] "temporal/t.register/testsu*/*_raster_mapmetadata.py" = ["FLY002"] "temporal/t.register/testsuite/test_t_register_raster.py" = ["FLY002"] diff --git a/python/grass/temporal/univar_statistics.py b/python/grass/temporal/univar_statistics.py index 96a9f65474d..dd334e7e9f1 100755 --- a/python/grass/temporal/univar_statistics.py +++ b/python/grass/temporal/univar_statistics.py @@ -103,7 +103,7 @@ def compute_univar_stats(registered_map_info, stats_module, fs, rast_region=Fals for perc in stats_module.inputs.percentile: perc_value = stats[ "percentile_" - f"{str(perc).rstrip('0').rstrip('.').replace('.','_')}" + f"{str(perc).rstrip('0').rstrip('.').replace('.', '_')}" ] string += f"{fs}{perc_value}" string += eol @@ -220,7 +220,7 @@ def print_gridded_dataset_univar_statistics( cols.extend( [ "percentile_" - f"{str(perc).rstrip('0').rstrip('.').replace('.','_')}" + f"{str(perc).rstrip('0').rstrip('.').replace('.', '_')}" for perc in percentile ] ) diff --git a/raster/r.basins.fill/testsuite/testrbf.py b/raster/r.basins.fill/testsuite/testrbf.py index eaa57388150..4077a2113a4 100644 --- a/raster/r.basins.fill/testsuite/testrbf.py +++ b/raster/r.basins.fill/testsuite/testrbf.py @@ -5,8 +5,8 @@ Author: Sunveer Singh Copyright: (C) 2017 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ import unittest diff --git a/raster/r.in.ascii/testsuite/test_r_in_ascii.py b/raster/r.in.ascii/testsuite/test_r_in_ascii.py index cff31b7b3e2..baa892d83a8 100644 --- a/raster/r.in.ascii/testsuite/test_r_in_ascii.py +++ b/raster/r.in.ascii/testsuite/test_r_in_ascii.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2017 Copyright: (C) 2017 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ from grass.gunittest.case import TestCase diff --git a/raster/r.proj/testsuite/test_rproj.py b/raster/r.proj/testsuite/test_rproj.py index 5f3834be881..678e8b7cd06 100644 --- a/raster/r.proj/testsuite/test_rproj.py +++ b/raster/r.proj/testsuite/test_rproj.py @@ -57,7 +57,7 @@ def run_rproj_test(self, method, statics): The expected statics of the output raster """ output = method - ## Get the boundary and set up region for the projected map + # Get the boundary and set up region for the projected map stdout = call_module( "r.proj", project=src_project, @@ -80,7 +80,7 @@ def run_rproj_test(self, method, statics): res=1, ) - ## Project the map + # Project the map self.assertModule( "r.proj", project=src_project, @@ -91,13 +91,13 @@ def run_rproj_test(self, method, statics): quiet=True, ) - ## Validate the output + # Validate the output self.assertRasterFitsUnivar(output, reference=statics, precision=1e-7) self.assertRasterFitsInfo(output, reference=raster_info, precision=1e-7) def test_nearest(self): """Testing method nearest""" - ## Set up variables and validation values + # Set up variables and validation values method = "nearest" statics = """n=40930 min=55.5787925720215 @@ -109,7 +109,7 @@ def test_nearest(self): def test_bilinear(self): """Testing method bilinear""" - ## Set up variables and validation values + # Set up variables and validation values method = "bilinear" statics = """n=40845 min=56.3932914733887 @@ -121,7 +121,7 @@ def test_bilinear(self): def test_bicubic(self): """Testing method bicubic""" - ## Set up variables and validation values + # Set up variables and validation values method = "bicubic" statics = """n=40677 min=56.2407836914062 @@ -133,7 +133,7 @@ def test_bicubic(self): def test_lanczos(self): """Testing method lanczos""" - ## Set up variables and validation values + # Set up variables and validation values method = "lanczos" statics = """n=40585 min=56.2350921630859 @@ -145,7 +145,7 @@ def test_lanczos(self): def test_bilinear_f(self): """Testing method bilinear_f""" - ## Set up variables and validation values + # Set up variables and validation values method = "bilinear_f" statics = """n=40930 min=55.5787925720215 @@ -157,7 +157,7 @@ def test_bilinear_f(self): def test_bicubic_f(self): """Testing method bicubic_f""" - ## Set up variables and validation values + # Set up variables and validation values method = "bicubic_f" statics = """n=40930 min=55.5787925720215 @@ -169,7 +169,7 @@ def test_bicubic_f(self): def test_lanczos_f(self): """Testing method lanczos_f""" - ## Set up variables and validation values + # Set up variables and validation values method = "lanczos_f" statics = """n=40930 min=55.5787925720215 diff --git a/raster/r.reclass/testsuite/test_r_reclass.py b/raster/r.reclass/testsuite/test_r_reclass.py index 3f4ecfdf6a3..8b1eb2e523a 100644 --- a/raster/r.reclass/testsuite/test_r_reclass.py +++ b/raster/r.reclass/testsuite/test_r_reclass.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2017 Copyright: (C) 2017 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ from grass.gunittest.case import TestCase diff --git a/raster/r.tile/testsuite/testrt.py b/raster/r.tile/testsuite/testrt.py index 6cb5a91c296..a26ff967d33 100644 --- a/raster/r.tile/testsuite/testrt.py +++ b/raster/r.tile/testsuite/testrt.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2018 Copyright: (C) 2018 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ from grass.gunittest.case import TestCase diff --git a/raster/r.what/testsuite/testrw.py b/raster/r.what/testsuite/testrw.py index 8184f534720..fdaf7eec98c 100644 --- a/raster/r.what/testsuite/testrw.py +++ b/raster/r.what/testsuite/testrw.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2018 Copyright: (C) 2018 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ from grass.gunittest.case import TestCase diff --git a/scripts/r.reclass.area/testsuite/testrra.py b/scripts/r.reclass.area/testsuite/testrra.py index 8270c122129..5e11bf6aecc 100644 --- a/scripts/r.reclass.area/testsuite/testrra.py +++ b/scripts/r.reclass.area/testsuite/testrra.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2018 Copyright: (C) 2018 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ from grass.gunittest.case import TestCase diff --git a/vector/v.extract/testsuite/test_v_extract.py b/vector/v.extract/testsuite/test_v_extract.py index 7f067c5723e..958f153d1a3 100644 --- a/vector/v.extract/testsuite/test_v_extract.py +++ b/vector/v.extract/testsuite/test_v_extract.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2017 Copyright: (C) 2017 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ import os diff --git a/vector/v.vect.stats/testsuite/test_vect_stats.py b/vector/v.vect.stats/testsuite/test_vect_stats.py index fe982ceff33..e8a1c30c966 100644 --- a/vector/v.vect.stats/testsuite/test_vect_stats.py +++ b/vector/v.vect.stats/testsuite/test_vect_stats.py @@ -5,8 +5,8 @@ Author: Sunveer Singh, Google Code-in 2017 Copyright: (C) 2017 by Sunveer Singh and the GRASS Development Team Licence: This program is free software under the GNU General Public - License (>=v2). Read the file COPYING that comes with GRASS - for details. + License (>=v2). Read the file COPYING that comes with GRASS + for details. """ from grass.gunittest.case import TestCase From 870343fe17389f3d40d0c6fa81a906d07805ac65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:06:56 -0400 Subject: [PATCH 61/69] style: Fix if-else-block-instead-of-if-exp (SIM108) (part 1) (#4561) Ruff rule: https://docs.astral.sh/ruff/rules/if-else-block-instead-of-if-exp Since the amount of changes for SIM108 are quite large, (more than 330), I've decided to split the fixes in more than 1 PR. I kept `scripts/*`, `python/*` and `gui/*` in other PRs. To avoid conflicts, I didn't commit the modified `pyproject.toml`, nor extra typing annotations that I used to help guiding and validating these fixes. * style: Fix if-else-block-instead-of-if-exp (SIM108) in utils/ * style: Fix if-else-block-instead-of-if-exp (SIM108) in lib/init/grass.py * style: Fix if-else-block-instead-of-if-exp (SIM108) in doc/ * style: Fix if-else-block-instead-of-if-exp (SIM108) in man/build_html.py * style: Fix if-else-block-instead-of-if-exp (SIM108) in temporal/ * style: Manual fixes of if-else-block-instead-of-if-exp (SIM108) in temporal/ --- doc/python/raster_example_ctypes.py | 5 +-- doc/python/vector_example_ctypes.py | 5 +-- lib/init/grass.py | 33 ++++----------- man/build_html.py | 5 +-- temporal/t.info/t.info.py | 6 +-- temporal/t.list/t.list.py | 5 +-- temporal/t.rast.accdetect/t.rast.accdetect.py | 41 ++++--------------- .../t.rast.accumulate/t.rast.accumulate.py | 38 ++++------------- temporal/t.rast.aggregate/t.rast.aggregate.py | 5 +-- temporal/t.rast.to.rast3/t.rast.to.rast3.py | 5 +-- temporal/t.rast.what/t.rast.what.py | 20 ++------- temporal/t.rename/t.rename.py | 11 +---- temporal/t.topology/t.topology.py | 5 +-- temporal/t.unregister/t.unregister.py | 7 +--- .../t.vect.observe.strds.py | 7 +--- .../t.vect.what.strds/t.vect.what.strds.py | 9 ++-- utils/g.html2man/ggroff.py | 5 +-- utils/mkrest.py | 5 +-- utils/ppmrotate.py | 7 +--- utils/update_version.py | 5 +-- 20 files changed, 48 insertions(+), 181 deletions(-) diff --git a/doc/python/raster_example_ctypes.py b/doc/python/raster_example_ctypes.py index 67f7a2cf4cb..54de0aab30b 100644 --- a/doc/python/raster_example_ctypes.py +++ b/doc/python/raster_example_ctypes.py @@ -40,10 +40,7 @@ sys.exit("You must be in GRASS GIS to run this program") # parse command line arguments, prompt user for a raster map name if one wasn't given -if len(sys.argv) == 2: - input = sys.argv[1] -else: - input = input("Name of raster map? ") +input = sys.argv[1] if len(sys.argv) == 2 else input("Name of raster map? ") # initialize GRASS library G_gisinit("") diff --git a/doc/python/vector_example_ctypes.py b/doc/python/vector_example_ctypes.py index ae3877224d0..27053d653c9 100644 --- a/doc/python/vector_example_ctypes.py +++ b/doc/python/vector_example_ctypes.py @@ -33,10 +33,7 @@ if "GISBASE" not in os.environ: sys.exit("You must be in GRASS GIS to run this program.") -if len(sys.argv) == 2: - input = sys.argv[1] -else: - input = input("Name of vector map? ") +input = sys.argv[1] if len(sys.argv) == 2 else input("Name of vector map? ") # initialize GRASS library G_gisinit("") diff --git a/lib/init/grass.py b/lib/init/grass.py index d2d8301c52b..505d48dadae 100755 --- a/lib/init/grass.py +++ b/lib/init/grass.py @@ -125,7 +125,7 @@ def clean_env(): write_gisrc(env_new, gisrc) -def is_debug(): +def is_debug() -> bool: """Returns True if we are in debug mode For debug messages use ``debug()``. @@ -133,13 +133,8 @@ def is_debug(): global _DEBUG if _DEBUG is not None: return _DEBUG - _DEBUG = os.getenv("GRASS_DEBUG") # translate to bool (no or empty variable means false) - if _DEBUG: - _DEBUG = True - else: - _DEBUG = False - return _DEBUG + return bool(os.getenv("GRASS_DEBUG")) def debug(msg): @@ -553,10 +548,7 @@ def write_gisrc(kv, filename, append=False): def add_mapset_to_gisrc(gisrc, grassdb, location, mapset): - if os.access(gisrc, os.R_OK): - kv = read_gisrc(gisrc) - else: - kv = {} + kv = read_gisrc(gisrc) if os.access(gisrc, os.R_OK) else {} kv["GISDBASE"] = grassdb kv["LOCATION_NAME"] = location kv["MAPSET"] = mapset @@ -564,10 +556,7 @@ def add_mapset_to_gisrc(gisrc, grassdb, location, mapset): def add_last_mapset_to_gisrc(gisrc, last_mapset_path): - if os.access(gisrc, os.R_OK): - kv = read_gisrc(gisrc) - else: - kv = {} + kv = read_gisrc(gisrc) if os.access(gisrc, os.R_OK) else {} kv["LAST_MAPSET_PATH"] = last_mapset_path write_gisrc(kv, gisrc) @@ -1333,11 +1322,8 @@ def get_shell(): sh = os.path.basename(sh) else: # If SHELL is not set, see if there is Bash and use it. - if shutil.which("bash"): - sh = "bash" - else: - # Fallback to sh if there is no Bash on path. - sh = "sh" + # Fallback to sh if there is no Bash on path. + sh = "bash" if shutil.which("bash") else "sh" # Ensure the variable is set. os.environ["SHELL"] = sh @@ -1651,11 +1637,8 @@ def sh_like_startup(location, location_name, grass_env_file, sh): else: f.write("test -r ~/.alias && . ~/.alias\n") - if os.getenv("ISISROOT"): - # GRASS GIS and ISIS blend - grass_name = "ISIS-GRASS" - else: - grass_name = "GRASS" + # GRASS GIS and ISIS blend + grass_name = "GRASS" if not os.getenv("ISISROOT") else "ISIS-GRASS" if sh == "zsh": f.write("setopt PROMPT_SUBST\n") diff --git a/man/build_html.py b/man/build_html.py index 0ef860d42f3..a8cc4c057a5 100644 --- a/man/build_html.py +++ b/man/build_html.py @@ -464,10 +464,7 @@ def write_html_cmd_overview(f): def write_html_footer(f, index_url, year=None): - if year is None: - cur_year = default_year - else: - cur_year = year + cur_year = default_year if year is None else year f.write( footer_tmpl.substitute( grass_version=grass_version, index_url=index_url, year=cur_year diff --git a/temporal/t.info/t.info.py b/temporal/t.info/t.info.py index 575446030a1..c04fe0c0a5f 100755 --- a/temporal/t.info/t.info.py +++ b/temporal/t.info/t.info.py @@ -103,11 +103,7 @@ def main(): if not system and not name: gs.fatal(_("Please specify %s=") % ("name")) - if name.find("@") >= 0: - id_ = name - else: - id_ = name + "@" + gs.gisenv()["MAPSET"] - + id_ = name if name.find("@") >= 0 else name + "@" + gs.gisenv()["MAPSET"] dataset = tgis.dataset_factory(type_, id_) if not dataset.is_in_db(dbif): diff --git a/temporal/t.list/t.list.py b/temporal/t.list/t.list.py index 52285d04b83..c41bcae4e22 100755 --- a/temporal/t.list/t.list.py +++ b/temporal/t.list/t.list.py @@ -123,10 +123,7 @@ def main(): outfile = open(outpath, "w") for ttype in temporal_type.split(","): - if ttype == "absolute": - time = "absolute time" - else: - time = "relative time" + time = "absolute time" if ttype == "absolute" else "relative time" stds_list = tgis.get_dataset_list(type, ttype, columns, where, order, dbif=dbif) diff --git a/temporal/t.rast.accdetect/t.rast.accdetect.py b/temporal/t.rast.accdetect/t.rast.accdetect.py index 1588b44d4b9..17433e06f3f 100644 --- a/temporal/t.rast.accdetect/t.rast.accdetect.py +++ b/temporal/t.rast.accdetect/t.rast.accdetect.py @@ -173,11 +173,7 @@ def main(): mapset = tgis.get_current_mapset() - if input.find("@") >= 0: - id = input - else: - id = input + "@" + mapset - + id = input if input.find("@") >= 0 else input + "@" + mapset input_strds = tgis.SpaceTimeRasterDataset(id) if not input_strds.is_in_db(): @@ -261,10 +257,7 @@ def main(): # The minimum threshold space time raster dataset minimum_strds = None if minimum: - if minimum.find("@") >= 0: - minimum_id = minimum - else: - minimum_id = minimum + "@" + mapset + minimum_id = minimum if minimum.find("@") >= 0 else minimum + "@" + mapset minimum_strds = tgis.SpaceTimeRasterDataset(minimum_id) if not minimum_strds.is_in_db(): @@ -282,10 +275,7 @@ def main(): # The maximum threshold space time raster dataset maximum_strds = None if maximum: - if maximum.find("@") >= 0: - maximum_id = maximum - else: - maximum_id = maximum + "@" + mapset + maximum_id = maximum if maximum.find("@") >= 0 else maximum + "@" + mapset maximum_strds = tgis.SpaceTimeRasterDataset(maximum_id) if not maximum_strds.is_in_db(): @@ -304,16 +294,10 @@ def main(): if input_strds.is_time_absolute(): start = tgis.string_to_datetime(start) - if stop: - stop = tgis.string_to_datetime(stop) - else: - stop = input_strds_end + stop = tgis.string_to_datetime(stop) if stop else input_strds_end else: start = int(start) - if stop: - stop = int(stop) - else: - stop = input_strds_end + stop = int(stop) if stop else input_strds_end if input_strds.is_time_absolute(): end = tgis.increment_datetime_by_string(start, cycle) @@ -365,10 +349,7 @@ def main(): if indicator: num_maps = len(input_maps) for i in range(num_maps): - if reverse: - map = input_maps[num_maps - i - 1] - else: - map = input_maps[i] + map = input_maps[num_maps - i - 1] if reverse else input_maps[i] if ( input_strds.get_temporal_type() == "absolute" @@ -637,19 +618,13 @@ def compute_occurrence( # Aggregate num_maps = len(input_maps) for i in range(num_maps): - if reverse: - map = input_maps[num_maps - i - 1] - else: - map = input_maps[i] + map = input_maps[num_maps - i - 1] if reverse else input_maps[i] # Compute the days since start input_start, input_end = map.get_temporal_extent_as_tuple() td = input_start - start - if map.is_time_absolute(): - days = tgis.time_delta_to_relative_time(td) - else: - days = td + days = tgis.time_delta_to_relative_time(td) if map.is_time_absolute() else td if input_strds.get_temporal_type() == "absolute" and tsuffix == "gran": suffix = tgis.create_suffix_from_datetime( diff --git a/temporal/t.rast.accumulate/t.rast.accumulate.py b/temporal/t.rast.accumulate/t.rast.accumulate.py index 6fe067e02bc..d254d21c110 100644 --- a/temporal/t.rast.accumulate/t.rast.accumulate.py +++ b/temporal/t.rast.accumulate/t.rast.accumulate.py @@ -192,11 +192,7 @@ def main(): mapset = tgis.get_current_mapset() - if input.find("@") >= 0: - id = input - else: - id = input + "@" + mapset - + id = input if input.find("@") >= 0 else input + "@" + mapset input_strds = tgis.SpaceTimeRasterDataset(id) if not input_strds.is_in_db(): @@ -205,10 +201,7 @@ def main(): input_strds.select(dbif) - if output.find("@") >= 0: - out_id = output - else: - out_id = output + "@" + mapset + out_id = output if output.find("@") >= 0 else output + "@" + mapset # The output space time raster dataset output_strds = tgis.SpaceTimeRasterDataset(out_id) @@ -244,11 +237,7 @@ def main(): # The lower threshold space time raster dataset if lower: - - if lower.find("@") >= 0: - lower_id = lower - else: - lower_id = lower + "@" + mapset + lower_id = lower if lower.find("@") >= 0 else lower + "@" + mapset lower_strds = tgis.SpaceTimeRasterDataset(lower_id) if not lower_strds.is_in_db(): @@ -271,11 +260,7 @@ def main(): _("The upper option works only in conjunction with the lower option") ) - if upper.find("@") >= 0: - upper_id = upper - else: - upper_id = upper + "@" + mapset - + upper_id = upper if upper.find("@") >= 0 else upper + "@" + mapset upper_strds = tgis.SpaceTimeRasterDataset(upper_id) if not upper_strds.is_in_db(): dbif.close() @@ -293,17 +278,11 @@ def main(): if input_strds.is_time_absolute(): start = tgis.string_to_datetime(start) - if stop: - stop = tgis.string_to_datetime(stop) - else: - stop = input_strds_end + stop = tgis.string_to_datetime(stop) if stop else input_strds_end start = tgis.adjust_datetime_to_granularity(start, granularity) else: start = int(start) - if stop: - stop = int(stop) - else: - stop = input_strds_end + stop = int(stop) if stop else input_strds_end if input_strds.is_time_absolute(): end = tgis.increment_datetime_by_string(start, cycle) @@ -371,10 +350,7 @@ def main(): num_maps = len(gran_list) for i in range(num_maps): - if reverse: - map = gran_list[num_maps - i - 1] - else: - map = gran_list[i] + map = gran_list[num_maps - i - 1] if reverse else gran_list[i] # Select input maps based on temporal topology relations input_maps = [] if map.get_equal(): diff --git a/temporal/t.rast.aggregate/t.rast.aggregate.py b/temporal/t.rast.aggregate/t.rast.aggregate.py index 609d6d19d38..0675407794a 100755 --- a/temporal/t.rast.aggregate/t.rast.aggregate.py +++ b/temporal/t.rast.aggregate/t.rast.aggregate.py @@ -218,10 +218,7 @@ def main(): dbif, gs.overwrite(), ) - if register_null: - register_null = False - else: - register_null = True + register_null = not register_null tgis.register_map_object_list( "rast", diff --git a/temporal/t.rast.to.rast3/t.rast.to.rast3.py b/temporal/t.rast.to.rast3/t.rast.to.rast3.py index 7776d7426ee..118e19549c6 100755 --- a/temporal/t.rast.to.rast3/t.rast.to.rast3.py +++ b/temporal/t.rast.to.rast3/t.rast.to.rast3.py @@ -183,10 +183,7 @@ def main(): gs.warning(_("%s failed to set units.") % "r3.support") # Register the space time voxel cube in the temporal GIS - if output.find("@") >= 0: - id = output - else: - id = output + "@" + mapset + id = output if output.find("@") >= 0 else output + "@" + mapset start, end = sp.get_temporal_extent_as_tuple() r3ds = tgis.Raster3DDataset(id) diff --git a/temporal/t.rast.what/t.rast.what.py b/temporal/t.rast.what/t.rast.what.py index b3cec73a538..4d13c6a924c 100755 --- a/temporal/t.rast.what/t.rast.what.py +++ b/temporal/t.rast.what/t.rast.what.py @@ -410,10 +410,7 @@ def one_point_per_row_output( for i in range(len(values)): start, end = map_list[i].get_temporal_extent_as_tuple() - if vcat: - cat_str = "{ca}{sep}".format(ca=cat, sep=separator) - else: - cat_str = "" + cat_str = "{ca}{sep}".format(ca=cat, sep=separator) if vcat else "" if site_input: coor_string = ( "%(x)10.10f%(sep)s%(y)10.10f%(sep)s%(site_name)s%(sep)s" @@ -480,10 +477,7 @@ def one_point_per_col_output( out_str = "start%(sep)send" % ({"sep": separator}) # Define different separator for coordinates and sites - if separator == ",": - coor_sep = ";" - else: - coor_sep = "," + coor_sep = ";" if separator == "," else "," for row in matrix: if vcat: @@ -517,10 +511,7 @@ def one_point_per_col_output( first = False - if vcat: - ncol = 4 - else: - ncol = 3 + ncol = 4 if vcat else 3 for col in range(num_cols - ncol): start, end = output_time_list[count][col].get_temporal_extent_as_tuple() time_string = "%(start)s%(sep)s%(end)s" % ( @@ -567,10 +558,7 @@ def one_point_per_timerow_output( if write_header: if first is True: - if vcat: - header = "cat{sep}".format(sep=separator) - else: - header = "" + header = "cat{sep}".format(sep=separator) if vcat else "" if site_input: header += "x%(sep)sy%(sep)ssite" % ({"sep": separator}) else: diff --git a/temporal/t.rename/t.rename.py b/temporal/t.rename/t.rename.py index a6aee79b790..a1f1a164fee 100755 --- a/temporal/t.rename/t.rename.py +++ b/temporal/t.rename/t.rename.py @@ -59,15 +59,8 @@ def main(): # Get the current mapset to create the id of the space time dataset mapset = gs.gisenv()["MAPSET"] - if input.find("@") >= 0: - old_id = input - else: - old_id = input + "@" + mapset - - if output.find("@") >= 0: - new_id = output - else: - new_id = output + "@" + mapset + old_id = input if input.find("@") >= 0 else input + "@" + mapset + new_id = output if output.find("@") >= 0 else output + "@" + mapset # Do not overwrite yourself if new_id == old_id: diff --git a/temporal/t.topology/t.topology.py b/temporal/t.topology/t.topology.py index 4356596f319..e9da9b369a7 100755 --- a/temporal/t.topology/t.topology.py +++ b/temporal/t.topology/t.topology.py @@ -74,10 +74,7 @@ def main(): spatial = None if spatio_temporal_relations: - if sp.get_type() == "strds": - spatial = "2D" - else: - spatial = "3D" + spatial = "2D" if sp.get_type() == "strds" else "3D" if temporal_relations or spatio_temporal_relations: sp.print_spatio_temporal_relationships(maps=maps, spatial=spatial) diff --git a/temporal/t.unregister/t.unregister.py b/temporal/t.unregister/t.unregister.py index b39b7b9819f..cacfe579a7b 100755 --- a/temporal/t.unregister/t.unregister.py +++ b/temporal/t.unregister/t.unregister.py @@ -93,12 +93,7 @@ def main(): # Map names as comma separated string if maps is not None and maps != "": - if maps.find(",") == -1: - maplist = [ - maps, - ] - else: - maplist = maps.split(",") + maplist = [maps] if maps.find(",") == -1 else maps.split(",") # Build the maplist for count in range(len(maplist)): diff --git a/temporal/t.vect.observe.strds/t.vect.observe.strds.py b/temporal/t.vect.observe.strds/t.vect.observe.strds.py index 9c60a3d026c..547f60a3250 100755 --- a/temporal/t.vect.observe.strds/t.vect.observe.strds.py +++ b/temporal/t.vect.observe.strds/t.vect.observe.strds.py @@ -202,11 +202,8 @@ def main(): vector_db = gs.vector.vector_db(input) # We copy the vector table and create the new layers - if vector_db: - # Use the first layer to copy the categories from - layers = "1," - else: - layers = "" + # If vector_db, use the first layer to copy the categories from + layers = "1," if vector_db else "" first = True for layer in range(num_samples): layer += 1 diff --git a/temporal/t.vect.what.strds/t.vect.what.strds.py b/temporal/t.vect.what.strds/t.vect.what.strds.py index 6ea36e79579..b1f2c17a9c6 100755 --- a/temporal/t.vect.what.strds/t.vect.what.strds.py +++ b/temporal/t.vect.what.strds/t.vect.what.strds.py @@ -158,12 +158,9 @@ def main(): raster_maps = (new_map.get_id(),) for rastermap in raster_maps: - if column: - col_name = column - else: - # Create a new column with the SQL compliant - # name of the sampled raster map - col_name = rastermap.split("@")[0].replace(".", "_") + # Create a new column with the SQL compliant + # name of the sampled raster map if not column + col_name = column or rastermap.split("@")[0].replace(".", "_") coltype = "DOUBLE PRECISION" # Get raster type diff --git a/utils/g.html2man/ggroff.py b/utils/g.html2man/ggroff.py index e62c5ec2b1c..a0458dd0334 100644 --- a/utils/g.html2man/ggroff.py +++ b/utils/g.html2man/ggroff.py @@ -119,10 +119,7 @@ def fmt(self, format, content, var=None): self.show(pre) if sep != "": if var: - if var == "index": - val = self.get("index") + [0] - else: - val = True + val = self.get("index") + [0] if var == "index" else True self.pp_with(content, var, val) else: self.pp(content) diff --git a/utils/mkrest.py b/utils/mkrest.py index 24481bc3374..8d156e0bcc7 100755 --- a/utils/mkrest.py +++ b/utils/mkrest.py @@ -21,10 +21,7 @@ from datetime import datetime pgm = sys.argv[1] -if len(sys.argv) > 1: - year = sys.argv[2] -else: - year = str(datetime.now().year) +year = sys.argv[2] if len(sys.argv) > 1 else str(datetime.now().year) src_file = "%s.html" % pgm tmp_file = "%s.tmp.txt" % pgm diff --git a/utils/ppmrotate.py b/utils/ppmrotate.py index ec041e0f253..cef32eba0f4 100755 --- a/utils/ppmrotate.py +++ b/utils/ppmrotate.py @@ -110,11 +110,8 @@ def convert_and_rotate(src, dst, flip=False): to_png = False if dst.lower().endswith(".png"): to_png = True - if to_png: - tmp_img = gs.tempfile() + ".ppm" - # TODO: clean up the file - else: - tmp_img = dst + # TODO: clean up the file + tmp_img = gs.tempfile() + ".ppm" if to_png else dst write_ppm(tmp_img, ppm) if to_png: ppmtopng(dst, tmp_img) diff --git a/utils/update_version.py b/utils/update_version.py index c66a34a62cd..947e68a1648 100755 --- a/utils/update_version.py +++ b/utils/update_version.py @@ -226,10 +226,7 @@ def status(args): version_info = read_version_file() today = datetime.date.today().isoformat() version = construct_version(version_info) - if not version_info.micro.endswith("dev"): - tag = version - else: - tag = None + tag = version if not version_info.micro.endswith("dev") else None if args.bash: status_as_bash(version_info=version_info, today=today, version=version, tag=tag) else: From 5d4f7fb6dc36a05b0b02d0d301756b3b5033531d Mon Sep 17 00:00:00 2001 From: ShubhamDesai <42180509+ShubhamDesai@users.noreply.github.com> Date: Mon, 21 Oct 2024 08:32:27 -0400 Subject: [PATCH 62/69] v.hull: fix null pointer dereference issues (#4524) --- vector/v.hull/chull.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/v.hull/chull.c b/vector/v.hull/chull.c index 93dfd15742e..cd8dcf52153 100644 --- a/vector/v.hull/chull.c +++ b/vector/v.hull/chull.c @@ -687,6 +687,8 @@ void CleanEdges(void) e = edges; DELETE(edges, e); } + if (!edges) + return; e = edges->next; do { if (e->delete) { @@ -711,6 +713,8 @@ void CleanFaces(void) f = faces; DELETE(faces, f); } + if (!faces) + return; f = faces->next; do { if (f->visible) { @@ -746,6 +750,8 @@ void CleanVertices(void) v = vertices; DELETE(vertices, v); } + if (!vertices) + return; v = vertices->next; do { if (v->mark && !v->onhull) { From 24b398a38159a88e2b4b41241cd578b3fee15052 Mon Sep 17 00:00:00 2001 From: Anna Petrasova Date: Mon, 21 Oct 2024 09:48:43 -0400 Subject: [PATCH 63/69] r.sim.water: add tests (#4551) --- .../testsuite/data/depth_complex.pack | Bin 0 -> 36093 bytes .../testsuite/data/depth_default.pack | Bin 0 -> 25906 bytes .../testsuite/data/discharge_complex.pack | Bin 0 -> 38375 bytes .../testsuite/data/discharge_default.pack | Bin 0 -> 38180 bytes .../r.sim.water/testsuite/test_r_sim_water.py | 201 ++++++++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 raster/r.sim/r.sim.water/testsuite/data/depth_complex.pack create mode 100644 raster/r.sim/r.sim.water/testsuite/data/depth_default.pack create mode 100644 raster/r.sim/r.sim.water/testsuite/data/discharge_complex.pack create mode 100644 raster/r.sim/r.sim.water/testsuite/data/discharge_default.pack create mode 100644 raster/r.sim/r.sim.water/testsuite/test_r_sim_water.py diff --git a/raster/r.sim/r.sim.water/testsuite/data/depth_complex.pack b/raster/r.sim/r.sim.water/testsuite/data/depth_complex.pack new file mode 100644 index 0000000000000000000000000000000000000000..60f9de2be64c74c7d2c2dc1d40a8b0385bd0810a GIT binary patch literal 36093 zcmV)pK%2iGiwFp@%MND(|72xwbZB2=Z*6dFWq2-dVPk6m?7azCjcwQe-#k*Os7R$j zgyw0lwXQ^(MW%#MDn%Mpl91*}hC(Ts8pte4C^U#sse`t@B*#qOGH?WA5k{YUAnV;Tg#DZyCD%_;642_J9``*{n zH_$WTQ8D@}{ol2`}P9cNkpd;H(n z*zmue|Md+1Vg5HT);Hu)(fup^|8F|~djnq@eB-BvGDg>>L2Lqwu1d?nY&m(p#O4E zS>f(3=HV8+$`@4p+&oMT#N0r|*ucb8&%i`mSIjdARCKl37G@b5nCkY;A*{Z1-_%5G zgt^d_GFz)kzLw&=6`rm>1e_;Oqzcl~r_RaqT`+tAa`G4tRP7O%# zUl;!y8~wxlZ)9SkI}rc>6(e{}fG4OdUE%K*EVg7#u;*g`z&;%Sl~9jBu@zyf7rXoW z1_XKr1ugUUTfBs`Jvd=tLvTR<2lW4cwf>v->Hom`-``gMSFUpN3;v(=|9`3f1_uAA z|Hk?Q`+tAQ&;>p1KI7=>^|`)*KFhRkE;cqcg}%23+H{6qnjuB9}H?&f#(im;PL?<1&%UG%jc z_5Z(f{@>>i|Ff;Y|NZ*^Kkfe;4DA2^HN$+-*v(D1Qh3aDON>q?E{o=i(HL-w0sSA) z|G%~V5A=WijrE^>JM=k)Z@^!s|9bzZ|HgX81O2~$$xSApcc=ddqq zrT_jb{!Q-x-|D}iuKqti|8t=J?=Kk|D!MBF)B$KBrVIK;Mx2L#>iuCP6GN7Xp^=^e z`wZtlU9tb>Jp1!T+|zxhbd5}PjY0R1^J4$X?#H}|se%DXa4gCaeKLYOWC&R6$H>>QY`Rsm9 zYVD^*NIxyP{Q_1y`)R|y&bH_KX>Z@psoZ{uX}-)J(qMysT{SqsWJNU$K+tGN9Pt2O%>%B{x_v+d{FrhcyH_G^TH?`H(J-ylkwes1ITJ8Xa5&$PAu+&QS98N2(r zi`&nUb&1P5y)i{PKU}x+^xdF+_X01^My)bF&P8F}xIG#6Y%9Q#W5nR{#!@(WVH0G( zWr1rE3*rqmV9O#C*id~1hR)Q3Fn;@j@Wv~0`!PB40lb`6f!;kM zp?HN5+(_Vo&GS7VYV%~+Yg!Cvj{uZD=|D02hd9*k6B_2vLuNx7&TTQm`HIibGiM@h zFP@A$N95w}L$7dK-F4iq){f;%6;Lgs2p-toguJdmaBIy4qxr{J-EmPn<9K1Y1ga(?#)z!M z7gI&i?SdOdR~2Et+Btj}Yl-g*yGVW?r@^D&AP;ZthfUuyk;haW_J(Cb)al0%BPb6$ zTv(94@FDmuEr%rsZb72tO}I1U9o%+23hiRQaG1q0+!f@2dwula=E)u?o+gBjDfeKP zR1s`m-wIo1`h#Pn2FECeGSr}^B^){@yhT~byC|b(iehso!?$xmIO44sPU;pzgJqFu zBIt;A_uO&1^?tlnoQ@%j+@a=@JXn?hJlkb}ykT!a_ii?v>FR<@RzILRUmx~*93TOi zb;MIDh2@Si*!%4eiMCge*wHW>)bV)Uf zQXkgRJkOn^ms>~{JFk)vE1is8J`jIM42jpJk=)M+ygu~+X8vqJ$Dx7P!uJK6=C7pK zv8%95;3b~m-AX(k2hkYWcw%|B|29afCqU5>BPcj61-k`rfMnq$SU$rYf_iVl=B2>O zwy%K2UN0e6>L?^+`@qplQ{cnLb7%rDF?3BhyztrtMLKnmB%z6_!I$82_et2k*bi2h z)xq}KHIVt@6BL#`f(vm=;qD_tIQNPN4$G~8mqwB(uC4$*-SsF`G6{uOyg;ZW^s<0M+T(Bk$rK8w$_b2u)lf|SRa-@(iN)sp5 zk!Z4yCvCFbF8gH*exz;2tVurJ#fvY2L;t6CfD!GTs7!tV;6tcNgYk0nHi z#enSUxe%f<6%NiC2T#sFLD8KrP`dUtY~AGti+{km*(~UFDMBG@S>$~#k2Br+rkkIS z(74kb+Qvyj`M3@6u{IJ_+e^*Tm-I}W{cDQZW|>nMXt4&Tep5x6g`3E7+%<~&;6Zs= zx^ztb0_8k*r&Zz;NpoxtDK=gq9HCDkCk<$_%S-rwUXu4{c~=C5 z^35j8b^#LHR!i~~#iX?QCdW7)4bn8-zmmooe4~*KE+mu}i*?}&#B2MErtOI*t(8lN zH7A5TG7O2;yzxH_0?zA9Inxqr<|&ATa8O9rgAl(&&Q!K=WH5|%7Ubwh=;S>d-6&mu z3$nGw!Tpcg(7kdugvl<0#A9CIS&<0m*RO%XC+a}^Zi8)xH0%yegHyX>q3&lf+`l;u z-pG~0=Yu=omZbpPG!2F);z{r*M;PAeKZ72nTC_0fMTfJ!sPLc~E}9EMTEiUjO!+~d zr|+fDD{q-C6i=OKEEj9$I^`Em4ts~1R!>pIXDjXB!%q(u@20&g=Ft2|1sdhgOUj`y zNYQmKjh)?hA;oe@x3hpuPf3%;WnL1qy-IxIx@1%JisHsg&`OtHauIk&(iNXb$80F} zp3B4Q{tcw7T0k1f^)xAV7|oTrPK)$n$UKoD$E;*p+Eqje+keq=-3;=a=}gns@1>bj zKaj_`r!=iZj?C%;X^3q#X=5f{N&P}Y1}9*IP&z!qa!J&pL0B-&p0rAi7^<41%ifq9r#$Bh9rG=*jMod zF5UVHk)M-bInNsKUGNaXU*tk~x&~;qM{+*9Y_KgH0t=|nsf7o*v!MIYQ{;CDgtvqI z;NI#puxGdj99(zD)%l--YXFokZHxYFS@*<>5=hQwan!6&U9_s%$7*es>-ZJ8vQBaC14c4DjH zc{0fICPn{OWK?BKikpU!R?AA#sF_dV8KX%hK!7IS$fwEi_T)BcH%axj;g?|zG+pf? z=}Xlne zfukEup(MT&9+|d4P24A_eRvuwq(4C8qjso&HV+Q3`pS-upkPl9+&{D&+FgC2ge4Ct zPMbmJZ3=vAsHRV;{#YsS1wyh9!JLjRxc+oC%7hi5?@kR|TX+_yTsn&J@3)iO4LwHP zN0X+E<0YlJl{EZg7pc@2lG@{OWY?BNvm#tcul6&ImmEo&7e#6Gv8SXmYX-L5uEsX` zqQ0M9NXBE=lJVO46d;j8RneJ@{N5afS7tR89$Y{HFY;+{Z4kZ`noj(KW%0}1pENl5 z75=)+i;V|{W0Cnu8lpS|?};tJ`{f%*tuJ_3eZYZS(^rz3&^A(9nMo#fE+l9vNW#jY zxb$i=@qJYzm9=)1yr`4rTgZ}gL)>oRDZpvc@P zXcIZk5%s8%77!%i2(gt`oZN&R&d&4~g1tY-g56USPz}<7#O52Y&u1G{Y~_XK&dKok zPB;$ET8=XQmr*k}702H+MuU4YC~f@#6*rsV$i~|^+2$k8S3ZFY&Q3+Mg^F10phzDb zy=h^666ALJ!jg)GkiYajyuTTT6Wp)h67x0;Tm1vI(>!s+s$KZ~{4+CSD|s^^fe~~j z`8Zhw22=1iK{69_qP2cCaG1ra^-fEKKi?yWv%z`kwlN5RE@zbe~*vLBvbLR%)@kKePI)R6H zwmA^=>XTts3LQ%jrR?c8GFzm205}a2zp8;L(Gq06wETlx$}-9%mE!JIBY^uh)E6F4YZ9H%%fM}s%s zs9^CNMYYDjv5Hox{~m!FsWRlHH=W)afSJyYcC&FyHJNc!Pt&8zV;SD6Uv%GkIHerw zpiPClX@R0VX;>wZc-mLScpJ=JevpiY{$wuPEn}p^t0{5wQ$i<6 z!kH5I=|c^6~uAdV$oDAY3% z1+w$ufI$+J6-VNdeMfQL!e?mU-wHo|?nIuFHk59D0#^g>ax(ThX=iAfmj#is88Gfd z17yA*4Z){oLdvB?IL&VaO(SfeJ~$Vi#7&1DO-bYx&O~w1G~^GihF@n5;HOy^yqa5# zqHju3=IJ)PXuOv$E6Cuoj$2TxVTdoJvyj!fB9G2=Pr<#>Up`_;}}G?1(R+<>f1={b?w@wAev*4>d@&=@V&I z9%WBiSpF%A#6Hf){F~KS$#cTA!{Ri4Q1!vv3-w9a<0rW*oBcLOUucR7SzB=Uo)V~h zH3@dL)S$tjN{l@pi&JM?;jj~7sP26n1)G+^gXbSmqA?jo`8%M}fPqybL_j+>3(Ahw zgQlVvh}(o{i{$FodO^Ij=-0j<;e5?4DuzLqoT%Glv3_S(Z#vA z#UYq357xpD!#}~U{cX_tc^wKH2*asFEoh##ALY$;aMZq&$mdbQj?UoOl@hpku?z)| zRKX2HYvg~INLjoG>CD`Dl(or_E-vh4@~jRqzarl=8Y^q)RZ}S=8ZXTlh&*IO`=*H~ z2UnWq5J_5VCgJ_PhcTu^57kdx#k7zwOj^4Rb9Ln&I$5@yqIY_emz5q(pKDK6b(J(` zvkggKa>9l?efm>YPXhRwq)bQQ*Gor9eYiZG%nfCfx>PAm#-B8=<&p&}fwbhxNa&O< z4K{Mdhn6jPNI3$Zy4*pp+B}>bh8nO)qsOecW^RvzRrhGZ88#4zfK2ri3T{IGLfS%G1E&p z>t7jzhQgiPX86=pfr9tqagh2ulr4`#iL(+Yen|nkPA74~UFr6Ea+Xu4joTZcEmav( z?fbloXEVzE`T}=arEvI-bd>MZ!NFnY;qmDUa5tg?j_$}tKE3Ji{Q6qtn=l_`*GN*f z_+iS5)uM=|U6g%OpHUgT-b|^e+{|t72S%^#AzcW%&&+WSWrj?el1YbX@wQ;nskA4(36Jq^-UF;3r$|C6AF!@T0?!Pc ziATh4p;KilZknD6ar(yiI=7sxht2zK5I*${XwwAfpQg*X(8UM8!|m#YXq}Xd7mMa% zK*B7Xzexlqbge-#I)D=MU&HIi+aM<<8dgQ`W0jlVfo#`haGX~H`6X7uo7ZRI%Jf!v zD(!_5TjX&h5{~|&hRO~KIKFH+vh18u*XS5Zo}GpsGXv>(g)th7pNCx$E8yO-3(z*i z3Wu(bhT{hk;k)~E6qoJdL|NyyRKcb)D>%~F1vidq!;je8@Xq2Gj!N^UWivv^&iFmW z3_DMs<<2uhYV?`WTT9L6D%>=ieQ*;a;B$phv23DuO=l@LweI-&SsjaX+v1}jKq4Hv9xCu@mtQtvzptntM?{0jI6;kcY`t0 z?mq6T48sM{gd<(t$fhXZcOFs_ZUIFRK6oPA@m;ilpqIDfnqC0A`DfrBeC-)boa zw{1oyRR+gO@gc82AH16#3g@24gPoKfxTrjZ^Fce{*4#+QzEKXX&%Ptit5VLqKg41l zj*(o8Q)IP~g80zf#RY929z$)qhm$4eQpiVb+MGQV%Oce@$hgN9~8 z5KqN(?8$?|$2~N5R~2dSMpNGXUgco1^2R~v3ccMY&%zq8G1*E|LIHIoLG-t+KVxA z)H&jp{`lJ8zfQ$up>;UYq6hgx!%^BTg$5mO$HKM)m>eyP4yG~e#1XnR zZJ?@Ai?bTczF;$FNysS~#6u7h)H-@>(sFivh0 zyP}qp?~L)C48J66ahSCgY?PZ0-km^`nj#pHR9k8=x=sr_6KT$>QgZ8fNZ$U#$w!lq z*{T=HT)vgWNV#V-Li;~4v1bNTqv8@gw=&b;wli_B<;ZExaeP^`8Q(v# zAhCz9NoYYiemWU}fyo6}XWfm>H|zYWrJ zqy(~Te!#bYtytL?(s{XvprCIw>h<)c{%arN8Ie8 zlM9R~#O)KZtWDwLFJ|S%E^(Sp*=eI+**yKnl{p0-xzY9J%hHr-9b;Z z^_kDFo|vt(E;o}4h&GcQ+hsQX#X?4N?|U--x`T=0v1Z;cNTHHcKhGw(KynA%Nz=T%91vnyEy4Q9r@dCZi}Q=)GVwo&|uAC%CmM2pov z600(vY(yB69MXveWqsLwej({}ttWG_pESc?n517CkiGdOth#&%ze*g(C&Rw~))0-3 zGmw!W3XQF`IJ5meR%*MU^w-I_hbNxKEPsi26ego<9-^x9Ea=j?M zbB#i;rF9q)CxtdfN${|4Fh}Uwi;b%e--V4YrbCLrWyoB!86K-1!9h8EXrSam!#}u^ zsP}2OeMt*$u5p1A#b=>>$6-hs?Fb7NyoB{~6%dgo4d)h(1_53X&SItAj~6gc%m6E# ze$m`dELPp|RPg;Shf)vUpa%2MZ2PCWk3bB(+oxjoM$r%R`p6gR-8tOF3gaxrMc*1`Uz5fJSk zj;;=4@N%FY_V(<CF^TuzGrMJz8G|eN6!|fl#!J1T*%_HMnHfw{)~&=Z ze~XlR2a}`WamHogE3*KXKr;c;E0n(8k2c{~%IIB28y!?B-t{cGw|$`vdtOn5CyVUu zddPg^U;-6y((o3=JqM&gg~kAI4?vLvAL$q8tGYlQsWJ}C0$ zGb!?4p@V6C5mK`q%4|)-A%^==yyYHz6>5a{Rb!z{bUfsiUV^2Oi4b}B8eC}Cgu^~z z7(6@#zt3u+p#{>|S*L)91q1P_ctl$exV#dayF8JkJ!`5*CPW)(hNR*Mg3 zeWPhfqNM%g0LiiT5)??#g6ErQg4TN4P+0KWAf!GNibwoHm2vgZkY)f)j%Vm}qz_$I zX3$2_7VRT>&@fdNMUFgyTF(hk>BtMa&wPgUEj}=7s~TjmbiuA70er^Xh8P1=uO`0P@ETLX#$syvBHCXXO9_WdAgIn4RJMe245Ij?;1920 zPe-gfLjyrpGy~jqV_@Sf502+7mR*dK=BeYvM@k?wVGWoR7qY`)ayc%`1Sz_i@%~t9 zHuCLMGu_?e%^>EknPbErGZ%M%Gv)Dm%&FV2ne`GLjO=|inw8j!O^}Cy#-3;pJp`Xt znBr--Q8dJ?0pG+fpj%_g87*52`qlD`4xetInZ0Al;p1MKxIU7~biOd9n@%xlKC(1M z%@^yR<&aqXR}xhjiI1N(V~{rw)<)mM6G|pDQl*w;g3?I3=^4g9-a{JJ&*;F3os?D5 zK+C+tC}WiqYZX8@LSp^4dS~wTq_02(WKhMv(aD8_#RAwDP{+v$ay}SS#r;UNV5pr#b6%(9TrEI07#~R>8g`p zVYV5jI7&m9HVcg$QpsGegVvWjQQir8%30({`$rF@f*>oi3Ci!xCK)B0jgu-e8|m`I zOjLLzb1nKM6FRJjUIgwSyCzF=v2|wTE#I0MsiiS1A4Q=0xwo7ZiljzE^q%z)qt3OV z-X%4hn|U5IHYp4qY;VA}&P&)DV~7v0=V0Ub zDlAs&!l>u%SUUa@@eBFk>%E0E?aXDGwDTLb)qg>Aslga=V+F19lxHMPexp0SeO}od zPCFcT(RtOgzYU^dCjl?#&cYSBe5iSAKHNN5Kn0G|NTs(0M-6|2)>dL@lJ^;jI%>*mib>31nIig9BzJ5LVp@bA*B*_3c^YO}YcEF55VFG<%)vSYk8$)NV#T(PFrN z>?KZ^a0`dq_M)!eWV}afNg!@0)`rU92bD_V9TZ7}(wb;EiILo3UDBAELgqH_XhxGE z&E4)ws}-zB?Rhc@4!0%CO-Lph1vKKUA@(N4F+4M+X@S-8qeyZNKM8F*)0dCcW8Rh}7`L+(&k5Z`qoqBlcF+Np9k<}xA+9)8ISP~Czs4>0 zBT3{;3JK+@k@WK>I%0H>W)3IpPa! zvh_uaFmGISNDYkOBzU~M1UVlT-~&dDc#Rg4;KD^DQ1A*LKQYHTcM-g?(+?wG?18VL zA8^CZlcd9%!~|4}G1JG6V+1On(|x`h6j8VWpFhdL{WS`>e@Pe?Fm^cI?GkQ#uozRb zr{kf^=kdzRootWBd?;p;e?NfXAj;ncZCC}%YU1sZ~&>+(?ck~-{5w`DJzz_8##II%ni zCr&6vv+pM$T3!g;y*5IIY7U%v_YqniTA}b%Mb!DCkKUhx;k|1)%;~iRK2)Xmcj|ES`ufrhNcaZAZ`x zmWFM+X5!rzUlR9k$0vt+v8$WGE^#4FlJ@ku1qs#|lk(pEG-ca$+I}#ci8~m_INeEO zMEEB$Cag?mw{9x4TVV~OzkDopgdM^!KI*vd!C<`bS^*EuYQT$ayNU0r1ZIbB#Uk$` zn8)*)vp{$?W)VqtsS&RING2Y}cxl)Rl5TY;`99J1n7xE9jPGEES2WN(ol>uTB{ zHa3w{+;A=NF?<^sEm{FGyK+Iz zJr}0Ui3h8p7deF%^KZT7?B%oblEozp;CZ?Su6DP_4bCc@Y8ZAcz?th$@qO)GQrhT8 zJnCmiF#IdND*aBP2hz#VEP$qbOQI=5!^v;;bGqWK$D~Z>W#o$9(stH7%6QLEzRqoC zjKnEscBL!RdOecaY?X?!vG?)k6)oKAB280PhLKnCFp{3Nl}sMVlcAsiEn8DXt|I&t z`qi1zhiZ`N$jNFY_YXRdF}aF{Bk1x z6znF~>J)1K#m~gg_G98o&3_w2sB#l5)hXfV!L>f2seiVR_-&-wtG}q$gwCsdig;S@&j_#A}Adz0a0l09767YDa4D8kR- zQW$iq3MP9jC|B1kYr$ z%(cSnLP!QJs*H_$Cv)YHHZx?HCM~wTOfq*@<8A*iJpQB_pFC*6_N|g+!FQPU3aK%M zCAXLz4p0BIr+zM-Q<>QJ7p6_V$LPl5bEq?<3r7q0MFxf^(O}jnwbq1y(yZLz$}wnW{)(&!ix%xmb&@*Ey4NTqg}OUqM6X zz9F61WXfKw%NRU*#*8X0rUU#$d7~Z3=CvEP?y$vfT0(H4n3}`7sbj}dGx2s==E21o zq*@w74#OB+ZzPCM&2)d5tpMbmtAz^l zCg92=`!G(a9+Jba0h6&CGUQw!t0fM3XX&B%FG7v+4^aK#CDb*PMA~Fe!?b6kcAh8> z8tDNyXIq2%!vn0(St78yyAp!i3OG5D?ZTCuKx1~uNw$c?$#49yogbj`yE}Wm4chOw zaQ4@SeUO6U2mz=%w3ozP+lcSdZqhKiPNFV+crU<-1V&g8@Ac=jD&QzHIis7t)IB5f z6fZKUi=l0YRY^@@EDgC*OU|m7sVF9#iltd3eN&OK_$tF(jqWD7VY2vf+6_E-YB)A6 zai?ARX3VMa1&p9u423?NLRXn`hIdyaUF{B_=mt4*NPkTyv-B9hZ5B+hxetZqiR1gw z`K0*RhID0ik@(~Y65pnY&3Zd&)R+CV@OT}q@4iN<-`nZ_gFh8pza6av(~iZ!kuiph z!nF5T?`i-$wZu6kIo~p*kS}2>G#BoImU0iyBI2FnV({r)CrVu`gGTwSsM4bjHnRB~ zfww==C+rEUpkzcO{5UldKV>N8t|qFfu@q(+MagT8a9T zAEK18Iu2@FhddDy$a_2yZdkRznPayhRq-Tymk>4Y2*DH?S8!%0dUg$*I^Nocr;#_I z9%USF;OM!$s1tqyr_6sxS|xW$FnJx6bobry{8QlGrHhbtOc43C1mIK0SUBYO1ABWvDee^`Eyf}4ERZ>H&oGq zfRD7}O&8@>9isA*Z}ek+4u$y|6L0GSQr}!g;B}u|gSu$_hRc-jas;W*vBMXtOH1%V>CGDDgxeBBp2z#rH0xF&{-q z&U6d@n%hiXPBp&`!mdCx-(5^U3MbI9wZ~9L=_4w}o1rvyqwq9Q6v-EZ`|T!h*)tLL zpE?W~_pZWz0e`stb_^7He!%ewE|A`I4up?(u=ge)=%^^{Jg^3?2W&_2{FTVc@kjGn zM#yS5B(ch2r1f+jw4@RA=r|y6b~cK?af42QB~Y-cime+^Ah{kA1MY+8#ujjx+RF-A zd;sRGv4P`5FT=NlW=;`CpSZ)7UzV_D+zlu>F&BU4g_BKe1tt32p?H@^v{6!o;!}F5 zP$QGdBSi_EWk~6@IB6F|6HYr!YVYRI^nk(S_tS|)D~qv1;1G?ORYr^6E~3n~bP86A zWW28yGfigS$U@%<1Ggt&i2GI&N%vr)UPv?VpBFM_A%?WF{VW}9pT|ggb~3sXe=&kK zdbE@O33<-AMSel{bn5CGI<5bb7FgPooX}_dvgSM))%nrIy`yOJy$W)glt+B;w$Wgp zy}u2@j{RdRtr$iBNK%@YkFxF#@V!(EZXM2pX3ZG59sdEI^1OtSaCvALTMDfuR`4?E z6sJ`5!eR?l++hZHLV96U@iR_=1AF)Iy!LE(cti_c9j!+tr*9aiFdH`=t;E9}!)dwi zWgI0m10{vVqiW4yXbx$Iqx^-iAKpXtQgcp!NzthbFkSUHjHoh# zGt@bI>lI~#IRVB_5lMKiqe222mH5i(E}5*IL-EefX`E#qEt~e95<05rh@TaiY8<6u z`HD2fH3Ylt9BF7(2+fvmqSc#uC}!nBG9K}rCcbT>Sd%o`uK101yQk7-ux8S(j${@+ zJBlVsiRdbS7azDVWGZ`-iT}Qhx&7Lk;c|ox{nNPmk2?4SySCyNxFuwn$;* zGXyvV2p87vffT!^P{ZGV!ZTWNxa>#H#Xl#%7p~fUhhHak;nH(gPLXv;=@}d{Hl0&C z%8tHHKd|6TM>lU=fJb)e$SaeKZq?41$vX#&lCtrh{R!GQt%OG0@j)wBa}@DQfb!c> zP%T;e#`KWvFbi`;*Pf4(jCF}^_g|Zi3qQm|ibLmWAm8_PLD}OJ8`xkqhjztbVg-7}j)qXjAE=M74&Po*W<6Z=AP6`Hj) zh60*yP=?J+@>;iqyx!a`?L#>i?90+gU}kIVbs{}jwR$~z_C;MJ; zZzQBBYM|J;Zzy}h2ku*C!`&=H{9%qU>Z2yG>0*~PZqb!>D zXdXFbtfMI^jikJ%lN?1ZP)f}bT0N$X#FQ#YJT{-q!w-;FA`kJtT0+`CX3%55b~^U6 z2CpZU;hBmge5*L0#OKD+(8sDY>3KC{qCJs`;2%nYKZat%N@FtJ_nCA*kEgE-9-8sZ zoWOkdnn>5(HEB!0Guo1-P97%{X-1YLxm^jNCDz|4woIGG)iZR!G?C6KUZ-KHOHl0aEgUN(g1)io>;gSV>OxLC z1bc~O?Ta3GUJwAwPOJml`h#E>KMK4R0@!7(BslXu`6%SjiW?`$RDhp`Bo)#W-&WeQ zc?Ipf*F-BSSCL}Xbdoq3OGCmAW6x4kl21NKT2;N2I8A|$S5L=z)^0doHwGI`?P-;H zG9^x4N|E}LskGo0b0zjOvnKrr7Fyep@SzD<-Kk9zN&@NPj8ZcrHzTIbuY%&Q@1n^~ zTBK|IigYD3Xlalo&2F-y)H&B^OZh&AkM9>{zn7+^otG(0U!3Np45w4_9h9$Afp4`m z{=*<>`i>txe=WxR(ND41`T*`Vi^Uiw2Ax};;P_Mn_+|0|sxPnPEGDwouQaYzvA&lG zak6ST!R2gE!7)L}pl`g6U3`taa`C8qpchRfuHdXi9=OPV1&+Jc0QVBlp{jia`VSsN zJCl*j%^l#)%t!F`c{!rsD6}>li{AXoI48G~Z6LU8^ORH2&F;op!fOFDq|d^smSWBh zC%e0g{r_>vIgM=`{Bb9k%pUaRBi*f}Fe`&>7zYY-m!R!oeL_D)kD{tqk!|}9Vv>f? z$U_aJvc1n^3}Q+1WEIUfzQ+vFi=wMOi;2m5M#jal6wAt|6XFNy+L23i``IJLuya3i zJm@_8d(c)_4R^X(k?4qzG}V796Y^<}+2CCnlymejP0Qa$PT$s()3x(7ea07>w{I$y zSm#o6Y#JlAyMr>9?xz(x`zYk_Aj;GWrs9?kYS@2}tThk*Hpn#-Q@pe#0OOW##ED9t zsPf_yO5_Eg+?RSBYpILU+78gZQ4ww|xyha$AZ!0?b}biYYqc+2W^W{+@UL+gD1rvtb;$9 zZ%L=p-t7#Hen=sFy5z|?(~0-t)Zw>*5z5`qh;==qH(w7k#Zqa^6wMY?@m9hedn2)Y zRy%%J)J_)ar_K0WhcJZ)nrNlxDdMktL^_8hXzJAEbkU8%HU9hFYms8(6K4c4LYn9#O;qT-C$-)5H z8>`@b>Q}gDx*vHA)zKm@jFuNIr0r^o7d|VS_#g(u^_ySF^ETi!&wMp^VA{sQOn7u?#{6C+NRaG)Gw)7DrwWpqH^{nWE zbvs??SwK&++^PFk5Y^caV%F3hWO`z5&_?mI`25IMyjwGhL^iUprlpBl?<2=Ny~rYE z-D$Yn)`l#dZqO;=a>ikb6C<<4fI4~;>E*;lbbPNft<_{G-|Q*16uo1{?+9Z&UgcA6 z1^;h@u-EAos2Z*>e9h?v&;B9?Yt}4y=@CCf6pVT zDs6Pfvo(8h`J=UH7AuOXVz*It-&>R${|i2CeZ|hmA>-|2SeL#ZW^W6D8Qb2AU%|Do!; z<9cl0uuEwGEkM%0NrML3nn*kPp67Xg(=Z}4v$99_iil8DqM{*0L!zXlLDEtpWRFM@ z5s~Z};{9IN^L}2x_m4iFkDgNZbzkQ=&f_@FH+$=;M@0vzhCU|cp(98V1xO<+lzOYn z5{i$|{)Tcv%Dj?}>K4*wmqE09%bXTQ2+yXJTN%`P;3B=Vt*6ry*OA}- z7Zh>(33V*#D}3}y7t8EOp}7C{UH*3<5kF($n`RN5PfUS>c4A1)_h*ncR5_Z%y>cTc zE6#&-D;>_+Wl5duLQLBEA?b&H5rsI96}|6k0fygKaWGJlS2+2AA+${9mUE~Z6fUfQ zyCc59>yGKDVe}LIY#!4+?K}ASz%_ITn+6Y!g5glqbXc{}j}azNdrvK#3U!5OVLR+z zdkHd9oFMN`H_jj1mbM7=%yi(qXC9mZS;!P#;pso~Fi!O;ruw&1mzj?ECpnA)))v!f z?@UbW?8FRTIefjh9~mz&Bb7IMNqJj3^*n4%YUi>@Yj-pC%^6D8RVS(F-c3rs>rBz5 zKPk!R3Ei@3peKucDdfv&a_M(cxDi|-JaPO=YNt+OXaD}xb#EAH+sISM{CJ^ZlDiOn zX0tF>R$mAldY8WDv{In`Ns3GNq!zFD)OJplj_-US4q;+ibD8dg$PqTHRej1>sq1J{ zZ{MEt!`Sh+Mzs5I56~GL077vlza^~8-l<~F^UhPnOsG7t0qzGE!}GXCR1@7tw-beQ zBTj}EbU`R>o5v5F=@SnJ^n&{uF{nPN9G)7#gag^XAk8NU9({^}lgWP|#dj}k&HOK? z6ge*BCGxS-C~RpPhc{HOlZ^EvGHMDU_~;A>MTUUQ=$ zTTn|Eu8ybO)tR*NiX(NqJ%!f!qOdyokML`cHtovX@b5rQE%8I`EfcxgsaN$E>}NX! zyUj|6I=jnIRMiL}IbFCQXUgp`@J!N&P4jkx+0RsdAT{Qz*ewAw>nKrtbr7s|w1wcw zc`)0@kC&vbiwyaEBll)KR5X5P>=w9K*cYX1rqJ9Nb82$l1-~WpVhNoJ>L>aBnN}DQKrMPgD9lC537?C6xn#5 z_Pnp9LcfLd>QN2Vygo%WBUFX%k(t8aX$J*Kk1K3(sTLmGFBN{a*^%k503xOCB(=et z+@mJZ#z&8Z3zNqPug9*X3uC8~K|~fQze}SLuRqX^B~JteR1ms89Ysf$-lUT=5(!?7 zp&rL_=-Ggg!qu`R!nAY$sHEh4(H&QMRiL@0CMsph!1t#O@WQnO9+}%f{_T7?u&|tm zpZJ3lV53JqxZOW2deqP#?5FhZ)6a|Q&4wtuR}9YeV#wGRw%)@nHgv}XaE{G zO@_2S0&)jh}lOim5wuN)(_LpCI1u>#xe9@2_s_sK48GWE?J zO@^OlP^k1vO4;E>yM857+ynzkxH*{)hIUf&G%re&Li;a+5z7Na)h~a8 zZnrOt`Xl=BA^^-1`h(q%X*{p&U-pTMK$$-Yv)s6np}@yR)tyz6LHuIb4lhUw>wBJ33^2MBO|7oLo_0Jc{cepJ^(g z!pTCYJYtSAK^gE?qmc}z{vzGWmq>Z@6!3pN z9C4U7rgouvKS40iA1ic^iJ%K6iz(-!mTpOamy)gYy|k{p8m2y&hV zXf?AN%1=9p$`%FCY&f7K~*e|@a^bJX?cf)&!E3kQr2K9eY zN#evYG^6KG3QqH;S&4CXZ(u@N4Zf(5R8l76u<3g`>Amho4$-9)lC+#cUiGI~m0py(CzSS! zlBhD-TTp*EgBsgx=yHyxAphi-U^}>{06PZ=($n)P-!ew5bWKexBeujQzk7I3sQ{N> zRl<^tQW}t2FU0Bp7J`0QklBYCQhqj>Hg~$wvAIctRF#t;@03iH<)u^_vzH3m8-%Xy zS;FS5mxAimf5ri@J|Kv;C7#DucP~QQ^<=nSy#Y>(S|O)12U5!x^AHqi?adt<5`!*5 ze~ulV&xc}^MC_J~(Y%So1OyYr^-``H&(z7On=qhKpW5pt8w^ z!}s;KyE8%_6ieSDXO$#Dc5Zj3i-$W_i{Z`2kvKrv4`nvwqC?+g?5o%tdr$FWNG}dj z3&ep28mRvH7~1~$i*^gl(Lr)EM$|dd>J4Rda)=jQU4IlWWQ@epgx&boFoJWb3U*Ax z8Y_Vu2CSzpCE<9ZT#MAa{*t2Q5VA49N20||)W7#UvMzl|ewrmzzS4@yjTK2%tS$swaLy5}t1r?Q%4>g0tHEt7@e zmX#DdX)`5k^`%Sir3LL1Lj|+<5rR>`LqWz=i)OeSpuNBQ)0~F+*m{4(zY%WD%QVWi zkSBfn*YM$_EW8?agAbz$7N>Rsw#zo#^`u9ATd^=II0oi!Y+_J-q4PvQKd$7t#i zDJV?{L&L&*XqdbnwM~@Z)5yPkX0Nxk6s_;uq4`h;RP*VDLV)B}rI$hb+zNE}U4b^Y zs!&mNK2*9*M3u-HI5KTIE;Q4Juvu$4VD$#$9iOUU+( z;6t}NS2n*`y3=i7I3}&t;QEjd&1=4*t0qahrchxEgeUpRX7B7P0MjY$s6)^ z4iE+xW{B<1)nmr^l`zq83>U(-_!nT~%w=RTz>yq|UnJ*^J?ZT5)8gF;d4k!F)o>so zo^uC|nft-h6n9v!a`s;i(d@rUkk;r<`!3w!+K+3oo^Zrh2GYuR!iJLr`GK&6%^r4G zpcQW(7av9@hZb3_Zi3L398qrVY8JM*dTQ7Nc_=K| z|0`x`6gRy|Oo>Ew)7OH!aVy3hwc!uz;rFBPQj+8iMagKk(h<#y{cu3!Xg*4wGg;C| zdMZNaKx6bNID_uT55xPd1o7<_@O6X?_B?S6*L92Jx0Jyw%)TRL{V+}?ntpL9N|~4< zrOic|(rr9Xem?vMuBAU`+-8XJn9flKcKefB!Z~Eb*fk8$l(Yb-J17tB0&KBIxCIow ze$Tkh=(~B8@VV`Pc;C84x__}J4VRIG$yo;6l8Qx^ROKqzkv59)5GYt}s5tRZoDf=3 zB`Qq41%WjmU|!xgD3Y;4ZMBL24n%zWJZ*BhPH~avq21*N>{D@tguYF1sQwz48blsk zz+HeO4-fXneCFB>mfSVgO>v42F@y1o-t&Jzl<&a%5|&RE+;wL*PB`?*AyoBHg3QPE z%nX1DKOy;iS1yK9tL0+N z;t-M!w8JO66|ni44axmHNj>7GlX-eDO+USyG{;V$qZMJ4-LRL+hg_nIwjp#rdpGqK zwJ@g%(JSL+Fk`$aCVohQa_<@7dLakq>u=`Hdq);rfY^?je+Lqt8ICa)52@(351GlE zK~~o-jCcThN`qi$$|vq|5^Y)x11X=6Q+6GJW)parB^rA^oBpNAJVyNmv?6W|O-FFn?A|GwE)wh7`nA`l2KgrHP zIcaA+VBv*k?xAqo*PNLmKtoop=$*-CNKy5M;^^t9`=9^=O4q^uAtxasHvx8yiH4H} z@o+FQ0XB9Xh2vf3p+m6?DLMb(IdW&KJ##lg^L@6Ms4xtRl^^5mv4`N~B{R78&H=IQ z8uh&Lob0!jQ;*N)kQvuT-kz@XNOKCEQXNU3M?5B6t%aJ&zd6%#fTx(f#1I{GK^Q!E z26Y&O#)dP@lm=piG%g0JJaJF-cTWj7 z%_(_0f&r-{HP{#Tl-|JuK0EMuSSB9J(!el(e{@K>fooS6V2-L0Cc3TyowVzs&+4t9 zY`LE2A!h!W>95S^L+9Ex;N|^ljQ{eN66e|at^J9>8(G_Uso+a8&sd-Eej{dfLwYF6+T$x0eVMhRtBO(C;< zd6*NgPNjGgU%}002x&d-B1j!uE{J0<3u7Y`DE*>8np>{`k59`*`6(Tsw>uvEVsr7k z!8gHWl|3DB=!DMXpYUtxHZ(Puj20^6gJ|t=8sV1wVk`I z8qE~=e1-K`w>;EfSxpgmUAfOZC;9DX9OUFhq40B)19Mj8GQF1eaNO{)AN+l1$ht`lR(g2V&lF z31fPk!D5A1M6u`K+vx{fbGT~jJ@9rZ0*8jfkn*h>8lH4T<>VP)(pk*hf7l4u>C}eR zENqFodn^-mG+yQOAV!SdX*ZV+F8LrlH8DqvvO3)6IUBK13Ozao3yXGo2!ltPfZv}n zqMuui^M}9y$-n{E$bYk+U{G3!8W&BW>gQv0cbSH(cWU6o13p+7wGiElj-m11u{inO z9*pj4i>9x0xVP77^*yMs@fqV2r{Ni;UU2U320m}!S6slWB^J6E`Hmfue9jwQd@u}- zAr9S2mb2nSboKNT_M&kh_1k(6QEIU>BLIq~Z960SRTIa*holX_E>BF*SY;6QTx!Vr zHtf1;A-@^JXPsqHL-h4e8vojuNxgU*z$(mld6%jCbR&4PPK9%s87Ry03Ik!;3!bbO z^Y1|1GLK`pT_;v7Tqm4M_7W;iEr7UVMm+II-Vj*kV#wy{sMQb&S5uvsSFUJfzqL+( zo*!W*D(p{=0EasEf@J{-ka=f66K|rS*BT7Ju?g>k*Cc*s353IXegI&H|!{D=f@lZenmLK1T*`8u_vR{JZ%B?X* zaUSlP-NpzIsBlgWN@m_b>qUuJWqu!PRt(|@^U-)~R5SPHtQKZ97_Sz@UzY!?V`Mo{ zbmOnWe`Jk>eXLUCA@1)Fchn1a;s?PVaDB!LQO*<-?n%kydwH$_DD!hP>Wyz>J}bN# zW z`HxO;W+uNKlCUMpdRzyNKmBmwn!Y&wQ3U37dQq2cCxmdR0>L(PkD$NzIkv2e7pr_Z zC|o#V$ch9$6KBkOCcKd}n2?q0K)b!S2(qJ3;b_g(xVv&I=K3h(1N#N&eB}~n{zZU{eE zRwyy$!5WV(=+KD&4rF&;70!G!1v5SsQm|yPkd? z{sG=et%rDf5epF0f8h20Xc+ZV(KY>cF_Z+asRlZnKZ|E1iy?*1D0c`$9opYN>Ex*d$VX zvrkx9J)P#&ufo~A3Sj$TPhRq}t6bU~%nyWxs?&2ESve|9@7f`ZxUvzKd^Z#ZzZobL zwalQ32TqiKa1AZd*^E=2UQ^Ot9ny2tfuSY_q6#~0QBfCU)eINyFxkOF`{_box$R`0 zk%`lEE@IltZ1hP?fXh!$@B>M;D8>-I@2I&X0CHYEwcp9q8xLl0w0)O70;fb9ouROmbvhrN?!N8CwbJo?LD2~AAE@$x5>#`Aa-^NG1elUJBQr-h-Pr1VyN#=db z=Rzk(CBcuT9%y0HfcFO8#APbP+Xf~|vX0!#@Ij%pdOMxasQh;z$2LWv;hZlR{&A2H zaXdjR9Xm^ipVT3=z-J0`i5Cz3s4FZJD)7oVXR3g-6pt_<%+|OXU z;Iiccf~pbxJkgFnLtF&~?{*>TS~fj>Fod!?YU%vx8q!|4m5e>Ek)Z7jOIn&aY|qL= z7CxL`nDOM-oRbW{N2!r(aGlVrml1lLc!I~zq~L^kl}tl|_7C0h^}1>d-sB3M8XsU= zyDi+CwhBr;Z==cRct*`Zg#deQF(_xB57$j!Fc}`2WsT;p60CG(1q3V8nS#rzi@+RK zabv6u6Y^u^%{sI@yA|aI$KuFa!I=F~2h-MT;D$qOxY;frW0Tk7*;Rm*{nlW%a2l_V z-$SxpgYeh5w;1!|J*T*ymfy_792?NFmLWO&6-v4HWo~%l-j`j4AG2=2^;g@VyQHZu zw;C(dMrjLbHsAgo$gd(Boc*gi#&~!2w83h6dBQ1r0=^dtYbAYVOA_3yC?$~fcYK0~qDD^)P) zF_Dh?1Y+QcV^~(_i&K9jFslsF{b%P`LKl71@#8=xOT6DrB2nXuJ%cI)6aB9k>pvK; zOzMt4BP5NYj|oN{*QGv{Y3S}Wo_FWZdq=}nr+7X`!5gjAy>&3E=Dk3z%Lh9z*@(9&AL-C3K7x`BUd4IwZJZoNI>U zrIp6R$39^6K`o3L@e%#XwQ)*r7)GY85mJV}5E_0e<2~;ioN+VFESBdbR`Sk&{E)F@ z;EANM)F@OETikIL%bp#_dN5unNWvzHAGCmCQ1rh8xo9{A7tGMXFtrRkG-d(ax?N1~ zo2KH@L4R?h${lpSZih=QY{%heY_RXLH!P7t^CvMHBwFy8*{^ISPKp>uW=3I{vaSv- zdfa9uAG!vu##74|k&dh(*$+;jdgg$e=(Jaub8%RmjDAF*WcKKx9GWv0y7J$p8KR2Y%w z06jFzIfl;5W%(usCZW*p+yD<2$BN387BCSIckE^ab5_;8oGi=AaVT?r%8L?7{{-Xa z{^gb*H{V(y=$D}PenL;(J=inkCkHTlM=0*3Fg5bpb zDA={*EaatJ=Q$~+`2e??46}8%zey zZ}G~sBE0vloUR!L3SHI*vP6YjOE2L2v`5&I;fmRQm3TEJ4sR^?zZlbY zS3HsQ(sq!{#=ST^bRTZ9Lv)$rhD)}Hab9jas_$?R?$=Eg=Fb@nJG-d!Mo{v>X7Vtk z<1UQtx)5Y`j^}2Ytm2U50NlIjJl(i=Ly+pM!jy@17z{D^=$jG^E53zR6J)WU;bC+M zFGY>1OHe8I09rLW;K~Q4WEAU-&iAEphTTR~+BAgwMSA|~%O4D*FR>8;6N|DxJ9dcB zAUz!W-F*%xNS2qidIfnLW?=%PkfxbjLg$@(6hj{LMZ4eUQFg=$xI8cyjYPNcjDikn z4O}UR0+tEmFFE4TvkmBA(Fxl(9fXX}D`C=2PhLGTvWKLq!XBCGIA+jzPK#w;$Z>Cr zIj8N~ovCOx=D`09sJ70;w@2DAfA?p6sp(16tX|TU$15=3+mX>~@Xk3ce0y{f{tUWH z>b6g?`T9C6cX7vS17~CEHDzpee?upx4WT_p^+=fCgG}`%;YGhec)mgkXLh=>9V3E| zb*SL5#ZmNUycX-uMO%XVFfbB!1bt)bUH)b=5vbqgE*x@@{32Acxrbm7l7PBNV%!?^ znMTY~M{h*|jn)`p@BBN=$N;`-NgBdX1N0bq85b&qkloOH-05)|XAL&M?$)&^w?Gr8 zAK%NZ)L9c|HSa297F5IGk;M#4g7q;A*(jR!HaOBFqY)hTu%FhG^(7DzcZ1LF-z_`F z?99=7U=c1_`wG*XCXt-wUB+;MOVI-%HZYE>$5#G1#0|?jI`HDu`=M)cC0e|zMD@oRD1Ck=cRFRXA{;UR=hhA-hp5Y# zH(@Q>x*SBcG%*XG3}WGLER)4C22D$GHFhaI441OPISATO(nCnG%@T?{@4(7EB@kUN z1FL##a!~cWe?Rz9_ZsDN7jw_xh#i)AXJs9p4mgHN-E6ts!m#8t4zW!~``5*i)b_i)KeM@rJ57DG4S1DkzB`plyLp$LuSvHrDzQrk;^ps~@+7#BY5>r<0o4APaOSBy;eQS;)>< zrpA~o9GYN^6=loyyf=~bHuzRcQ?RZ&gVU5pQnc|GY}$7fcghaJsrK$@2FqDBgFU)W zz%EJ3ICNJf2J9&yVNC~~+*gk}FT28{dS$e)F~Ch13-~esMy#v+7|v%k17e>st3no@ z(B#`y-uSV?f>BhN=L#e2)ekkh`Z^A3pOhPg;#4*IY`O;Tyzud;6l9y zxQ^WWFJws?Knx)zEX{Ah$EWj2KXfKp)a#M6!3SELmP}3~p3vhCRtePo&mw?R4^KJ5BZ3&zw)0V+6mZ z{X>)a#O&+c_q;o1;e_E#7P}tu$)u!6VDuu=jnfwfxg^r^>slo1naY1TmATp=({mzP zSq*@5f;$eF_MFXIaPjhXjJ>2yldWH1xo-d(Ul|Hj^OvF9DsK#Z=?t$v1~L)_m?L&~btTq73q2A6&OM^d4l5^@Z=1M(}n~PxxV%glYqnQLAbhnxr&B zqt!P!x=GTtFE7N&m1X#WK9EkEudv;BpwKRMhnnNku+3J13sq0(Ho&E?J+No@i5PUL zoG+=_Uh`e3c1#qm2Kh2R9E7i^_;*9BYFFd3C7L+S>=y2nzJ=}Q74d$F5^0*Y(fCbO zH2ZHM#lDiGJz^0pZ7U{gVK`pwJp@xUr{MiBU&%2pggz&Jq%os)@IhJ&UVk)~Y`4zA z^CCYiAK3*82Rz_l8e^-QbQW`6Jln3L-WT`|smN{~9CBa}g2i>_9w#Y>spOcsFu<@D z9Qqi*Bx6f(?H(wqI^2_sbsovoz~w%-xxuF1$PbusLlRD|ou?&^me}m-g%kbn@XyCY zy}^Ssr}G5Q^ofa;BRO!y)7p*jMM&u>8E5!z^+-im%Znh}0ohmebs8C{2E2L+=<2EB(ebxWnkn2)4IPC0W^idFDN^LW~ z6lUOKzec<(+J=uC>hMcsJ^8N~N-<+i>F_FbI^w;Gta9Js0aaHFxaNkxCPtB?W*w#M zokF4ee5tqb6MR@E!kd9TFzKZyv(MmgeZb5NUZ1nD@Havqofcl^)*4Y`{&2ug^44&f z9J?v*t%-tOb|+mPwTYLiFZC=y%565Ey{NkPhO=i@v3WV`*3s?x58N~AEei7E2m?3Z zB}vJyTMY2}MgwNKD&vmvt|%Md6%H#V@_5Z2TIgD79A~`+70o6?wboib_m?zqu+(un zoHngs!cxYzWMKyTth^7;Hcf`o#dA^D{S;b94~O4grkv+|E7*eX!D2HVwk6_4uVzrH zO9e0gq44qZdAPJ;C|3xaw9I3iH4Bd zh^tzkVBq=wn64&^&m^7e=U_dOifhID@&zRS;0xI;3L(|286=21soeiPrEc^jePdb7 z-BE=3wz|}%x`gKM$)$r^%gFwK0!HZ0BrW&h_|Ww&tDsm9z%eUDMR^Weu=&OAogyf< zFW@YBHa}pKIR=@txx$~qO@jNvS)}Ue!~IVf_{WsEEK#zz_({nVs8R_ zztKeJsARG_eHzQ2e?hG!fKrmKThcvqLos$k7}x8x+b>vNl*3S2^wKKDUfcaS7S)#S z04E-#@)7Q#=cl<5=eyn~;ELmT2CAZ2DsU%lMkHr06W^w+L~F+!jNX)t)-hq67Nt4C zmNPjSLN0@HQ1Rjvx*t4%n+Is)dW9iqA-2Qj%mCq(OQKlcOAp+yjOWM!`+kkD|ECX8 zJHHYaOxMil*aD2<8jz?Fk;&=l{7lBV!3)4}rtDe8ip9na=0EU`w1 znBn)fRN;LuJE0Q;@LpdX4$wuP@)HIYMpF{}H>qO+R5tHsFvqr$at!Wf$sFqAmg7YE zA$WBD7d%?G5;v?IM-FWRvG!9nn%|wyt!}sH?Zy?hooF>_7@W&*fcg`|pkUx82Hl|f z5G(BGyAsv*TB1TyB>z0yGQ>ho;fzE$Su86{EDxcj0Dat(-&mj z!H7Yf{Gqbd9gO9Y=NbS-VTFu9!TrX@zqH56C(qJNgA`#IMoU8l?|2>#ecOCc3Dv?!L5I#|Si(~(cz-}HN(NAh9jtd`# zW8+mh=Jj&LWhh-E=Dzih^e1!s!rt;*QSDtes^1?Ab)#Q#J$#bx2JS}j*rgNxJV?VC z*TY$(%bPi-w`9IxZ?G1-7;V6+R}N^gVG!i+S;~usAEP9dm|`xpDfzRzAG3``yY*AOll~+x7r4`oS&l7VppW<**Ix= z0j9LN)3A{Zw9#}BEnl>jmNgtD%NruRHD@4=SAI&JQstDfNfs|IzkvI4caW@}Bl*p) zrqfOpR4tSVP8IzGsU;7=W~?92AB>s83@%x%&)y_SzQB#g!<=RRta6U<*A{o{?=HlC z9w1~b>A<>aQY?&#e%{{9>-BffdvQpE>C)rZA7!zaYfTn?3&r>lcU+^m6AQP`qHa6Q z@pi~g)Vune19}5rpTxnNy5od5r=d-l41*u|!DLerf6(vtNy3fuA{5LlIXYkzQOF=0 z?g_@IK+Qit!TslDsJHRF5IgshFeXzZS6c)Z{}HmlTQ=DaMtqq>m>o(-mqd(%iS*NfEp z@1}E#$Ek5b2sz_^EM2w{_vqW;{XtG-qPT*B*R2+`e`N_8OXav+TGF-hki}*xb?b;r z-=uRg(V#g;@V@a{_;q6wjZqdclNpSCzXR`G`^iN_hp$z!wSMevXU6qhXHrlz2(_}G zW1p>?F>!G&W@##5z>_1`Y-536PcO&&qXU`AKc~d%<;mkD&j_4fUBg)Xyh>vOq=jV~ zD1UrAqq^eU&!#wJoCWJg(6pO6YIlvtowZMdY)g^2tI0YHvfVG%I`mrH-TyO36LV011d>k<{O2w%^u<8VnmBw4(Ob46_1Qehc7P-D1K22WjcvCvE!Pm z62tFsd01CU3Cd%9h5y-(pq~YM3(av@k~EpWxlH~lzvzLGE~H#MM$crmNUH7!ipqau zPGkig5*5?lo!QjYz<@@sG^3{j!>RPmEV4}2!{j9`=v8Hj+nU3%`tD^K(9$e)cN|Ys zhgGm0RV=BC7NmPHRth(~VLiwDoE|L6v+7B7S8}~$noppX(=*gq@Ro0kV>v@7?K)bo z)WTA`tC%gl2K8Eo;H>gaTy{Jk-?S*<>C^+b=0_RzEe*!IJI`Y4Y8U=sb(au#98DQ^ z5PfP~VW{g2R=qK3hR?Gn-SlK{Il9zr!<}`h7&*cWzw9?8^Q9W3n_MaG*7;H#a(pbC z=5YaP{G?B!eYd0duuAehP%H609vf)Idkr>DV2QoFX%1Q?X5g(8Rap6}f_B{)N_$+N zQa{zRR3Gq+d{b1|?Gk;SKMyx98%foYpff2pQQhh}=w+=If-*y7iqlX$T0 zI_}K1!-HSW;oaFFUXr{~9ML`)EcYGa3=YmS4I9!QbbnGZT$&~zhY{S~P zp`>im6-T~O!5!PGF~6{#Rf_PcVhmjV{gTbpMgGG-uxd#3Tt$ja3t7pF%MS+e-L*f= zAH$D5hn&7T+QNn28fc^G#kZfj+m`a1&T=6GA6YMBdgUVCIvPVEE2^-)H5c!W)4&H> zi?PUP1StgD2->L|sA|y#aywx}IiYSey00NPczZ+sY%k_RN%gVyl(q2}GzEy*0slJ? z21~QrdGFluIB)ty-WP1t8q6D=srwH@TZkL&?-MHwJiCWx?HfZEZ@bZiFG<+iYXEs2 zwxSD$6XQi@VZ!p5n0Ff~9EPu82#BBe{>q}0FSX_`*3#Uql@YdGbU^#KfiUKWtR zAByBa_^6a=Np7a^g6yMbA^vGHobNc!XVX5{LLuYsX58O;gC-pp1b6S*bjs}s9sRLY zz?wwy?W8Bpy+Q+p>Mhss$seRHZ)LcPQGEA%z)TsFL{aC%cFo57NV%SQqgvU zQqH_o42p&WJ7?g4`+wlQ=4^I*MG7^qIC?N+nHq;c7!_*a;%j`;#|BHxdxhOF>6GKN zId~}b-C0E{MsrDOP%KGhZlZ#9^Qh5fJs2ceqt_H^{uRAE&Cs!8ViaeEf*ppYnM}7v?o*rj4*&v{pQ1 zksH-+^};2uZ;^3DFct3t!Dg1Opj>;GmO1Rfiw8|G^=B=nt80;N>@u;-nZ?4{>Q>&& z?K%0IFA>XnT*u}id=|oF4F|5r^Td7oN;`++_ig#Wf2J)q8t`#aKE52Vj%-5fN&b!^ z{M~PchW-2C1{*K>d^p)zI!3`I3bec$`v%BK<=-F6i{+lL;)T70mW{#b) z!IRr!IuK04iY628a*R~sw0N&U~dikH7x|=XyRj#Qta?mEQ&y9#lp^V> z9>m{=>Uqt-z`B%ymeAXUfe^Rn`3_Y1?Li$_p@VCEP$#V8@kafZrGSJN9(7vR!6^}h| zODq)}2rDvVcx83jYXKcv>PTUm4)fK5Yj6J%J@irkpM@^X!3?fIqcUyCx_;$9Xn4_k zzO!(~qjbK-O%l%70%DY3?~mo>onns-L&e4Un+3VT8$uVg7ZjXrOwq411U0`|Lj15X zxNe{h>BZ_(*s3qM`dD8Gdo`Txs^T*O{kOL`ZJ)8ynXv%VFS79T*Psb<9d2;#XEZg96qm8^Z5NOAWBGB$XFi)O8% zy;EWZo%H$QUZDrX={8|>$+M95-TMMsmV+4;7DjijVjv}q64`-NS#RFdG3E=K%dr1P z^7G=e2Q8R4)(M-bC0KT;98WiGU?B*u`Z=?GSYo~X#o{oVkLXakg26zjHX@Z~ zM=W79Q6BQPt=KGf>zpPeIW&WvmH`iU_ivX|^c)2|C944MyG!xWxZ%=&WNTK6GC4D9 z&PwAj27@k^hSe|we7>h}f4Mqj6z+iU8s>1Q-)D%6X%kx+PZuYQd`C7;isV<@M1>zW zQ}~StvE4H_@qpadm{{7A`r7@5PSYN+BGMl;pC1OyH2r`1$~hvR(@xnugehwCr}RO! z8MXK+K#NQd4kCkI+N7bRfwfs1aEY^+Pv6)t$S^4XBokf|vj&f0UssyEXzJHYT1Mqq zxxyHZWh{iW*D{o)=px>3VlGZG-y+VhaTQm*J%Vv_L;1mG@fo)y zmq41SG2i~9Q?UV8?2zH4xBQ)s@Ot4nXxv^1g%kZzd5kaW2ar%Zatc$r0(zux$8p#Ll|q#H%gBID z$t~k1&8vEDha1o2@$EAK_q{s->y+;BXR^aH5NJ*y=YTQp7WH<+;O!I8uvZhR)ZOE| zxk92B;CTB;?qkpNC~S&&_U%`SyE=y!B)9W$6;bmF@2@Q+Tb+$)*6xQrG%_Le(rl&z z_;(IkY+%H8sWT}Xqvx>AHWA-L`4`6(mNAQQp)7U3*!*}BTd5~3 z@4HDnp|*yOtPBtv_5UokyRZtb40t2DI;DYgXWN5JL`^~r-)7*K^N^#icb{*78@oQD z(sETSlH{+JDP3^*-ZgyDq~<0`ZxAyU6XxhM+YWv^qGK+gMSm+Umte}Samt&S(K6b9 zs-=iV2O4GQh_=bo`5yO5Ggs(&;y0?CZA1ND%W(1N&2TWbKNJhckqX~om_nA=-A5!| zxwIJ7o5!PO<1lh`{EpccOL$n3Bv}}Hrw_NRmBfD0??p+_q`4mMIyW+D9`@)mft&C! z$@i1FL(ul}WmGRq;m#F|+`zuRrf?%EmnM)geTTYREs&726#kgq!Qxq~@bj(jIQ-OL zl+QT9sY8w>yZ#*rd-!KRy@seJfzKisyus`?`ZUIpw#-!+YLkvu-#PvI4{oC)p-9UgD~cj)%oMYtTpM z2A-2iAUWd>>Y0BU>#oS7^FvisHGYXb7CuK6olO|!cM;u(&)_$eP4lu9uAt%eK9K5k z29|4G!W$ak;YX)E`-+oiWQa%U%HstKXPmrsDj6?#X1xqoVaepbVe$r) zbF=4k)Zw$v!u&~&oUk$HaT^rg=*x{kS@>i5H({s;b$i#3LKjWO;KNgK@YOR=;4_6! zH$%mhnA!ahT4-6I^1AcfDO^$k{_E74Gs6DeO`Isr6h&;z$`Dz`fn|ak)(5bCP<#`P ztrRzc**Q58k1bLquOn-qE|u`y!$iD#bSsH#9K|tCW5jr8E2r&C!V6n70fk5RbMm!K zULa1KxDZDTsDKaAN8#(?cqlz<15XAogbT-JaYN;HLu*vhO2Y9g`=H^?$&4?|LuHwN zC%hUskk6^TO;<53BbLny$C`pJq;%&wK6lE){S9wXqvH@xF!;Oyz#L4Eo;teKWTQ-#=vn9G}$zM>5@@!ZL&s&VLfr2DGBZg8+OU?M-IuTB$AX zF`b`~L8?n0z^#G7Y^5C(`^3PHKLzLr+u`1vZE*icIsd!loyBmjODor)FwqUuFP{25 zfz2VX+h95DZdi*t*H`oTGo$ujS5o2gjDu_4;9{R!ShJ@A8xKWtX32Z6o20Eg8pFzd zV1Q`=BU;0wv9hc)W-I(aI`jziT9yJSHtSH~(r>oY92Gtq5i8>XtI;KSh>VT zxG6Ih?F)XeO?E6Q;FDfw#pkXp6f3NghPxBG9?ZGGPj%r;Liz;MEP|8L^7!K>bAsi+v93T~nAO zP4JsxAvD_dLMdNeGQRwYjx5EpGx74*lTz#j>O7@G|%dcYmnpTY++8>fqubT{yoein|K2(6e1e4{e-Y zBv&xTvPb1t~F zoTJnFuH|T&?StwHYq)ai-M6#w^+Pc{9W{ha4pBwT1C3vY)0_jd#IlzL2o0P2kob!^ z{*9STYtMF2_~uJu#e!V1)?Q7{uHTpTm(x%Sl>SiGt|}TD*agnJsbim4SJ7~gX)mXk_ z@6O;TUK}u|pQFjoVgJ`qSknC!R9b(AmY_+DIKZ_PoAWX_1xHQ29}iPZ3A}A`C?r3( z#DW!?c(@>m@2E=KZjSSP%Sa`4JDzCmf>W!GqyNi!XmT(Rj-~0tH^tdJPX?bZgFnBj zaB$*m^wx3OjjWoi?ji=GQ)`lB;=7;r$W43>wQ|clbyNsaW17o4! z^LGe5G?2Pw+`|RYD;N)phk3@|y_YQm#aA?#gn|rQbMVZpwWK%Bl@3I8AWm6}Gewip z5_E_}EjGTaWK;*X1|2RXUwb{y4ywHm(@1 zyOf}r{V6;$>^Q55+zR+bq0-qrmu;R;UCA{z{gD5{;$enq8ZlqGhCnXq?ik6jO`27)WDHD zA_$&4lk2Wo6URcz^%5s~Y}P8w{P{v06*5Y!6{UtN4Gg(QO2zw?VB$59Pu8Nlw?cd6 zZnn*U&%fDDTLEkglk-W94}0hd90?i*NBz~|T)*3J+4nBAKN|_Jy7)trO8{JJc>}rK z7D4r}CCt-=%}h|wBnpQt&%%fw7I+}U7w2Z}!kIOCT=X)+q_2&=0^|6TdzTZtd_gm9iNuHAl-ovZXgTH#$yHtQl0&~ zAzm-D`PywpwPdWlGwxkElY+t3j9+wZtsnP!51+dV&P6;s%5o~OrI9H(`%P+sajJgu@vZT;i$OnC}GG{OAyJD~Vc2b@q) zhkD;L(6Czy9*j+4#A#^lc**zdew`YGc7MO&L>*Tg){u{0YsWBif7W56bG8ExLTj#S z%KWqlEmOy1<<-j=rZo_4zKC(^*+I-E9V)ycAmjOZD71OQ^T^4cyHH+vDJm#jf@&*C zrFK*XzUIEc{I1`qyUZvENz~!Y6UG6%{opV;>+Yv0(*@W(^(LIN%Ec!=(lG1h09H7V zy>2@n`La<$pKI^2>_#*`c$LYv$ni=saQry(EjxqV?RVntds8vO>=-VX)QQ7??dN-0 zjC7CSphXHeKD`6SOmq8pAZN^^K~2(wM3kK4wtWZ9)!AYfl$&rGdoJ9F-D;Pzs|rQa zW0)0%@FR4FxN*!uo;O-4)zBlmYVBfk9g8W7qtifR?zq70 z&L4MIyc9H8TjQii6uw)QS==w2m`zV}1yx5p8$ zJ8r|$LsxNoL^$?)T!+&ARzPQ9G0KY%!e6%^tS$I=Ajdz~@uqD>Wh^6Xu{s;#XK#b6 zy1P-{pcGw=cHqGCVJO$6!p5G0nT(|viv97ldM@8^aAQ#?TZhCCrTe6zC?#vm!LBJ3{Ys$Vs?a*cX`#o^T;#AY@ z@ag=PmjBA*vaw4SAG7ip`;XG+jP;aLWvG!nhFJ!pdPoBr7mq}<5=|xz)-TQ<#N4qSs^5itoIPmEnCZoN2qiKi=-%-M#niJ^OL*IlpsG604dshCTDbCN}H6JT@hD2pa@FY|x7%;jIBT zNdw}T5Z^Bl9D2PqX+?9I7Os@x!UGr||oj=Y$RU>m~dyu?3lT5yb~zD@Y05GJ6HQy&xGbwj?7# zkOb9ST?5;Xje=9}bg;S49%S1NPY(nRb+9*2TtNQ~*x33Gh41KY9?q7W*u|3n@De;f z@Ku_xVPquKPsN5+vLCw&$%H#}wGA`5L92flo461HLkDVXZQk2#-lV-ud~7}&|I(L~ zUw*(xqbW*X&Z{PVhx!GACQ|f-MMJ&bwHWHghKQ8>>9PPDSbB<$8?~8@p56+#vTm{Q zKe-;*I3*)6e(N}>YG?x2$>UVv=Ihn)fwqGp>AZGiI_z&ufOWghK;w)Q%AT{MXce>^ z{u`UbRLtK;C8wX4ul26amsVX1r%8K8{z zhj7;K|K#vgQfFh>4xDge9mw=6YdA@B9!xId+S5d4UX1aMg9&t`L2DoKvS?0p|8WfA zLCJ|Rq#*LPFw+hW-!US?D;Y7UosWSgL zrv3~W$57{n+6atJgn<rKuy1%89KBY@CO$QZ*$#9PjdiE{G#gR7g%vE>&!){Rf@`e; ztgY;UtVK^@dh&jOAi)9s`>M}s@bb8k(6XTnF3z6AhGu`rzV|bcB!BhbV)RB*R@5Y> zXQpLB?LFI((M@S9UVp*|bqNttZdD_8)%fpaoP(s(?~)P_&Bs3)R?!=on+pcnl(wDSaHe4m zB^B5$YI*=lX9D^X>HQ>O-xN!v5 z&pS^EoY5eLZ=jX?b71|Ubf|=-P_8eBic7DeI{x<&(n`%jhwMo$)D6>i=bnGBm!5Ii z=aIj@M98vFvdM0r?l)vtJO`u8ZJ_tZlBYY%ugxr z-NYLuS&VAMygFWoh^1Q8;5+dDiXRWg*IEky^SUPLrq+9alIHgd zWl`NUHU4k4u&I_Rl0$a6CBMvD)6|H#PzyU0InCj9yZnAhpfaN*77c2=c0Eav9WFn= zKfPLtH0~ygs)tP0~_iSrEQp9V8Ma~ Z3l=O`uwcQ01q*iw{{njY%!dF#0RWf+Lm~hG literal 0 HcmV?d00001 diff --git a/raster/r.sim/r.sim.water/testsuite/data/depth_default.pack b/raster/r.sim/r.sim.water/testsuite/data/depth_default.pack new file mode 100644 index 0000000000000000000000000000000000000000..579863ecca98c84a9fa757a0de79d72b5b76aafa GIT binary patch literal 25906 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≦u6EvM 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ⅆOz+Ls8Z=_1PLz6z_KzK9Ad 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 Z95`^`z<~n?4jgV0{0l^7P67Zx0RS0g#c2Ql literal 0 HcmV?d00001 diff --git a/raster/r.sim/r.sim.water/testsuite/data/discharge_complex.pack b/raster/r.sim/r.sim.water/testsuite/data/discharge_complex.pack new file mode 100644 index 0000000000000000000000000000000000000000..01810de0cb695a428f15ec647b919853a8c4d9d1 GIT binary patch literal 38375 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

|DgMIs~v0XA8ey6gz?x@?` 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 636500 && y() > 223500, 0.3, 0.01)", + ) + cls.runModule( + "r.mapcalc", + expression=f"{cls.infil} = if (x() < 636500 && y() > 223500, 0.001, 0)", + ) + cls.runModule( + "r.unpack", + input="data/depth_complex.pack", + output=cls.reference_depth_complex, + ) + cls.runModule( + "r.unpack", + input="data/discharge_complex.pack", + output=cls.reference_discharge_complex, + ) + + @classmethod + def tearDownClass(cls): + """Clean up test environment""" + cls.runModule( + "g.remove", + flags="f", + type="raster", + name=[ + cls.elevation, + cls.dx, + cls.dy, + cls.reference_depth_default, + cls.reference_discharge_default, + cls.rain, + cls.mannings, + cls.infil, + cls.reference_depth_complex, + cls.reference_discharge_complex, + ], + ) + + def tearDown(self): + """Clean up test environment""" + self.runModule( + "g.remove", + flags="f", + type="raster", + pattern=f"{self.depth}*,{self.discharge}*", + ) + + def test_default(self): + """Test r.sim.water execution with defaults""" + # Run the r.sim.water simulation + self.assertModule( + "r.sim.water", + elevation=self.elevation, + dx=self.dx, + dy=self.dy, + depth=self.depth, + discharge=self.discharge, + random_seed=1, + ) + + # Assert that the output rasters exist + self.assertRasterExists(self.depth) + self.assertRasterExists(self.discharge) + # Assert that the output rasters are the same + self.assertRastersEqual( + self.depth, reference=self.reference_depth_default, precision="0.000001" + ) + self.assertRastersEqual( + self.discharge, + reference=self.reference_discharge_default, + precision="0.000001", + ) + + def test_complex(self): + """Test r.sim.water execution with more complex inputs""" + # Run the r.sim.water simulation + self.assertModule( + "r.sim.water", + flags="t", + elevation=self.elevation, + dx=self.dx, + dy=self.dy, + rain=self.rain, + man=self.mannings, + infil=self.infil, + depth=self.depth, + discharge=self.discharge, + niterations=15, + output_step=5, + diffusion_coeff=0.9, + hmax=0.25, + halpha=3.9, + hbeta=0.6, + random_seed=1, + ) + + # Assert that the output rasters exist + self.assertRasterExists(f"{self.depth}.05") + self.assertRasterExists(f"{self.depth}.10") + self.assertRasterExists(f"{self.depth}.15") + # Assert that the output rasters are the same + self.assertRastersEqual( + f"{self.depth}.15", + reference=self.reference_depth_complex, + precision="0.000001", + ) + self.assertRastersEqual( + f"{self.discharge}.15", + reference=self.reference_discharge_complex, + precision="0.000001", + ) + + +@unittest.skip("runs too long") +class TestRSimWaterLarge(TestCase): + """Test r.sim.water with large region""" + + # Set up the necessary raster maps for testing + elevation = "elevation" + dx = "tmp_dx" + dy = "tmp_dy" + depth = "tmp_depth" + + @classmethod + def setUpClass(cls): + """Set up region, create necessary data""" + cls.runModule("g.region", raster=cls.elevation) + cls.runModule("r.slope.aspect", elevation=cls.elevation, dx=cls.dx, dy=cls.dy) + + @classmethod + def tearDownClass(cls): + """Clean up test environment""" + cls.runModule( + "g.remove", + flags="f", + type="raster", + name=[cls.elevation, cls.dx, cls.dy, cls.depth], + ) + + def test_default(self): + """Test r.sim.water execution with defaults""" + # Run the r.sim.water simulation + self.assertModule( + "r.sim.water", + elevation=self.elevation, + dx=self.dx, + dy=self.dy, + depth=self.depth, + random_seed=1, + ) + self.assertRasterFitsUnivar( + self.depth, reference="sum=30364.327529", precision=1e-6 + ) + + +if __name__ == "__main__": + from grass.gunittest.main import test + + test() From 690534d037511a8ad386ef4d67ec83fa82a90d20 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Mon, 21 Oct 2024 11:09:02 -0400 Subject: [PATCH 64/69] wxGUI: Fixed E722 in modules/ (#4546) --- .flake8 | 3 +-- gui/wxpython/modules/colorrules.py | 4 ++-- gui/wxpython/modules/histogram.py | 4 ++-- gui/wxpython/modules/import_export.py | 2 +- gui/wxpython/modules/mcalc_builder.py | 6 +++--- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.flake8 b/.flake8 index 5d2d792b0c3..3a146f34ebd 100644 --- a/.flake8 +++ b/.flake8 @@ -24,8 +24,7 @@ per-file-ignores = doc/python/m.distance.py: E501 gui/scripts/d.wms.py: E501 gui/wxpython/image2target/g.gui.image2target.py: E501 - gui/wxpython/modules/*: F841, E722 - gui/wxpython/nviz/*: E722, F403, F405 + gui/wxpython/nviz/*: E266, E722, F403, F405 gui/wxpython/photo2image/*: F841, E722, E265 gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 gui/wxpython/psmap/*: F841, E266, E722 diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index 3dfdde8c42b..6f48006db44 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -325,7 +325,7 @@ def LoadRules(self): else: value = float(self.ruleslines[item][self.attributeType]) self.mainPanel.FindWindowById(item + 2000).SetValue(value) - except: + except Exception: continue if message: @@ -407,7 +407,7 @@ def _initLayer(self): layer = sel else: layer = self.layerTree.FindItemByData(key="type", value=self.mapType) - except: + except (AttributeError, TypeError): layer = None if layer: mapLayer = self.layerTree.GetLayerInfo(layer, key="maplayer") diff --git a/gui/wxpython/modules/histogram.py b/gui/wxpython/modules/histogram.py index c8001858dff..61d41809858 100644 --- a/gui/wxpython/modules/histogram.py +++ b/gui/wxpython/modules/histogram.py @@ -258,7 +258,7 @@ def UpdateHistDone(self): return try: id = self.imagedict[self.img] - except: + except KeyError: return # paint images to PseudoDC @@ -524,7 +524,7 @@ def OnCloseWindow(self, event): """ try: self.propwin.Close(True) - except: + except Exception: pass self.Map.Clean() self.Destroy() diff --git a/gui/wxpython/modules/import_export.py b/gui/wxpython/modules/import_export.py index c3106d0467b..6810484bfdd 100644 --- a/gui/wxpython/modules/import_export.py +++ b/gui/wxpython/modules/import_export.py @@ -527,7 +527,7 @@ def OnRun(self, event): if nBandsStr: try: nBands = int(nBandsStr.rstrip("\n")) - except: + except ValueError: pass if nBands < 0: GWarning(_("Unable to determine number of raster bands"), parent=self) diff --git a/gui/wxpython/modules/mcalc_builder.py b/gui/wxpython/modules/mcalc_builder.py index b0f2f280409..52630e55820 100644 --- a/gui/wxpython/modules/mcalc_builder.py +++ b/gui/wxpython/modules/mcalc_builder.py @@ -608,7 +608,7 @@ def _addSomething(self, what): if newmcalcstr[-1] != " ": newmcalcstr += " " position_offset += 1 - except: + except IndexError: pass newmcalcstr += what @@ -617,7 +617,7 @@ def _addSomething(self, what): try: if newmcalcstr[-1] != " " and mcalcstr[position] != " ": newmcalcstr += " " - except: + except IndexError: newmcalcstr += " " newmcalcstr += mcalcstr[position:] @@ -632,7 +632,7 @@ def _addSomething(self, what): try: if newmcalcstr[position + position_offset] == " ": position_offset += 1 - except: + except IndexError: pass self.text_mcalc.SetInsertionPoint(position + position_offset) From 15134e14f181c9c042a74486132cba52ea8d90e6 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Mon, 21 Oct 2024 11:10:58 -0400 Subject: [PATCH 65/69] temporal: Fixed E265/E266 in t.rast.what/ (#4550) --- .flake8 | 3 +-- temporal/t.rast.what/t.rast.what.py | 16 ---------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/.flake8 b/.flake8 index 3a146f34ebd..90686370f67 100644 --- a/.flake8 +++ b/.flake8 @@ -114,8 +114,7 @@ per-file-ignores = scripts/*/*.py: E501 temporal/t.rast.to.vect/t.rast.to.vect.py: E501 temporal/t.vect.algebra/t.vect.algebra.py: E501 - # ## used (##% key: r etc) - temporal/t.rast.what/t.rast.what.py: E265, E266, E501 + temporal/t.rast.what/t.rast.what.py: E501 # Line too long (esp. module interface definitions) temporal/*/*.py: E501 diff --git a/temporal/t.rast.what/t.rast.what.py b/temporal/t.rast.what/t.rast.what.py index 4d13c6a924c..24190a6a716 100755 --- a/temporal/t.rast.what/t.rast.what.py +++ b/temporal/t.rast.what/t.rast.what.py @@ -98,22 +98,6 @@ # % description: Use stdin as input and ignore coordinates and point option # %end -## Temporary disabled the r.what flags due to test issues -##%flag -##% key: f -##% description: Show the category labels of the grid cell(s) -##%end - -##%flag -##% key: r -##% description: Output color values as RRR:GGG:BBB -##%end - -##%flag -##% key: i -##% description: Output integer category values, not cell values -##%end - # %flag # % key: v # % description: Show the category for vector points map From a4786e1272e741865c2c42371056c718e8388ea3 Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Mon, 21 Oct 2024 15:29:22 -0400 Subject: [PATCH 66/69] wxGUI: Fixed F405 in nviz/ (#4567) --- .flake8 | 2 +- gui/wxpython/nviz/wxnviz.py | 197 ++++++++++++++++++++++++++++++++++-- 2 files changed, 188 insertions(+), 11 deletions(-) diff --git a/.flake8 b/.flake8 index 90686370f67..8211d9e03d4 100644 --- a/.flake8 +++ b/.flake8 @@ -24,7 +24,7 @@ per-file-ignores = doc/python/m.distance.py: E501 gui/scripts/d.wms.py: E501 gui/wxpython/image2target/g.gui.image2target.py: E501 - gui/wxpython/nviz/*: E266, E722, F403, F405 + gui/wxpython/nviz/*: E722 gui/wxpython/photo2image/*: F841, E722, E265 gui/wxpython/photo2image/g.gui.photo2image.py: E501, F841 gui/wxpython/psmap/*: F841, E266, E722 diff --git a/gui/wxpython/nviz/wxnviz.py b/gui/wxpython/nviz/wxnviz.py index 47cf99c079d..5a223747277 100644 --- a/gui/wxpython/nviz/wxnviz.py +++ b/gui/wxpython/nviz/wxnviz.py @@ -22,9 +22,9 @@ @author Anna Kratochvilova (Google SoC 2011) """ -import sys import locale import struct +import sys from math import sqrt try: @@ -42,26 +42,203 @@ import wx try: - from ctypes import * + from ctypes import ( + CFUNCTYPE, + UNCHECKED, + byref, + c_char_p, + c_double, + c_float, + c_int, + c_ubyte, + create_string_buffer, + pointer, + ) except KeyError as e: print("wxnviz.py: {}".format(e), file=sys.stderr) try: - from grass.lib.gis import * - from grass.lib.raster3d import * - from grass.lib.vector import * - from grass.lib.ogsf import * - from grass.lib.nviz import * - from grass.lib.raster import * + from grass.lib.gis import ( + G_find_raster2, + G_find_raster3d, + G_find_vector2, + G_free, + G_fully_qualified_name, + G_gisinit, + G_set_error_routine, + G_set_percent_routine, + G_unset_error_routine, + G_unset_percent_routine, + G_unset_window, + G_warning, + ) + from grass.lib.nviz import ( + ATT_COLOR, + ATT_EMIT, + ATT_MASK, + ATT_SHINE, + ATT_TOPO, + ATT_TRANSP, + CONST_ATT, + MAP_ATT, + MAP_OBJ_SITE, + MAP_OBJ_SURF, + MAP_OBJ_UNDEFINED, + MAP_OBJ_VECT, + MAP_OBJ_VOL, + Colors, + Nviz_change_exag, + Nviz_color_from_str, + Nviz_del_texture, + Nviz_delete_arrow, + Nviz_delete_scalebar, + Nviz_draw_all, + Nviz_draw_arrow, + Nviz_draw_cplane, + Nviz_draw_fringe, + Nviz_draw_image, + Nviz_draw_model, + Nviz_draw_quick, + Nviz_draw_scalebar, + Nviz_flythrough, + Nviz_get_bgcolor, + Nviz_get_cplane_rotation, + Nviz_get_cplane_translation, + Nviz_get_current_cplane, + Nviz_get_exag, + Nviz_get_exag_height, + Nviz_get_focus, + Nviz_get_longdim, + Nviz_get_max_texture, + Nviz_get_modelview, + Nviz_get_viewpoint_height, + Nviz_get_viewpoint_position, + Nviz_get_xyrange, + Nviz_get_zrange, + Nviz_has_focus, + Nviz_init_data, + Nviz_init_rotation, + Nviz_init_view, + Nviz_load_image, + Nviz_look_here, + Nviz_new_map_obj, + Nviz_num_cplanes, + Nviz_off_cplane, + Nviz_on_cplane, + Nviz_resize_window, + Nviz_set_2D, + Nviz_set_arrow, + Nviz_set_attr, + Nviz_set_bgcolor, + Nviz_set_cplane_here, + Nviz_set_cplane_rotation, + Nviz_set_cplane_translation, + Nviz_set_fence_color, + Nviz_set_focus, + Nviz_set_focus_map, + Nviz_set_fringe, + Nviz_set_light_ambient, + Nviz_set_light_bright, + Nviz_set_light_color, + Nviz_set_light_position, + Nviz_set_rotation, + Nviz_set_scalebar, + Nviz_set_surface_attr_default, + Nviz_set_viewpoint_height, + Nviz_set_viewpoint_persp, + Nviz_set_viewpoint_position, + Nviz_set_viewpoint_twist, + Nviz_unset_attr, + Nviz_unset_rotation, + nv_data, + ) + from grass.lib.ogsf import ( + GS_clear, + GS_delete_surface, + GS_get_cat_at_xy, + GS_get_distance_alongsurf, + GS_get_rotation_matrix, + GS_get_selected_point_on_surface, + GS_get_surf_list, + GS_get_trans, + GS_get_val_at_xy, + GS_get_viewdir, + GS_libinit, + GS_num_surfs, + GS_set_att_const, + GS_set_drawmode, + GS_set_drawres, + GS_set_rotation_matrix, + GS_set_trans, + GS_set_viewdir, + GS_set_wire_color, + GS_setall_drawmode, + GS_setall_drawres, + GS_surf_exists, + GS_write_ppm, + GS_write_tif, + GVL_delete_vol, + GVL_get_trans, + GVL_init_region, + GVL_isosurf_add, + GVL_isosurf_del, + GVL_isosurf_move_down, + GVL_isosurf_move_up, + GVL_isosurf_num_isosurfs, + GVL_isosurf_set_att_const, + GVL_isosurf_set_att_map, + GVL_isosurf_set_drawmode, + GVL_isosurf_set_drawres, + GVL_isosurf_set_flags, + GVL_isosurf_unset_att, + GVL_libinit, + GVL_set_draw_wire, + GVL_set_trans, + GVL_slice_add, + GVL_slice_del, + GVL_slice_move_down, + GVL_slice_move_up, + GVL_slice_num_slices, + GVL_slice_set_drawmode, + GVL_slice_set_drawres, + GVL_slice_set_pos, + GVL_slice_set_transp, + GVL_vol_exists, + ) + from grass.lib.raster import Rast__init_window, Rast_unset_window, Vect_read_colors + from grass.lib.raster3d import ( + GP_delete_site, + GP_get_sitename, + GP_select_surf, + GP_set_style, + GP_set_style_thematic, + GP_set_trans, + GP_set_zmode, + GP_site_exists, + GP_unselect_surf, + GP_unset_style_thematic, + ) + from grass.lib.vector import ( + GV_delete_vector, + GV_get_vectname, + GV_select_surf, + GV_set_style, + GV_set_style_thematic, + GV_set_trans, + GV_surf_is_selected, + GV_unselect_surf, + GV_unset_style_thematic, + GV_vect_exists, + ) except (ImportError, OSError, TypeError) as e: print("wxnviz.py: {}".format(e), file=sys.stderr) +import grass.script as gs from core.debug import Debug -from core.utils import autoCropImageFromFile from core.gcmd import DecodeString from core.globalvar import wxPythonPhoenix +from core.utils import autoCropImageFromFile from gui_core.wrap import Rect -import grass.script as gs log = None progress = None From 9d699d57ce29f16865e734ca8ee6c0454add9244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bartoletti?= Date: Mon, 21 Oct 2024 21:44:58 +0200 Subject: [PATCH 67/69] r3.showdspf: fix a typo: case 3 instead of case3 (#3867) --- raster3d/r3.showdspf/main_ogl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raster3d/r3.showdspf/main_ogl.c b/raster3d/r3.showdspf/main_ogl.c index 55b3097e2cf..da6e90a3721 100644 --- a/raster3d/r3.showdspf/main_ogl.c +++ b/raster3d/r3.showdspf/main_ogl.c @@ -1159,7 +1159,7 @@ void do__draw(file_info *Headp, struct dspec *D_spec) fdraw_polys(D_spec); break; case 2: - case3: + case 3: gdraw_polys(D_spec); break; } From 67a160931aa01d29a896def827d5dd687e08bfd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:07:17 -0400 Subject: [PATCH 68/69] style: Fix if-else-block-instead-of-if-exp (SIM108) (part 2) (#4562) * style: Fix if-else-block-instead-of-if-exp (SIM108) in scripts/ Ruff rule: https://docs.astral.sh/ruff/rules/if-else-block-instead-of-if-exp * style: Fix if-else-block-instead-of-if-exp (SIM108) in python/ Ruff rule: https://docs.astral.sh/ruff/rules/if-else-block-instead-of-if-exp * checks: Rename inner variable shadowing type to _type in python/grass/temporal/gui_support.py * style: Manual fixes for if-else-block-instead-of-if-exp (SIM108) in python/ Ruff rule: https://docs.astral.sh/ruff/rules/if-else-block-instead-of-if-exp --- python/grass/app/runtime.py | 10 +---- python/grass/benchmark/app.py | 6 +-- python/grass/benchmark/plots.py | 10 +---- python/grass/exceptions/__init__.py | 10 ++--- python/grass/gunittest/case.py | 14 ++----- python/grass/gunittest/invoker.py | 5 +-- python/grass/gunittest/multireport.py | 5 +-- python/grass/gunittest/reporters.py | 22 +++-------- python/grass/jupyter/map3d.py | 5 +-- python/grass/pydispatch/signal.py | 7 +--- .../pygrass/modules/interface/parameter.py | 5 +-- python/grass/pygrass/vector/__init__.py | 5 +-- python/grass/pygrass/vector/geometry.py | 5 +-- python/grass/pygrass/vector/table.py | 5 +-- python/grass/script/core.py | 15 ++------ python/grass/script/raster.py | 5 +-- python/grass/script/task.py | 10 +---- .../data/script_using_temporary_region.py | 10 +---- python/grass/script/utils.py | 20 ++-------- python/grass/script/vector.py | 10 +---- python/grass/temporal/abstract_map_dataset.py | 5 +-- .../temporal/abstract_space_time_dataset.py | 10 +---- .../grass/temporal/c_libraries_interface.py | 11 +----- python/grass/temporal/datetime_math.py | 15 ++------ python/grass/temporal/gui_support.py | 23 ++++++------ python/grass/temporal/list_stds.py | 5 +-- python/grass/temporal/register.py | 10 +---- python/grass/temporal/sampling.py | 17 ++------- python/grass/temporal/temporal_algebra.py | 37 ++++--------------- python/grass/temporal/temporal_granularity.py | 9 ++--- .../temporal/temporal_raster_base_algebra.py | 5 +-- python/grass/temporal/univar_statistics.py | 5 +-- scripts/d.rast.edit/d.rast.edit.py | 5 +-- scripts/d.rast.leg/d.rast.leg.py | 10 +---- scripts/db.droptable/db.droptable.py | 10 +---- scripts/db.out.ogr/db.out.ogr.py | 5 +-- scripts/db.univar/db.univar.py | 5 +-- scripts/g.extension/g.extension.py | 15 ++------ scripts/g.manual/g.manual.py | 5 +-- scripts/i.in.spotvgt/i.in.spotvgt.py | 6 +-- scripts/i.oif/i.oif.py | 10 +---- scripts/i.spectral/i.spectral.py | 5 +-- scripts/m.proj/m.proj.py | 10 +---- scripts/r.buffer.lowmem/r.buffer.lowmem.py | 5 +-- scripts/r.in.aster/r.in.aster.py | 5 +-- scripts/r.in.srtm/r.in.srtm.py | 5 +-- scripts/r.in.wms/wms_cap_parsers.py | 10 +---- scripts/r.in.wms/wms_drv.py | 5 +-- scripts/r.out.xyz/r.out.xyz.py | 5 +-- scripts/r.reclass.area/r.reclass.area.py | 5 +-- scripts/r.unpack/r.unpack.py | 5 +-- scripts/r3.in.xyz/r3.in.xyz.py | 10 +---- scripts/v.build.all/v.build.all.py | 5 +-- .../v.db.reconnect.all/v.db.reconnect.all.py | 5 +-- scripts/v.dissolve/tests/conftest.py | 5 +-- .../tests/v_dissolve_aggregate_test.py | 10 +---- .../tests/v_dissolve_layers_test.py | 5 +-- scripts/v.in.e00/v.in.e00.py | 5 +-- scripts/v.in.lines/v.in.lines.py | 7 +--- scripts/v.in.mapgen/v.in.mapgen.py | 10 +---- scripts/v.pack/v.pack.py | 5 +-- scripts/v.rast.stats/v.rast.stats.py | 15 ++------ scripts/v.report/v.report.py | 5 +-- scripts/v.unpack/v.unpack.py | 15 ++------ 64 files changed, 124 insertions(+), 445 deletions(-) diff --git a/python/grass/app/runtime.py b/python/grass/app/runtime.py index 3f3805c9dfd..27f35760b8f 100644 --- a/python/grass/app/runtime.py +++ b/python/grass/app/runtime.py @@ -79,10 +79,7 @@ def append_left_addon_paths(paths, config_dir, env): # addons (base) addon_base = env.get("GRASS_ADDON_BASE") if not addon_base: - if MACOS: - name = "Addons" - else: - name = "addons" + name = "addons" if not MACOS else "Addons" addon_base = os.path.join(config_dir, name) env["GRASS_ADDON_BASE"] = addon_base @@ -174,10 +171,7 @@ def set_python_path_variable(install_path, env): """Set PYTHONPATH to find GRASS Python package in subprocesses""" path = env.get("PYTHONPATH") etcpy = os.path.join(install_path, "etc", "python") - if path: - path = etcpy + os.pathsep + path - else: - path = etcpy + path = etcpy + os.pathsep + path if path else etcpy env["PYTHONPATH"] = path diff --git a/python/grass/benchmark/app.py b/python/grass/benchmark/app.py index 09cdf3f9481..835fc0d544b 100644 --- a/python/grass/benchmark/app.py +++ b/python/grass/benchmark/app.py @@ -47,11 +47,7 @@ def join_results_cli(args): def select_only(result): return result.label == args.only - if args.only: - select_function = select_only - else: - select_function = None - + select_function = select_only if args.only else None results = join_results_from_files( source_filenames=args.results, prefixes=args.prefixes, diff --git a/python/grass/benchmark/plots.py b/python/grass/benchmark/plots.py index 9483fda9116..24afcbcfbae 100644 --- a/python/grass/benchmark/plots.py +++ b/python/grass/benchmark/plots.py @@ -25,10 +25,7 @@ def get_pyplot(to_file): """ import matplotlib as mpl # pylint: disable=import-outside-toplevel - if to_file: - backend = "agg" - else: - backend = None + backend = "agg" if to_file else None if backend: mpl.use(backend) @@ -124,10 +121,7 @@ def num_cells_plot(results, filename=None, title=None, show_resolution=False): x_ticks = set() for result in results: - if show_resolution: - x = result.resolutions - else: - x = result.cells + x = result.resolutions if show_resolution else result.cells x_ticks.update(x) plt.plot(x, result.times, label=result.label) if hasattr(result, "all_times"): diff --git a/python/grass/exceptions/__init__.py b/python/grass/exceptions/__init__.py index b22d0a45c1d..deec48ffd96 100644 --- a/python/grass/exceptions/__init__.py +++ b/python/grass/exceptions/__init__.py @@ -71,13 +71,9 @@ def __init__(self, module, code, returncode, errors=None): """ # CalledProcessError has undocumented constructor super().__init__(returncode, module) - if not module or module in code: - # No need to include module name if it is directly in code - # of if it is not set. - executed = code - else: - # Make sure module name is there if provided and not in code. - executed = f"{module} {code}" + # No need to include module name if it is directly in code of if it is not set. + # Otherwise, make sure module name is there if provided and not in code. + executed = code if not module or module in code else f"{module} {code}" if errors: # We assume actual errors, e.g., captured stderr. err = _("See the following errors:\n{errors}").format(errors=errors) diff --git a/python/grass/gunittest/case.py b/python/grass/gunittest/case.py index 1277ee542b5..4e0ee3ab24d 100644 --- a/python/grass/gunittest/case.py +++ b/python/grass/gunittest/case.py @@ -691,10 +691,7 @@ def assertFileMd5(self, filename, md5, text=False, msg=None): at the end of file (as for example, Git or PEP8 requires). """ self.assertFileExists(filename, msg=msg) - if text: - actual = text_file_md5(filename) - else: - actual = file_md5(filename) + actual = text_file_md5(filename) if text else file_md5(filename) if actual != md5: standardMsg = ( "File <{name}> does not have the right MD5 sum.\n" @@ -1339,12 +1336,9 @@ def runModule(cls, module, expecting_stdout=False, **kwargs): errors = " The errors are:\n" + module.outputs.stderr else: errors = " There were no error messages." - if module.outputs.stdout: - # this is not appropriate for translation but we don't want - # and don't need testing to be translated - got = "only whitespace." - else: - got = "nothing." + # This is not appropriate for translation but we don't want + # and don't need testing to be translated + got = "only whitespace." if module.outputs.stdout else "nothing." raise RuntimeError( "Module call " + module.get_python() diff --git a/python/grass/gunittest/invoker.py b/python/grass/gunittest/invoker.py index 2fe9c898b8b..29b62830e25 100644 --- a/python/grass/gunittest/invoker.py +++ b/python/grass/gunittest/invoker.py @@ -54,10 +54,7 @@ def update_keyval_file(filename, module, returncode): keyval["name"] = module.name keyval["tested_dir"] = module.tested_dir if "status" not in keyval.keys(): - if returncode is None or returncode: - status = "failed" - else: - status = "passed" + status = "failed" if returncode is None or returncode else "passed" keyval["status"] = status keyval["returncode"] = returncode keyval["test_file_authors"] = test_file_authors diff --git a/python/grass/gunittest/multireport.py b/python/grass/gunittest/multireport.py index c5f36a6e0db..5a0350f1786 100644 --- a/python/grass/gunittest/multireport.py +++ b/python/grass/gunittest/multireport.py @@ -119,10 +119,7 @@ def median(values): smedian = median(successes) smax = max(successes) - if successes[-1] < smedian: - color = "r" - else: - color = "g" + color = "r" if successes[-1] < smedian else "g" # another possibility is to color according to the gradient, ideally # on the whole curve but that's much more complicated diff --git a/python/grass/gunittest/reporters.py b/python/grass/gunittest/reporters.py index 09f371dfffc..57b0a8fc643 100644 --- a/python/grass/gunittest/reporters.py +++ b/python/grass/gunittest/reporters.py @@ -234,11 +234,8 @@ def get_svn_path_authors(path, from_date=None): :returns: a set of authors """ - if from_date is None: - # this is the SVN default for local copies - revision_range = "BASE:1" - else: - revision_range = "BASE:{%s}" % from_date + # "BASE:1" is the SVN default for local copies + revision_range = "BASE:1" if from_date is None else "BASE:{%s}" % from_date try: # TODO: allow also usage of --limit p = subprocess.Popen( @@ -487,10 +484,7 @@ def tail(filename, n): def returncode_to_html_text(returncode, timed_out=None): if returncode: - if timed_out is not None: - extra = f" (timeout >{timed_out}s)" - else: - extra = "" + extra = f" (timeout >{timed_out}s)" if timed_out is not None else "" return f'FAILED{extra}' # alternatives: SUCCEEDED, passed, OK return 'succeeded' @@ -857,10 +851,7 @@ def finish(self): # this shoul be moved to some additional meta passed in constructor svn_info = get_svn_info() - if not svn_info: - svn_revision = "" - else: - svn_revision = svn_info["revision"] + svn_revision = "" if not svn_info else svn_info["revision"] summary = {} summary["files_total"] = self.test_files @@ -1025,10 +1016,7 @@ def end_file_test( num_failed = test_summary.get("failures", 0) num_failed += test_summary.get("errors", 0) if num_failed: - if num_failed > 1: - text = " ({f} tests failed)" - else: - text = " ({f} test failed)" + text = " ({f} tests failed)" if num_failed > 1 else " ({f} test failed)" self._stream.write(text.format(f=num_failed)) self._stream.write("\n") # TODO: here we lost the possibility to include also file name diff --git a/python/grass/jupyter/map3d.py b/python/grass/jupyter/map3d.py index dd373f315a7..99253251406 100644 --- a/python/grass/jupyter/map3d.py +++ b/python/grass/jupyter/map3d.py @@ -210,10 +210,7 @@ def render(self, **kwargs): with Display( size=(self._width, self._height), **additional_kwargs ) as display: - if has_env_copy: - env = display.env() - else: - env = os.environ.copy() + env = display.env() if has_env_copy else os.environ.copy() self._region_manager.set_region_from_command(env=env, **kwargs) self.overlay.region_manager.set_region_from_env(env) gs.run_command(module, env=env, **kwargs) diff --git a/python/grass/pydispatch/signal.py b/python/grass/pydispatch/signal.py index 1e968e99dca..51808e01ee3 100644 --- a/python/grass/pydispatch/signal.py +++ b/python/grass/pydispatch/signal.py @@ -7,7 +7,7 @@ from grass.pydispatch import dispatcher -def _islambda(function): +def _islambda(function) -> bool: """ Tests if object is a lambda function. @@ -146,10 +146,7 @@ class connects to the signal:: will print """ if weak is None: - if _islambda(handler): - weak = False - else: - weak = True + weak = not _islambda(handler) dispatcher.connect(receiver=handler, signal=self, weak=weak) def disconnect(self, handler, weak=True): diff --git a/python/grass/pygrass/modules/interface/parameter.py b/python/grass/pygrass/modules/interface/parameter.py index 3b58ea2b372..1ec5466bc74 100644 --- a/python/grass/pygrass/modules/interface/parameter.py +++ b/python/grass/pygrass/modules/interface/parameter.py @@ -337,10 +337,7 @@ def __doc__(self): .. """ if hasattr(self, "values"): - if self.isrange: - vals = self.isrange - else: - vals = ", ".join([repr(val) for val in self.values]) + vals = self.isrange or ", ".join([repr(val) for val in self.values]) else: vals = False if self.keydescvalues: diff --git a/python/grass/pygrass/vector/__init__.py b/python/grass/pygrass/vector/__init__.py index 461050807b0..6723b2e44b3 100644 --- a/python/grass/pygrass/vector/__init__.py +++ b/python/grass/pygrass/vector/__init__.py @@ -859,10 +859,7 @@ def features_to_wkb_list(self, bbox=None, feature_type="point", field=1): ok = libvect.Vect_cat_get( ctypes.byref(line_c), field, ctypes.byref(cat) ) - if ok < 1: - pcat = None - else: - pcat = cat.value + pcat = None if ok < 1 else cat.value wkb_list.append((f_id, pcat, ctypes.string_at(barray, size.value))) libgis.G_free(barray) diff --git a/python/grass/pygrass/vector/geometry.py b/python/grass/pygrass/vector/geometry.py index 10ecb1d2d13..b734161d1ea 100644 --- a/python/grass/pygrass/vector/geometry.py +++ b/python/grass/pygrass/vector/geometry.py @@ -810,10 +810,7 @@ def extend(self, line, forward=True): """ # set direction - if forward: - direction = libvect.GV_FORWARD - else: - direction = libvect.GV_BACKWARD + direction = libvect.GV_FORWARD if forward else libvect.GV_BACKWARD # check if is a Line object if isinstance(line, Line): c_points = line.c_points diff --git a/python/grass/pygrass/vector/table.py b/python/grass/pygrass/vector/table.py index 9c8d0c3f9a2..5442d2f1e51 100644 --- a/python/grass/pygrass/vector/table.py +++ b/python/grass/pygrass/vector/table.py @@ -1261,10 +1261,7 @@ def create(self, cols, name=None, overwrite=False, cursor=None): """ cur = cursor or self.conn.cursor() coldef = ",\n".join(["%s %s" % col for col in cols]) - if name: - newname = name - else: - newname = self.name + newname = name or self.name try: cur.execute(sql.CREATE_TAB.format(tname=newname, coldef=coldef)) self.conn.commit() diff --git a/python/grass/script/core.py b/python/grass/script/core.py index 4f70f525133..0b51e7fdbe9 100644 --- a/python/grass/script/core.py +++ b/python/grass/script/core.py @@ -334,10 +334,7 @@ def get_module_and_code(args, kwargs): args = make_command(*args, **kwargs) # Since we are in error handler, let's be extra cautious # about an empty command. - if args: - module = args[0] - else: - module = None + module = args[0] if args else None code = " ".join(args) return module, code @@ -1699,10 +1696,7 @@ def mapsets(search_path=False, env=None): :return: list of mapsets """ - if search_path: - flags = "p" - else: - flags = "l" + flags = "p" if search_path else "l" mapsets = read_command("g.mapsets", flags=flags, sep="newline", quiet=True, env=env) if not mapsets: fatal(_("Unable to list mapsets")) @@ -2033,10 +2027,7 @@ def create_environment(gisdbase, location, mapset, env=None): f.write("GISDBASE: {g}\n".format(g=gisdbase)) f.write("LOCATION_NAME: {l}\n".format(l=location)) f.write("GUI: text\n") - if env: - env = env.copy() - else: - env = os.environ.copy() + env = env.copy() if env else os.environ.copy() env["GISRC"] = f.name # remove mapset-specific env vars env = sanitize_mapset_environment(env) diff --git a/python/grass/script/raster.py b/python/grass/script/raster.py index 54c1219dbaf..d82780d7c5c 100644 --- a/python/grass/script/raster.py +++ b/python/grass/script/raster.py @@ -218,10 +218,7 @@ def raster_what(map, coord, env=None, localized=False): query :param env: """ - if isinstance(map, (bytes, str)): - map_list = [map] - else: - map_list = map + map_list = [map] if isinstance(map, (bytes, str)) else map coord_list = [] if isinstance(coord, tuple): diff --git a/python/grass/script/task.py b/python/grass/script/task.py index cf398c59214..9867b3d8c49 100644 --- a/python/grass/script/task.py +++ b/python/grass/script/task.py @@ -345,14 +345,8 @@ def _process_params(self): for ki in node_key_desc.findall("item"): key_desc.append(ki.text) - if p.get("multiple", "no") == "yes": - multiple = True - else: - multiple = False - if p.get("required", "no") == "yes": - required = True - else: - required = False + multiple = p.get("multiple", "no") == "yes" + required = p.get("required", "no") == "yes" if ( self.task.blackList["enabled"] diff --git a/python/grass/script/testsuite/data/script_using_temporary_region.py b/python/grass/script/testsuite/data/script_using_temporary_region.py index 5bb5a4cda26..839bf3d0a72 100755 --- a/python/grass/script/testsuite/data/script_using_temporary_region.py +++ b/python/grass/script/testsuite/data/script_using_temporary_region.py @@ -65,15 +65,9 @@ def main(): argument = sys.argv[1] sizes = argument.split(",", 1) size = sizes[0] - if len(sizes) > 1: - remaining = sizes[1] - else: - remaining = None + remaining = sizes[1] if len(sizes) > 1 else None nesting = int(sys.argv[2]) - if len(sys.argv) == 4: - map_name = sys.argv[3] - else: - map_name = None + map_name = sys.argv[3] if len(sys.argv) == 4 else None call_use_temp_region( script=this_file, size=size, diff --git a/python/grass/script/utils.py b/python/grass/script/utils.py index 448289b57aa..25eb70190c5 100644 --- a/python/grass/script/utils.py +++ b/python/grass/script/utils.py @@ -190,10 +190,7 @@ def decode(bytes_, encoding=None): if isinstance(bytes_, str): return bytes_ if isinstance(bytes_, bytes): - if encoding is None: - enc = _get_encoding() - else: - enc = encoding + enc = _get_encoding() if encoding is None else encoding return bytes_.decode(enc) # only text should be used raise TypeError("can only accept types str and bytes") @@ -221,10 +218,7 @@ def encode(string, encoding=None): if isinstance(string, bytes): return string if isinstance(string, str): - if encoding is None: - enc = _get_encoding() - else: - enc = encoding + enc = _get_encoding() if encoding is None else encoding return string.encode(enc) # if something else than text raise TypeError("can only accept types str and bytes") @@ -276,10 +270,7 @@ def parse_key_val(s, sep="=", dflt=None, val_type=None, vsep=None): for line in lines: kv = line.split(sep, 1) k = decode(kv[0].strip()) - if len(kv) > 1: - v = decode(kv[1].strip()) - else: - v = dflt + v = decode(kv[1].strip()) if len(kv) > 1 else dflt if val_type: result[k] = val_type(v) @@ -353,10 +344,7 @@ def convert(text): return int(text) if text.isdigit() else text.lower() def alphanum_key(actual_key): - if key: - sort_key = key(actual_key) - else: - sort_key = actual_key + sort_key = key(actual_key) if key else actual_key return [convert(c) for c in re.split("([0-9]+)", sort_key)] items.sort(key=alphanum_key) diff --git a/python/grass/script/vector.py b/python/grass/script/vector.py index ca3caf18471..2d484f7d590 100644 --- a/python/grass/script/vector.py +++ b/python/grass/script/vector.py @@ -129,10 +129,7 @@ def vector_columns(map, layer=None, getDict=True, env=None, **kwargs): s = read_command( "v.info", flags="c", map=map, layer=layer, quiet=True, env=env, **kwargs ) - if getDict: - result = {} - else: - result = [] + result = {} if getDict else [] i = 0 for line in s.splitlines(): ctype, cname = line.split("|") @@ -377,10 +374,7 @@ def vector_what( if "LC_ALL" in env: env["LC_ALL"] = "C" - if isinstance(map, (bytes, str)): - map_list = [map] - else: - map_list = map + map_list = [map] if isinstance(map, (bytes, str)) else map if layer: if isinstance(layer, (tuple, list)): diff --git a/python/grass/temporal/abstract_map_dataset.py b/python/grass/temporal/abstract_map_dataset.py index ecbf761d139..f6bec2bfef3 100644 --- a/python/grass/temporal/abstract_map_dataset.py +++ b/python/grass/temporal/abstract_map_dataset.py @@ -820,10 +820,7 @@ def temporal_buffer(self, increment, update=False, dbif=None): else: start, end, unit = self.get_relative_time() new_start = start - increment - if end is None: - new_end = start + increment - else: - new_end = end + increment + new_end = start + increment if end is None else end + increment if update: self.update_relative_time(new_start, new_end, unit, dbif=dbif) diff --git a/python/grass/temporal/abstract_space_time_dataset.py b/python/grass/temporal/abstract_space_time_dataset.py index d17baaab6ae..8140a2da261 100644 --- a/python/grass/temporal/abstract_space_time_dataset.py +++ b/python/grass/temporal/abstract_space_time_dataset.py @@ -779,10 +779,7 @@ def sample_by_dataset(self, stds, method=None, spatial=False, dbif=None): # print(relations) tb = SpatioTemporalTopologyBuilder() - if spatial: - spatial = "2D" - else: - spatial = None + spatial = "2D" if spatial else None mapsA = self.get_registered_maps_as_objects(dbif=dbif) mapsB = stds.get_registered_maps_as_objects_with_gaps(dbif=dbif) @@ -1429,10 +1426,7 @@ def get_registered_maps_as_objects_with_gaps( start1, end1 = maps[i].get_temporal_extent_as_tuple() start2, end2 = maps[i + 1].get_temporal_extent_as_tuple() end = start2 - if end1 is not None: - start = end1 - else: - start = start1 + start = end1 if end1 is not None else start1 map = self.get_new_map_instance(None) diff --git a/python/grass/temporal/c_libraries_interface.py b/python/grass/temporal/c_libraries_interface.py index 85a19a3ec6e..0d24fc0f732 100644 --- a/python/grass/temporal/c_libraries_interface.py +++ b/python/grass/temporal/c_libraries_interface.py @@ -256,11 +256,7 @@ def _get_driver_name(lock, conn, data): :returns: Name of the driver or None if no temporal database present """ mapset = data[1] - if not mapset: - mapset = libgis.G_mapset() - else: - mapset = encode(mapset) - + mapset = libgis.G_mapset() if not mapset else encode(mapset) drstring = libtgis.tgis_get_mapset_driver_name(mapset) conn.send(decode(drstring.data)) @@ -280,10 +276,7 @@ def _get_database_name(lock, conn, data): dbstring = None try: mapset = data[1] - if not mapset: - mapset = libgis.G_mapset() - else: - mapset = encode(mapset) + mapset = libgis.G_mapset() if not mapset else encode(mapset) dbstring = libtgis.tgis_get_mapset_database_name(mapset) dbstring = dbstring.data diff --git a/python/grass/temporal/datetime_math.py b/python/grass/temporal/datetime_math.py index 1031582fe23..b986637162a 100644 --- a/python/grass/temporal/datetime_math.py +++ b/python/grass/temporal/datetime_math.py @@ -694,10 +694,7 @@ def compute_datetime_delta(start, end): else: d += 24 * 60 * day_diff elif d == 0: - if comp["hour"]: - d = 60 * comp["hour"] - else: - d = 24 * 60 * day_diff + d = 60 * comp["hour"] if comp["hour"] else 24 * 60 * day_diff comp["minute"] = d @@ -914,10 +911,7 @@ def datetime_to_grass_datetime_string(dt): # Check for time zone info in the datetime object if dt.tzinfo is not None: tz = dt.tzinfo.utcoffset(0) - if tz.seconds > 86400 / 2: - tz = (tz.seconds - 86400) / 60 - else: - tz = tz.seconds / 60 + tz = (tz.seconds - 86400) / 60 if tz.seconds > 86400 / 2 else tz.seconds / 60 string = "%.2i %s %.2i %.2i:%.2i:%.2i %+.4i" % ( dt.day, @@ -999,10 +993,7 @@ def create_numeric_suffix(base, count, zeros): if len(spli) == 2: suff = spli[1] if suff.isdigit(): - if int(suff[0]) == 0: - zero = suff - else: - zero = "0{nu}".format(nu=suff) + zero = suff if int(suff[0]) == 0 else "0{nu}".format(nu=suff) else: zero = "05" else: diff --git a/python/grass/temporal/gui_support.py b/python/grass/temporal/gui_support.py index 41f22edc6b7..d2cbca13d68 100644 --- a/python/grass/temporal/gui_support.py +++ b/python/grass/temporal/gui_support.py @@ -37,16 +37,14 @@ def tlist_grouped(type, group_type=False, dbif=None): :return: directory of mapsets/elements """ result = {} + _type = type dbif, connection_state_changed = init_dbif(dbif) mapset = None - if type == "stds": - types = ["strds", "str3ds", "stvds"] - else: - types = [type] - for type in types: + types = ["strds", "str3ds", "stvds"] if _type == "stds" else [_type] + for _type in types: try: - tlist_result = tlist(type=type, dbif=dbif) + tlist_result = tlist(type=_type, dbif=dbif) except gs.ScriptError as e: gs.warning(e) continue @@ -65,10 +63,10 @@ def tlist_grouped(type, group_type=False, dbif=None): result[mapset] = [] if group_type: - if type in result[mapset]: - result[mapset][type].append(name) + if _type in result[mapset]: + result[mapset][_type].append(name) else: - result[mapset][type] = [ + result[mapset][_type] = [ name, ] else: @@ -90,19 +88,20 @@ def tlist(type, dbif=None): :return: a list of space time dataset ids """ + _type = type id = None - sp = dataset_factory(type, id) + sp = dataset_factory(_type, id) dbif, connection_state_changed = init_dbif(dbif) mapsets = get_available_temporal_mapsets() output = [] temporal_type = ["absolute", "relative"] - for type in temporal_type: + for _type in temporal_type: # For each available mapset for mapset in mapsets.keys(): # Table name - if type == "absolute": + if _type == "absolute": table = sp.get_type() + "_view_abs_time" else: table = sp.get_type() + "_view_rel_time" diff --git a/python/grass/temporal/list_stds.py b/python/grass/temporal/list_stds.py index 9f6b6867766..22a2708123d 100644 --- a/python/grass/temporal/list_stds.py +++ b/python/grass/temporal/list_stds.py @@ -325,10 +325,7 @@ def _get_get_registered_maps_as_objects_delta_gran( msgr.fatal(_("Empty entry in map list, this should not happen")) start, end = map_object.get_temporal_extent_as_tuple() - if end: - delta = end - start - else: - delta = None + delta = end - start if end else None delta_first = start - first_time if map_object.is_time_absolute(): diff --git a/python/grass/temporal/register.py b/python/grass/temporal/register.py index 92be36a3547..d8705765d02 100644 --- a/python/grass/temporal/register.py +++ b/python/grass/temporal/register.py @@ -158,10 +158,7 @@ def register_maps_in_space_time_dataset( # Read the map list from file if file: - if hasattr(file, "readline"): - fd = file - else: - fd = open(file) + fd = file if hasattr(file, "readline") else open(file) line = True while True: @@ -639,10 +636,7 @@ def register_map_object_list( string = f"{id}|{start}|{end}\n" register_file.write(string) - if output_stds: - output_stds_id = output_stds.get_id() - else: - output_stds_id = None + output_stds_id = output_stds.get_id() if output_stds else None register_maps_in_space_time_dataset( type, output_stds_id, unit=unit, file=filename, dbif=dbif diff --git a/python/grass/temporal/sampling.py b/python/grass/temporal/sampling.py index 425ca484da5..5209ce6a80c 100644 --- a/python/grass/temporal/sampling.py +++ b/python/grass/temporal/sampling.py @@ -82,19 +82,11 @@ def sample_stds_by_stds_topology( sts = [] for input in inputs: - if input.find("@") >= 0: - id = input - else: - id = input + "@" + mapset - + id = input if input.find("@") >= 0 else input + "@" + mapset st = dataset_factory(intype, id) sts.append(st) - if sampler.find("@") >= 0: - sid = sampler - else: - sid = sampler + "@" + mapset - + sid = sampler if sampler.find("@") >= 0 else sampler + "@" + mapset sst = dataset_factory(sampletype, sid) dbif = SQLDatabaseInterfaceConnection() @@ -156,10 +148,7 @@ def sample_stds_by_stds_topology( map = entry["granule"] start, end = map.get_temporal_extent_as_tuple() - if end: - delta = end - start - else: - delta = None + delta = end - start if end else None delta_first = start - first_time if map.is_time_absolute(): diff --git a/python/grass/temporal/temporal_algebra.py b/python/grass/temporal/temporal_algebra.py index e4717eb3326..2429b61e35e 100644 --- a/python/grass/temporal/temporal_algebra.py +++ b/python/grass/temporal/temporal_algebra.py @@ -992,10 +992,7 @@ def generate_map_name(self): same object for map name generation in multiple threads. """ self.count += 1 - if self.pid is not None: - pid = self.pid - else: - pid = os.getpid() + pid = self.pid if self.pid is not None else os.getpid() name = "tmp_map_name_%i_%i" % (pid, self.count) self.names[name] = name return name @@ -1234,10 +1231,7 @@ def check_stds(self, input, clear=False, stds_type=None, check_type=True): """ if isinstance(input, str): # Check for mapset in given stds input. - if input.find("@") >= 0: - id_input = input - else: - id_input = input + "@" + self.mapset + id_input = input if input.find("@") >= 0 else input + "@" + self.mapset # Create empty spacetime dataset. if stds_type: stds = dataset_factory(stds_type, id_input) @@ -1634,7 +1628,7 @@ def build_spatio_temporal_topology_list( def assign_bool_value( self, map_i, temporal_topo_list=["EQUAL"], spatial_topo_list=[] - ): + ) -> bool: """Function to assign boolean map value based on the map_values from the compared map list by topological relationships. @@ -1668,10 +1662,7 @@ def assign_bool_value( str(relationmap.get_temporal_extent_as_tuple()) + str(boolean), ) - if all(condition_value_list): - resultbool = True - else: - resultbool = False + resultbool = bool(all(condition_value_list)) map_i.condition_value = [resultbool] return resultbool @@ -2296,20 +2287,14 @@ def recurse_compare(conditionlist): ele_index = conditionlist.index(ele) right = conditionlist.pop(ele_index) left = conditionlist.pop(ele_index - 2) - if any([left, right]): - result = True - else: - result = False + result = bool(any([left, right])) conditionlist[ele_index - 2] = result recurse_compare(conditionlist) if ele == "&&": ele_index = conditionlist.index(ele) right = conditionlist.pop(ele_index) left = conditionlist.pop(ele_index - 2) - if all([left, right]): - result = True - else: - result = False + result = bool(all([left, right])) conditionlist[ele_index - 2] = result recurse_compare(conditionlist) @@ -2643,10 +2628,7 @@ def p_expr_tmap_function(self, t): input = t[3] if not isinstance(input, list): # Check for mapset in given stds input. - if input.find("@") >= 0: - id_input = input - else: - id_input = input + "@" + self.mapset + id_input = input if input.find("@") >= 0 else input + "@" + self.mapset # Create empty map dataset. map_i = dataset_factory(self.maptype, id_input) # Check for occurrence of space time dataset. @@ -3079,10 +3061,7 @@ def p_expr_t_select_operator(self, t): # Evaluate temporal operator. operators = self.eval_toperator(t[2], optype="select") # Check for negative selection. - if operators[2] == "!:": - negation = True - else: - negation = False + negation = operators[2] == "!:" # Perform selection. selectlist = self.perform_temporal_selection( maplistA, maplistB, topolist=operators[0], inverse=negation diff --git a/python/grass/temporal/temporal_granularity.py b/python/grass/temporal/temporal_granularity.py index b4043054520..173e4e715ea 100644 --- a/python/grass/temporal/temporal_granularity.py +++ b/python/grass/temporal/temporal_granularity.py @@ -494,7 +494,7 @@ def compute_absolute_time_granularity(maps): # Keep the temporal extent to compare to the following/next map previous_start, previous_end = start, end - # Create a list with a single time unit only + # Create a set with a single time unit only dlist = set() assigned_time_unit = None time_unit_multipliers = { @@ -529,11 +529,8 @@ def compute_absolute_time_granularity(maps): if not dlist: return None - if len(dlist) > 1: - # Find greatest common divisor - granularity = gcd_list(dlist) - else: - granularity = dlist.pop() + # Find greatest common divisor to get a single time unit + granularity = gcd_list(dlist) if len(dlist) > 1 else dlist.pop() if granularity is None: return None diff --git a/python/grass/temporal/temporal_raster_base_algebra.py b/python/grass/temporal/temporal_raster_base_algebra.py index 8ff156cbed5..cb2122f4a37 100644 --- a/python/grass/temporal/temporal_raster_base_algebra.py +++ b/python/grass/temporal/temporal_raster_base_algebra.py @@ -960,10 +960,7 @@ def p_expr_spmap_function(self, t): input = t[3] if not isinstance(input, list): # Check for mapset in given stds input. - if input.find("@") >= 0: - id_input = input - else: - id_input = input + "@" + self.mapset + id_input = input if input.find("@") >= 0 else input + "@" + self.mapset # Create empty map dataset. map_i = dataset_factory(self.maptype, id_input) # Check for occurrence of space time dataset. diff --git a/python/grass/temporal/univar_statistics.py b/python/grass/temporal/univar_statistics.py index dd334e7e9f1..b6a9c1ac508 100755 --- a/python/grass/temporal/univar_statistics.py +++ b/python/grass/temporal/univar_statistics.py @@ -304,10 +304,7 @@ def print_vector_dataset_univar_statistics( mapset = get_current_mapset() - if input.find("@") >= 0: - id = input - else: - id = input + "@" + mapset + id = input if input.find("@") >= 0 else input + "@" + mapset sp = dataset_factory("stvds", id) diff --git a/scripts/d.rast.edit/d.rast.edit.py b/scripts/d.rast.edit/d.rast.edit.py index ea6cc1e46bf..3464941e825 100755 --- a/scripts/d.rast.edit/d.rast.edit.py +++ b/scripts/d.rast.edit/d.rast.edit.py @@ -295,10 +295,7 @@ def paint_cell(self, dc, r, c): px, py = -dy, dx r, g, b, a = wx.Colour(fill).Get() - if r + g + b > 384: - line = "black" - else: - line = "white" + line = "black" if r + g + b > 384 else "white" dc.SetPen(wx.Pen(line)) dc.DrawLine(x0, y0, x1, y1) diff --git a/scripts/d.rast.leg/d.rast.leg.py b/scripts/d.rast.leg/d.rast.leg.py index 85cb423f9e9..74576113577 100755 --- a/scripts/d.rast.leg/d.rast.leg.py +++ b/scripts/d.rast.leg/d.rast.leg.py @@ -132,16 +132,10 @@ def main(): if not nlines: nlines = None - if rast: - lmap = rast - else: - lmap = map + lmap = rast or map kv = gs.raster_info(map=lmap) - if kv["datatype"] == "CELL": - leg_at = None - else: - leg_at = "%f,95,5,10" % VSpacing + leg_at = None if kv["datatype"] == "CELL" else "%f,95,5,10" % VSpacing # checking for histogram causes more problems than it solves # histfiledir = grass.find_file(lmap, 'cell_misc')['file'] diff --git a/scripts/db.droptable/db.droptable.py b/scripts/db.droptable/db.droptable.py index 571638748cf..39408221acc 100755 --- a/scripts/db.droptable/db.droptable.py +++ b/scripts/db.droptable/db.droptable.py @@ -56,14 +56,8 @@ def main(): gs.run_command("db.connect", flags="c", quiet=True) kv = gs.db_connection() - if options["database"]: - database = options["database"] - else: - database = kv["database"] - if options["driver"]: - driver = options["driver"] - else: - driver = kv["driver"] + database = options["database"] or kv["database"] + driver = options["driver"] or kv["driver"] # schema needed for PG? if force: diff --git a/scripts/db.out.ogr/db.out.ogr.py b/scripts/db.out.ogr/db.out.ogr.py index 4a840755b20..4fdfed23648 100755 --- a/scripts/db.out.ogr/db.out.ogr.py +++ b/scripts/db.out.ogr/db.out.ogr.py @@ -72,10 +72,7 @@ def main(): if format.lower() == "dbf": format = "ESRI_Shapefile" - if format.lower() == "csv": - olayer = basename(output, "csv") - else: - olayer = None + olayer = basename(output, "csv") if format.lower() == "csv" else None # is there a simpler way of testing for --overwrite? dbffile = input + ".dbf" diff --git a/scripts/db.univar/db.univar.py b/scripts/db.univar/db.univar.py index 97dfbdb7dbe..4654e3011a0 100755 --- a/scripts/db.univar/db.univar.py +++ b/scripts/db.univar/db.univar.py @@ -118,10 +118,7 @@ def main(): perc = [float(p) for p in perc.split(",")] if not output_format: - if shellstyle: - output_format = "shell" - else: - output_format = "plain" + output_format = "shell" if shellstyle else "plain" elif shellstyle: # This can be a message or warning in future versions. # In version 9, -g may be removed. diff --git a/scripts/g.extension/g.extension.py b/scripts/g.extension/g.extension.py index 194f498d49c..f14a742ca06 100644 --- a/scripts/g.extension/g.extension.py +++ b/scripts/g.extension/g.extension.py @@ -1608,10 +1608,7 @@ def install_extension_win(name): source, url = resolve_source_code(url="{0}/{1}.zip".format(base_url, name)) # to hide non-error messages from subprocesses - if gs.verbosity() <= 2: - outdev = open(os.devnull, "w") - else: - outdev = sys.stdout + outdev = open(os.devnull, "w") if gs.verbosity() <= 2 else sys.stdout # download Addons ZIP file os.chdir(TMPDIR) # this is just to not leave something behind @@ -1961,10 +1958,7 @@ def install_extension_std_platforms(name, source, url, branch): path_to_src_code_message = _("Path to the source code:") # to hide non-error messages from subprocesses - if gs.verbosity() <= 2: - outdev = open(os.devnull, "w") - else: - outdev = sys.stdout + outdev = open(os.devnull, "w") if gs.verbosity() <= 2 else sys.stdout os.chdir(TMPDIR) # this is just to not leave something behind srcdir = os.path.join(TMPDIR, name) @@ -2578,10 +2572,7 @@ def resolve_known_host_service(url, name, branch): ) return None, None if match: - if not actual_start: - actual_start = match["url_start"] - else: - actual_start = "" + actual_start = match["url_start"] if not actual_start else "" if "branch" in match["url_end"]: suffix = match["url_end"].format( name=name, diff --git a/scripts/g.manual/g.manual.py b/scripts/g.manual/g.manual.py index f4ecf961076..345a6d1714a 100755 --- a/scripts/g.manual/g.manual.py +++ b/scripts/g.manual/g.manual.py @@ -132,10 +132,7 @@ def main(): elif flags["t"]: special = "topics" - if flags["m"]: - start = start_man - else: - start = start_browser + start = start_man if flags["m"] else start_browser entry = options["entry"] gisbase = os.environ["GISBASE"] diff --git a/scripts/i.in.spotvgt/i.in.spotvgt.py b/scripts/i.in.spotvgt/i.in.spotvgt.py index cd744d4c252..666f3721761 100755 --- a/scripts/i.in.spotvgt/i.in.spotvgt.py +++ b/scripts/i.in.spotvgt/i.in.spotvgt.py @@ -136,11 +136,7 @@ def main(): spotdir = os.path.dirname(infile) spotname = gs.basename(infile, "hdf") - - if rast: - name = rast - else: - name = spotname + name = rast or spotname if not gs.overwrite() and gs.find_file(name)["file"]: gs.fatal(_("<%s> already exists. Aborting.") % name) diff --git a/scripts/i.oif/i.oif.py b/scripts/i.oif/i.oif.py index 0dabbe7cb38..cb156675927 100755 --- a/scripts/i.oif/i.oif.py +++ b/scripts/i.oif/i.oif.py @@ -90,10 +90,7 @@ def main(): stddev[band] = float(kv["stddev"]) else: # run all bands in parallel - if "WORKERS" in os.environ: - workers = int(os.environ["WORKERS"]) - else: - workers = len(bands) + workers = int(os.environ["WORKERS"]) if "WORKERS" in os.environ else len(bands) proc = {} pout = {} @@ -142,10 +139,7 @@ def main(): _("The Optimum Index Factor analysis result (best combination shown first):") ) - if shell: - fmt = "%s,%s,%s:%.4f\n" - else: - fmt = "%s, %s, %s: %.4f\n" + fmt = "%s,%s,%s:%.4f\n" if shell else "%s, %s, %s: %.4f\n" if not output or output == "-": for v, p in oif: diff --git a/scripts/i.spectral/i.spectral.py b/scripts/i.spectral/i.spectral.py index 171eac7359c..07efd8af31f 100755 --- a/scripts/i.spectral/i.spectral.py +++ b/scripts/i.spectral/i.spectral.py @@ -136,10 +136,7 @@ def draw_gnuplot(what, xlabels, output, img_format, coord_legend): cmd = [] for i, row in enumerate(what): - if not coord_legend: - title = "Pick " + str(i + 1) - else: - title = str(tuple(row[0:2])) + title = "Pick " + str(i + 1) if not coord_legend else str(tuple(row[0:2])) x_datafile = os.path.join(tmp_dir, "data_%d" % i) cmd.append(" '%s' title '%s'" % (x_datafile, title)) diff --git a/scripts/m.proj/m.proj.py b/scripts/m.proj/m.proj.py index 4540b3dcd0a..a018606fff9 100755 --- a/scripts/m.proj/m.proj.py +++ b/scripts/m.proj/m.proj.py @@ -236,14 +236,8 @@ def main(): gcore.debug("output file=[%s]" % outfile) # set up output style - if not decimal: - outfmt = ["-w5"] - else: - outfmt = ["-f", "%.8f"] - if not copy_input: - copyinp = [] - else: - copyinp = ["-E"] + outfmt = ["-w5"] if not decimal else ["-f", "%.8f"] + copyinp = [] if not copy_input else ["-E"] # do the conversion # Convert cs2cs DMS format to GRASS DMS format: diff --git a/scripts/r.buffer.lowmem/r.buffer.lowmem.py b/scripts/r.buffer.lowmem/r.buffer.lowmem.py index 2916ad95e7d..8866c21faeb 100755 --- a/scripts/r.buffer.lowmem/r.buffer.lowmem.py +++ b/scripts/r.buffer.lowmem/r.buffer.lowmem.py @@ -92,10 +92,7 @@ def main(): s = gs.read_command("g.proj", flags="j") kv = gs.parse_key_val(s) - if kv["+proj"] == "longlat": - metric = "geodesic" - else: - metric = "squared" + metric = "geodesic" if kv["+proj"] == "longlat" else "squared" gs.run_command( "r.grow.distance", input=input, metric=metric, distance=temp_dist, flags="m" diff --git a/scripts/r.in.aster/r.in.aster.py b/scripts/r.in.aster/r.in.aster.py index 24722293dde..626d27e7976 100755 --- a/scripts/r.in.aster/r.in.aster.py +++ b/scripts/r.in.aster/r.in.aster.py @@ -152,10 +152,7 @@ def main(): # Band 3b is not included ASTER L1T if proctype == "L1T": allbands.remove("3b") - if band == "all": - bandlist = allbands - else: - bandlist = band.split(",") + bandlist = allbands if band == "all" else band.split(",") # initialize datasets for L1A, L1B, L1T if proctype in {"L1A", "L1B", "L1T"}: diff --git a/scripts/r.in.srtm/r.in.srtm.py b/scripts/r.in.srtm/r.in.srtm.py index 1e4c585ac02..b9f51415ca0 100755 --- a/scripts/r.in.srtm/r.in.srtm.py +++ b/scripts/r.in.srtm/r.in.srtm.py @@ -177,10 +177,7 @@ def main(): infile = infile[:-4] (fdir, tile) = os.path.split(infile) - if not output: - tileout = tile - else: - tileout = output + tileout = output or tile if ".hgt" in input: suff = ".hgt" diff --git a/scripts/r.in.wms/wms_cap_parsers.py b/scripts/r.in.wms/wms_cap_parsers.py index 56b1d0ce48c..723a63f0b23 100644 --- a/scripts/r.in.wms/wms_cap_parsers.py +++ b/scripts/r.in.wms/wms_cap_parsers.py @@ -501,10 +501,7 @@ def _find(self, etreeElement, tag, ns=None): """!Find child element. If the element is not found it raises xml.etree.ElementTree.ParseError. """ - if not ns: - res = etreeElement.find(tag) - else: - res = etreeElement.find(ns(tag)) + res = etreeElement.find(tag) if not ns else etreeElement.find(ns(tag)) if res is None: raise ParseError( @@ -521,10 +518,7 @@ def _findall(self, etreeElement, tag, ns=None): """!Find all children element. If no element is found it raises xml.etree.ElementTree.ParseError. """ - if not ns: - res = etreeElement.findall(tag) - else: - res = etreeElement.findall(ns(tag)) + res = etreeElement.findall(tag) if not ns else etreeElement.findall(ns(tag)) if not res: raise ParseError( diff --git a/scripts/r.in.wms/wms_drv.py b/scripts/r.in.wms/wms_drv.py index 531112a1a6c..e1131918c4a 100644 --- a/scripts/r.in.wms/wms_drv.py +++ b/scripts/r.in.wms/wms_drv.py @@ -995,10 +995,7 @@ def _parseTilePattern(self, group_t_patts, bbox, region): res["y"] = (bbox["maxy"] - bbox["miny"]) / region["rows"] res["x"] = (bbox["maxx"] - bbox["minx"]) / region["cols"] - if res["x"] < res["y"]: - comp_res = "x" - else: - comp_res = "y" + comp_res = "x" if res["x"] < res["y"] else "y" t_res = {} best_patt = None diff --git a/scripts/r.out.xyz/r.out.xyz.py b/scripts/r.out.xyz/r.out.xyz.py index ae8e04de4d6..6df97f3c202 100755 --- a/scripts/r.out.xyz/r.out.xyz.py +++ b/scripts/r.out.xyz/r.out.xyz.py @@ -48,10 +48,7 @@ def main(): output = options["output"] donodata = flags["i"] - if donodata: - statsflags = "1g" - else: - statsflags = "1gn" + statsflags = "1g" if donodata else "1gn" parameters = { "flags": statsflags, "input": options["input"], diff --git a/scripts/r.reclass.area/r.reclass.area.py b/scripts/r.reclass.area/r.reclass.area.py index 5d6fc1292bc..01e474659bc 100755 --- a/scripts/r.reclass.area/r.reclass.area.py +++ b/scripts/r.reclass.area/r.reclass.area.py @@ -152,10 +152,7 @@ def reclass(inf, outf, lim, clump, diag, les): if len(f) < 5: continue hectares = float(f[4]) * 0.0001 - if lesser: - test = hectares <= limit - else: - test = hectares >= limit + test = hectares <= limit if lesser else hectares >= limit if test: rules += "%s = %s %s\n" % (f[0], f[2], f[3]) if rules: diff --git a/scripts/r.unpack/r.unpack.py b/scripts/r.unpack/r.unpack.py index 575d465ebb5..dd595b4722b 100644 --- a/scripts/r.unpack/r.unpack.py +++ b/scripts/r.unpack/r.unpack.py @@ -92,10 +92,7 @@ def main(): return 0 - if options["output"]: - map_name = options["output"] - else: - map_name = data_names[0].split("@")[0] + map_name = options["output"] or data_names[0].split("@")[0] gfile = grass.find_file(name=map_name, element="cell", mapset=".") if gfile["file"]: diff --git a/scripts/r3.in.xyz/r3.in.xyz.py b/scripts/r3.in.xyz/r3.in.xyz.py index b17d59506b7..5b2c8be4a65 100755 --- a/scripts/r3.in.xyz/r3.in.xyz.py +++ b/scripts/r3.in.xyz/r3.in.xyz.py @@ -226,10 +226,7 @@ def main(): addl_opts["flags"] = "i" if scan_only or shell_style: - if shell_style: - doShell = "g" - else: - doShell = "" + doShell = "g" if shell_style else "" grass.run_command( "r.in.xyz", flags="s" + doShell, @@ -243,10 +240,7 @@ def main(): ) sys.exit() - if dtype == "float": - data_type = "FCELL" - else: - data_type = "DCELL" + data_type = "FCELL" if dtype == "float" else "DCELL" region = grass.region(region3d=True) diff --git a/scripts/v.build.all/v.build.all.py b/scripts/v.build.all/v.build.all.py index 69b0837209f..8691ecddc32 100755 --- a/scripts/v.build.all/v.build.all.py +++ b/scripts/v.build.all/v.build.all.py @@ -31,10 +31,7 @@ def main(): vectors = grass.list_grouped("vect")[mapset] num_vectors = len(vectors) - if grass.verbosity() < 2: - quiet = True - else: - quiet = False + quiet = grass.verbosity() < 2 i = 1 for vect in vectors: diff --git a/scripts/v.db.reconnect.all/v.db.reconnect.all.py b/scripts/v.db.reconnect.all/v.db.reconnect.all.py index b42b8006673..9a9d46356a9 100755 --- a/scripts/v.db.reconnect.all/v.db.reconnect.all.py +++ b/scripts/v.db.reconnect.all/v.db.reconnect.all.py @@ -255,10 +255,7 @@ def main(): schema = "" table = schema_table - if new_schema: - new_schema_table = "%s.%s" % (new_schema, table) - else: - new_schema_table = table + new_schema_table = "%s.%s" % (new_schema, table) if new_schema else table gs.debug( "DATABASE = '%s' SCHEMA = '%s' TABLE = '%s' ->\n" diff --git a/scripts/v.dissolve/tests/conftest.py b/scripts/v.dissolve/tests/conftest.py index 9b069330488..e5e9a38818d 100644 --- a/scripts/v.dissolve/tests/conftest.py +++ b/scripts/v.dissolve/tests/conftest.py @@ -13,10 +13,7 @@ def updates_as_transaction(table, cat_column, column, column_quote, cats, values): """Create SQL statement for categories and values for a given column""" sql = ["BEGIN TRANSACTION"] - if column_quote: - quote = "'" - else: - quote = "" + quote = "'" if column_quote else "" for cat, value in zip(cats, values): sql.append( f"UPDATE {table} SET {column} = {quote}{value}{quote} " diff --git a/scripts/v.dissolve/tests/v_dissolve_aggregate_test.py b/scripts/v.dissolve/tests/v_dissolve_aggregate_test.py index 68ca178b864..90dc3de075e 100644 --- a/scripts/v.dissolve/tests/v_dissolve_aggregate_test.py +++ b/scripts/v.dissolve/tests/v_dissolve_aggregate_test.py @@ -101,10 +101,7 @@ def test_aggregate_column_result(dataset, backend): for stats_column in stats_columns: assert stats_column in columns column_info = columns[stats_column] - if stats_column.endswith("_n"): - correct_type = "integer" - else: - correct_type = "double precision" + correct_type = "integer" if stats_column.endswith("_n") else "double precision" assert ( columns[stats_column]["type"].lower() == correct_type ), f"{stats_column} has a wrong type" @@ -221,10 +218,7 @@ def test_sqlite_agg_accepted(dataset): for method, stats_column in zip(stats, expected_stats_columns): assert stats_column in columns column_info = columns[stats_column] - if method == "count": - correct_type = "integer" - else: - correct_type = "double precision" + correct_type = "integer" if method == "count" else "double precision" assert ( columns[stats_column]["type"].lower() == correct_type ), f"{stats_column} has a wrong type" diff --git a/scripts/v.dissolve/tests/v_dissolve_layers_test.py b/scripts/v.dissolve/tests/v_dissolve_layers_test.py index 702aa8f8496..f6986d35917 100644 --- a/scripts/v.dissolve/tests/v_dissolve_layers_test.py +++ b/scripts/v.dissolve/tests/v_dissolve_layers_test.py @@ -50,10 +50,7 @@ def test_layer_2(dataset_layer_2): for method, stats_column in zip(stats, expected_stats_columns): assert stats_column in columns column_info = columns[stats_column] - if method == "count": - correct_type = "integer" - else: - correct_type = "double precision" + correct_type = "integer" if method == "count" else "double precision" assert ( columns[stats_column]["type"].lower() == correct_type ), f"{stats_column} has a wrong type" diff --git a/scripts/v.in.e00/v.in.e00.py b/scripts/v.in.e00/v.in.e00.py index 4d63636199f..4258fa3181a 100755 --- a/scripts/v.in.e00/v.in.e00.py +++ b/scripts/v.in.e00/v.in.e00.py @@ -86,10 +86,7 @@ def main(): ) merging = True - if vect: - name = vect - else: - name = e00name + name = vect or e00name # do import diff --git a/scripts/v.in.lines/v.in.lines.py b/scripts/v.in.lines/v.in.lines.py index 44112b297a3..35991988f6b 100755 --- a/scripts/v.in.lines/v.in.lines.py +++ b/scripts/v.in.lines/v.in.lines.py @@ -50,12 +50,7 @@ def main(): fs = separator(options["separator"]) threeD = flags["z"] - - if threeD: - do3D = "z" - else: - do3D = "" - + do3D = "z" if threeD else "" tmp = grass.tempfile() # set up input file diff --git a/scripts/v.in.mapgen/v.in.mapgen.py b/scripts/v.in.mapgen/v.in.mapgen.py index 404fb7ec6b2..efe7af1075d 100755 --- a/scripts/v.in.mapgen/v.in.mapgen.py +++ b/scripts/v.in.mapgen/v.in.mapgen.py @@ -73,18 +73,12 @@ def main(): if not os.path.isfile(infile): grass.fatal(_("Input file <%s> not found") % infile) - if output: - name = output - else: - name = "" + name = output or "" if threeD: matlab = True - if threeD: - do3D = "z" - else: - do3D = "" + do3D = "z" if threeD else "" tmp = grass.tempfile() diff --git a/scripts/v.pack/v.pack.py b/scripts/v.pack/v.pack.py index 4468c888bcb..e39d52dbafe 100755 --- a/scripts/v.pack/v.pack.py +++ b/scripts/v.pack/v.pack.py @@ -73,10 +73,7 @@ def main(): infile = infile.split("@")[0] # output name - if options["output"]: - outfile = options["output"] - else: - outfile = infile + ".pack" + outfile = options["output"] or infile + ".pack" # check if exists the output file if os.path.exists(outfile): diff --git a/scripts/v.rast.stats/v.rast.stats.py b/scripts/v.rast.stats/v.rast.stats.py index 803fc8691ad..4096aa49caf 100644 --- a/scripts/v.rast.stats/v.rast.stats.py +++ b/scripts/v.rast.stats/v.rast.stats.py @@ -116,10 +116,7 @@ def main(): # Get mapset of the vector vs = vector.split("@") - if len(vs) > 1: - vect_mapset = vs[1] - else: - vect_mapset = mapset + vect_mapset = vs[1] if len(vs) > 1 else mapset # does map exist in CURRENT mapset? if vect_mapset != mapset or not gs.find_file(vector, "vector", mapset)["file"]: @@ -373,10 +370,7 @@ def set_up_columns(vector, layer, percentile, colprefix, basecols, dbfdriver, c) perc = b if perc: # namespace is limited in DBF but the % value is important - if dbfdriver: - perccol = "per" + percentile - else: - perccol = "percentile_" + percentile + perccol = "per" + percentile if dbfdriver else "percentile_" + percentile percindex = basecols.index(perc) basecols[percindex] = perccol @@ -424,10 +418,7 @@ def set_up_columns(vector, layer, percentile, colprefix, basecols, dbfdriver, c) + _("Use -c flag to update values in this column.") ) else: - if i == "n": - coltype = "INTEGER" - else: - coltype = "DOUBLE PRECISION" + coltype = "INTEGER" if i == "n" else "DOUBLE PRECISION" addcols.append(currcolumn + " " + coltype) if addcols: diff --git a/scripts/v.report/v.report.py b/scripts/v.report/v.report.py index cec84582155..29d9d3c914e 100755 --- a/scripts/v.report/v.report.py +++ b/scripts/v.report/v.report.py @@ -91,10 +91,7 @@ def main(): isConnection = False colnames = ["cat"] - if option == "coor": - extracolnames = ["x", "y", "z"] - else: - extracolnames = [option] + extracolnames = ["x", "y", "z"] if option == "coor" else [option] if units == "percent": unitsp = "meters" diff --git a/scripts/v.unpack/v.unpack.py b/scripts/v.unpack/v.unpack.py index ea75d443b57..c3a7a55deb7 100644 --- a/scripts/v.unpack/v.unpack.py +++ b/scripts/v.unpack/v.unpack.py @@ -93,10 +93,7 @@ def main(): return 0 # set the output name - if options["output"]: - map_name = options["output"] - else: - map_name = data_name + map_name = options["output"] or data_name # grass env gisenv = grass.gisenv() @@ -233,19 +230,13 @@ def main(): # for each old connection for t in dbnlist: # it split the line of each connection, to found layer number and key - if len(t.split("|")) != 1: - values = t.split("|") - else: - values = t.split(" ") + values = t.split("|") if len(t.split("|")) != 1 else t.split(" ") from_table = values[1] layer = values[0].split("/")[0] # we need to take care about the table name in case of several layer if options["output"]: - if len(dbnlist) > 1: - to_table = "%s_%s" % (map_name, layer) - else: - to_table = map_name + to_table = "%s_%s" % (map_name, layer) if len(dbnlist) > 1 else map_name else: to_table = from_table From af55fa7eaeeaabd3c4db99f4622e9849b71da80a Mon Sep 17 00:00:00 2001 From: Arohan Ajit Date: Tue, 22 Oct 2024 10:20:23 -0400 Subject: [PATCH 69/69] d.rast.edit: Fixed E722 in d.rast.edit/ (#4568) --- .flake8 | 1 - scripts/d.rast.edit/d.rast.edit.py | 21 +-------------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/.flake8 b/.flake8 index 8211d9e03d4..ffa7d162eda 100644 --- a/.flake8 +++ b/.flake8 @@ -108,7 +108,6 @@ per-file-ignores = scripts/i.pansharpen/i.pansharpen.py: E722, E501 scripts/r.in.srtm/r.in.srtm.py: E722 scripts/r.fillnulls/r.fillnulls.py: E722 - scripts/d.rast.edit/d.rast.edit.py: E722 scripts/v.what.strds/v.what.strds.py: E501 # Line too long (esp. module interface definitions) scripts/*/*.py: E501 diff --git a/scripts/d.rast.edit/d.rast.edit.py b/scripts/d.rast.edit/d.rast.edit.py index 3464941e825..102d7e447d8 100755 --- a/scripts/d.rast.edit/d.rast.edit.py +++ b/scripts/d.rast.edit/d.rast.edit.py @@ -644,28 +644,9 @@ def update_status(self, row, col): if self.angles: self.status["aspect"] = self.angles[row][col] - def force_color(self, val): - run("g.region", rows=1, cols=1) - run("r.mapcalc", expression="%s = %d" % (self.tempmap, val)) - run("r.colors", map=self.tempmap, rast=self.inmap) - run("r.out.ppm", input=self.tempmap, out=self.tempfile) - run("g.remove", flags="f", type="raster", name=self.tempmap) - - tempimg = wx.Image(self.tempfile) - gs.try_remove(self.tempfile) - - rgb = tempimg.get(0, 0) - color = "#%02x%02x%02x" % rgb - self.colors[val] = color - tempimg.delete() - def get_color(self, val): if val not in self.colors: - try: - self.force_color(val) - except: - self.colors[val] = "#ffffff" - + self.colors[val] = "#ffffff" return self.colors[val] def refresh_canvas(self):