From 20ad9f3f6ce204c42ccb91812e96b1878330f27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 2 Nov 2025 22:49:59 +0000 Subject: [PATCH 1/9] CQ: Start enforcing I001: Import sorting Ruff rule: https://docs.astral.sh/ruff/rules/unsorted-imports/ Starts applying to simple cases, and not too big folders, where there shouldn't be issues with import order matters. --- db/db.columns/testsuite/test_dbcolumns.py | 2 +- db/db.connect/testsuite/test_db_connect.py | 2 +- display/d.mon/render_cmd.py | 4 ++-- display/d.text/test.py | 2 +- general/g.findfile/tests/test_g_findfile.py | 2 +- locale/grass_po_stats.py | 1 - misc/m.measure/testsuite/test_m_measure.py | 2 +- pyproject.toml | 13 ++++++++++++- raster3d/r3.flow/testsuite/r3flow_test.py | 1 + raster3d/r3.gradient/testsuite/r3gradient_test.py | 1 - raster3d/r3.info/testsuite/test_r3_info.py | 2 +- temporal/t.list/t.list.py | 2 +- temporal/t.rast.colors/t.rast.colors.py | 4 +++- temporal/t.rast.list/tests/conftest.py | 3 +-- temporal/t.rast.list/tests/t_rast_list_test.py | 3 +-- temporal/t.rast.series/t.rast.series.py | 4 +++- 16 files changed, 30 insertions(+), 18 deletions(-) diff --git a/db/db.columns/testsuite/test_dbcolumns.py b/db/db.columns/testsuite/test_dbcolumns.py index 11f30b80df9..bbb42c3d9a9 100644 --- a/db/db.columns/testsuite/test_dbcolumns.py +++ b/db/db.columns/testsuite/test_dbcolumns.py @@ -1,6 +1,6 @@ from grass.gunittest.case import TestCase from grass.gunittest.main import test -from grass.script.core import read_command, parse_command +from grass.script.core import parse_command, read_command output_plain = """cat OBJECTID diff --git a/db/db.connect/testsuite/test_db_connect.py b/db/db.connect/testsuite/test_db_connect.py index e5c4e23885d..2bebefad27f 100644 --- a/db/db.connect/testsuite/test_db_connect.py +++ b/db/db.connect/testsuite/test_db_connect.py @@ -1,6 +1,6 @@ from grass.gunittest.case import TestCase from grass.gunittest.main import test -from grass.script.core import read_command, parse_command +from grass.script.core import parse_command, read_command class TestDbConnect(TestCase): diff --git a/display/d.mon/render_cmd.py b/display/d.mon/render_cmd.py index 7f1d2d54dbc..f3f92ce670d 100644 --- a/display/d.mon/render_cmd.py +++ b/display/d.mon/render_cmd.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 +import glob import os import sys -import glob import tempfile from pathlib import Path +from grass.exceptions import CalledModuleError from grass.script import core as grass from grass.script import task as gtask -from grass.exceptions import CalledModuleError non_rendering_modules = ( "d.colorlist", diff --git a/display/d.text/test.py b/display/d.text/test.py index dd8836938a5..66251e744e9 100755 --- a/display/d.text/test.py +++ b/display/d.text/test.py @@ -2,8 +2,8 @@ # Author: Owen Smith - Rewritten from test.pl by Huidae Cho # Run: d.mon start=wx0 && ./test.py | d.text at=0,100 import math -from pathlib import Path import re +from pathlib import Path # Quiet black syntax checking for fonts and colors to keep the code printed to # the display vertically short. diff --git a/general/g.findfile/tests/test_g_findfile.py b/general/g.findfile/tests/test_g_findfile.py index 9297ad2468e..a0b83e63d60 100644 --- a/general/g.findfile/tests/test_g_findfile.py +++ b/general/g.findfile/tests/test_g_findfile.py @@ -1,8 +1,8 @@ import os -import pytest from pathlib import Path import grass.script as gs +import pytest @pytest.fixture(scope="module") diff --git a/locale/grass_po_stats.py b/locale/grass_po_stats.py index db8106d51f5..9c142773257 100644 --- a/locale/grass_po_stats.py +++ b/locale/grass_po_stats.py @@ -22,7 +22,6 @@ import os import subprocess import sys - from pathlib import Path diff --git a/misc/m.measure/testsuite/test_m_measure.py b/misc/m.measure/testsuite/test_m_measure.py index 1b49a7b1b59..8473d0b0161 100644 --- a/misc/m.measure/testsuite/test_m_measure.py +++ b/misc/m.measure/testsuite/test_m_measure.py @@ -1,6 +1,6 @@ from grass.gunittest.case import TestCase from grass.gunittest.main import test -from grass.script.core import read_command, parse_command +from grass.script.core import parse_command, read_command class TestMMeasure(TestCase): diff --git a/pyproject.toml b/pyproject.toml index f58e088bc43..4867bfbb38f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -170,7 +170,6 @@ ignore = [ "FBT001", # boolean-type-hint-positional-argument "FBT002", # boolean-default-value-positional-argument "FBT003", # boolean-positional-value-in-call - "I001", # unsorted-imports "INP001", # implicit-namespace-package "N801", # invalid-class-name "N802", # invalid-function-name @@ -285,10 +284,14 @@ ignore = [ # Ignored after reverting: "gui/**" = ["PLW0108"] # See https://github.com/OSGeo/grass/issues/4124 # Other ignores: +"**.ipynb" = ["I001"] "**.py" = ["PYI066"] "*/testsuite/**.py" = ["PT009", "PT027", "PLW1514"] "display/d.mon/render_cmd.py" = ["PLW1514"] "display/d.text/test.py" = ["PLW1514"] +"doc/**.py" = ["I001"] +"general/**.py" = ["I001"] +"gui/**.py" = ["I001"] "gui/wxpython/animation/temporal_manager.py" = ["PLW1514"] "gui/wxpython/core/gconsole.py" = ["PLW1514"] "gui/wxpython/core/render.py" = ["PLW1514"] @@ -330,11 +333,14 @@ ignore = [ "gui/wxpython/vnet/vnet_data.py" = ["PLW1514"] "gui/wxpython/web_services/dialogs.py" = ["PLW1514"] "gui/wxpython/wxplot/profile.py" = ["A005", "PLW1514", "SIM115"] +"imagery/**.py" = ["I001"] "imagery/i.atcorr/create_iwave.py" = ["PLW1514"] +"lib/**.py" = ["I001"] "lib/imagery/testsuite/test_imagery_sigsetfile.py" = ["FURB152"] "lib/init/grass.py" = ["PLW1514", "SIM115"] "lib/init/testsuite/test_grass_tmp_mapset.py" = ["PTH208"] "locale/grass_po_stats.py" = ["SIM115"] +"man/**.py" = ["I001"] "man/build.py" = ["PLW1514", "PTH208"] "man/build_class.py" = ["PLW1514"] "man/build_class_graphical.py" = ["PLW1514", "PTH208"] @@ -349,6 +355,7 @@ ignore = [ "man/build_rest.py" = ["PLW1514", "PTH208"] "man/build_topics.py" = ["PLW1514"] "man/parser_standard_options.py" = ["PLW1514"] +"python/grass/**.py" = ["I001"] "python/grass/__init__.py" = ["PTH110", "PYI056"] "python/grass/exp*/tests/grass_script_mapset_session_test.py" = ["SIM117"] "python/grass/exp*/tests/grass_script_tmp_mapset_session_test.py" = ["SIM117"] @@ -396,11 +403,13 @@ ignore = [ "python/grass/temporal/univar_statistics.py" = ["PLW1514", "SIM115"] "python/grass/tools/support.py" = ["PLR6201"] "python/grass/utils/download.py" = ["PTH208", "SIM115"] +"raster/**.py" = ["I001"] "raster/r.*/testsuite/*.py" = ["SIM115"] "raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py" = ["PLW1514"] "raster/r.topidx/*.py" = ["SIM115"] "raster/r.topidx/arc_to_gridatb.py" = ["PLW1514"] "raster/r.topidx/gridatb_to_arc.py" = ["PLW1514"] +"scripts/**.py" = ["I001"] "scripts/d.correlate/d.correlate.py" = ["PLW1514", "SIM115"] "scripts/d.frame/d.frame.py" = ["PLW1514", "SIM115"] "scripts/d.out.file/d.out.file.py" = ["PLW1514"] @@ -449,7 +458,9 @@ ignore = [ "temporal/t.rast.what/t.rast.what.py" = ["PLW1514"] "temporal/t.remove/t.remove.py" = ["PLW1514"] "temporal/t.unregister/t.unregister.py" = ["PLW1514"] +"utils/**.py" = ["I001"] "utils/*.py" = ["PLW1514"] +"vector/**.py" = ["I001"] [tool.ruff.lint.flake8-import-conventions.extend-aliases] # Declare a custom aliases, checked with rule ICN001 diff --git a/raster3d/r3.flow/testsuite/r3flow_test.py b/raster3d/r3.flow/testsuite/r3flow_test.py index a1009ef719f..b8277406e41 100644 --- a/raster3d/r3.flow/testsuite/r3flow_test.py +++ b/raster3d/r3.flow/testsuite/r3flow_test.py @@ -5,6 +5,7 @@ """ import os + from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/raster3d/r3.gradient/testsuite/r3gradient_test.py b/raster3d/r3.gradient/testsuite/r3gradient_test.py index b1ae270605d..fec7a21914d 100644 --- a/raster3d/r3.gradient/testsuite/r3gradient_test.py +++ b/raster3d/r3.gradient/testsuite/r3gradient_test.py @@ -7,7 +7,6 @@ from grass.gunittest.case import TestCase from grass.gunittest.main import test - r3univar_test_grad_x = """ n=600 null_cells=0 diff --git a/raster3d/r3.info/testsuite/test_r3_info.py b/raster3d/r3.info/testsuite/test_r3_info.py index 75a9d8c95cf..7bf4ef2e74a 100644 --- a/raster3d/r3.info/testsuite/test_r3_info.py +++ b/raster3d/r3.info/testsuite/test_r3_info.py @@ -1,6 +1,6 @@ from grass.gunittest.case import TestCase from grass.gunittest.main import test -from grass.script.core import read_command, parse_command +from grass.script.core import parse_command, read_command class TestR3Info(TestCase): diff --git a/temporal/t.list/t.list.py b/temporal/t.list/t.list.py index 7f8cab78ddc..7e520d237a4 100755 --- a/temporal/t.list/t.list.py +++ b/temporal/t.list/t.list.py @@ -88,9 +88,9 @@ # %end import sys +from contextlib import nullcontext import grass.script as gs -from contextlib import nullcontext ############################################################################ diff --git a/temporal/t.rast.colors/t.rast.colors.py b/temporal/t.rast.colors/t.rast.colors.py index 7ffa7993d0f..b70e27e23d6 100755 --- a/temporal/t.rast.colors/t.rast.colors.py +++ b/temporal/t.rast.colors/t.rast.colors.py @@ -102,9 +102,11 @@ # % guisection: Define # %end +from pathlib import Path + import grass.script as gs from grass.exceptions import CalledModuleError -from pathlib import Path + ############################################################################ diff --git a/temporal/t.rast.list/tests/conftest.py b/temporal/t.rast.list/tests/conftest.py index eef08f7ae17..cfdcec148ac 100644 --- a/temporal/t.rast.list/tests/conftest.py +++ b/temporal/t.rast.list/tests/conftest.py @@ -4,9 +4,8 @@ from datetime import datetime from types import SimpleNamespace -import pytest - import grass.script as gs +import pytest @pytest.fixture(scope="module") diff --git a/temporal/t.rast.list/tests/t_rast_list_test.py b/temporal/t.rast.list/tests/t_rast_list_test.py index e2919652b23..233e4df059b 100644 --- a/temporal/t.rast.list/tests/t_rast_list_test.py +++ b/temporal/t.rast.list/tests/t_rast_list_test.py @@ -5,9 +5,8 @@ import io import json -import pytest - import grass.script as gs +import pytest yaml = pytest.importorskip("yaml", reason="PyYAML package not available") diff --git a/temporal/t.rast.series/t.rast.series.py b/temporal/t.rast.series/t.rast.series.py index 825e6d69098..af2a51dd62d 100755 --- a/temporal/t.rast.series/t.rast.series.py +++ b/temporal/t.rast.series/t.rast.series.py @@ -92,9 +92,11 @@ # % description: Propagate NULLs # %end +from pathlib import Path + import grass.script as gs from grass.exceptions import CalledModuleError -from pathlib import Path + ############################################################################ From ab6f8e26ed4ee6b4b2532e5227551205cf52c761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 2 Nov 2025 22:52:42 +0000 Subject: [PATCH 2/9] CQ: Fix I001 import sorting in utils/ --- pyproject.toml | 1 - utils/create_python_init_file.py | 2 +- utils/g.html2man/g.html2man.py | 10 +++++----- utils/g.html2man/ggroff.py | 2 +- utils/generate_last_commit_file.py | 3 +-- utils/gitlog2changelog.py | 4 ++-- utils/md_isvalid.py | 4 ++-- utils/merge_sitemaps.py | 2 +- utils/mkhtml.py | 20 ++++++++++---------- utils/mkmarkdown.py | 12 ++++++------ utils/mkrest.py | 4 ++-- utils/ppmrotate.py | 6 +++--- utils/test_generate_last_commit_file.py | 4 ++-- utils/thumbnails.py | 3 +-- utils/update_version.py | 7 +++---- 15 files changed, 40 insertions(+), 44 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4867bfbb38f..78fef518f3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -458,7 +458,6 @@ ignore = [ "temporal/t.rast.what/t.rast.what.py" = ["PLW1514"] "temporal/t.remove/t.remove.py" = ["PLW1514"] "temporal/t.unregister/t.unregister.py" = ["PLW1514"] -"utils/**.py" = ["I001"] "utils/*.py" = ["PLW1514"] "vector/**.py" = ["I001"] diff --git a/utils/create_python_init_file.py b/utils/create_python_init_file.py index d60d3134914..96324bf5b20 100755 --- a/utils/create_python_init_file.py +++ b/utils/create_python_init_file.py @@ -14,9 +14,9 @@ @author Vaclav Petras """ +import glob import os import sys -import glob from pathlib import Path diff --git a/utils/g.html2man/g.html2man.py b/utils/g.html2man/g.html2man.py index f8d5b0a89b4..1d6bae49013 100755 --- a/utils/g.html2man/g.html2man.py +++ b/utils/g.html2man/g.html2man.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -from pathlib import Path -import sys import re -from ghtml import HTMLParser -from ggroff import Formatter - +import sys from io import StringIO +from pathlib import Path + +from ggroff import Formatter +from ghtml import HTMLParser entities = {"nbsp": " ", "bull": "*"} diff --git a/utils/g.html2man/ggroff.py b/utils/g.html2man/ggroff.py index bb770aaa242..5d4624d5986 100644 --- a/utils/g.html2man/ggroff.py +++ b/utils/g.html2man/ggroff.py @@ -1,6 +1,6 @@ -import sys import os import re +import sys __all__ = ["Formatter"] diff --git a/utils/generate_last_commit_file.py b/utils/generate_last_commit_file.py index c6eddc9a094..e9d91bad3a4 100644 --- a/utils/generate_last_commit_file.py +++ b/utils/generate_last_commit_file.py @@ -24,11 +24,10 @@ import json import os -import subprocess import shutil +import subprocess import sys - # Strict ISO 8601 format COMMIT_DATE_FORMAT = "%aI" diff --git a/utils/gitlog2changelog.py b/utils/gitlog2changelog.py index 08b736e308f..d24e8624b79 100755 --- a/utils/gitlog2changelog.py +++ b/utils/gitlog2changelog.py @@ -4,9 +4,9 @@ # Distributed under the terms of the GNU General Public License v2 or later import re -from textwrap import TextWrapper -import sys import subprocess +import sys +from textwrap import TextWrapper rev_range = "" diff --git a/utils/md_isvalid.py b/utils/md_isvalid.py index 0eb9c228376..56bf55f1e8f 100644 --- a/utils/md_isvalid.py +++ b/utils/md_isvalid.py @@ -5,10 +5,10 @@ # (on Debian/Ubuntu - apt install markdownlint) # (using Ruby installer - gem install mdl) -import os -import sys import argparse +import os import subprocess +import sys import grass.script as gs diff --git a/utils/merge_sitemaps.py b/utils/merge_sitemaps.py index 4d3f01af30f..422da3f534a 100644 --- a/utils/merge_sitemaps.py +++ b/utils/merge_sitemaps.py @@ -7,9 +7,9 @@ """ import argparse -from xml.dom import minidom # noqa: S408 import urllib.parse from pathlib import Path +from xml.dom import minidom # noqa: S408 def check_url_version(url: str, version: str) -> str: diff --git a/utils/mkhtml.py b/utils/mkhtml.py index b476e22eba7..3e68e04c223 100644 --- a/utils/mkhtml.py +++ b/utils/mkhtml.py @@ -16,16 +16,14 @@ # ############################################################################# -import sys +import locale import os -import string import re +import string +import sys +import urllib.parse as urlparse from datetime import datetime -import locale - from html.parser import HTMLParser - -import urllib.parse as urlparse from pathlib import Path try: @@ -35,13 +33,15 @@ gs = None from mkdocs import ( - read_file, - get_version_branch, - get_last_git_commit, - top_dir as topdir, get_addon_path, + get_last_git_commit, + get_version_branch, + read_file, set_proxy, ) +from mkdocs import ( + top_dir as topdir, +) grass_version = os.getenv("VERSION_NUMBER", "unknown") trunk_url = "" diff --git a/utils/mkmarkdown.py b/utils/mkmarkdown.py index 17a2b898815..e4ffed5b3d5 100644 --- a/utils/mkmarkdown.py +++ b/utils/mkmarkdown.py @@ -17,9 +17,9 @@ ############################################################################# import os -import sys -import string import re +import string +import sys import urllib.parse as urlparse from pathlib import Path @@ -30,12 +30,12 @@ gs = None from mkdocs import ( - read_file, - get_version_branch, - get_last_git_commit, - top_dir, get_addon_path, + get_last_git_commit, + get_version_branch, + read_file, set_proxy, + top_dir, ) diff --git a/utils/mkrest.py b/utils/mkrest.py index 1cc51c72b8a..ce5fccba548 100755 --- a/utils/mkrest.py +++ b/utils/mkrest.py @@ -14,10 +14,10 @@ # ############################################################################# -import sys -import string import re +import string import subprocess +import sys from datetime import datetime from pathlib import Path diff --git a/utils/ppmrotate.py b/utils/ppmrotate.py index 28bfee13141..a4832edcd12 100755 --- a/utils/ppmrotate.py +++ b/utils/ppmrotate.py @@ -13,10 +13,10 @@ # for details. # -import sys -import os -import atexit import array +import atexit +import os +import sys from pathlib import Path import grass.script as gs diff --git a/utils/test_generate_last_commit_file.py b/utils/test_generate_last_commit_file.py index d5566767a92..388f9632da3 100644 --- a/utils/test_generate_last_commit_file.py +++ b/utils/test_generate_last_commit_file.py @@ -17,12 +17,12 @@ @author Tomas Zigo """ -import os import json +import os import subprocess +from pathlib import Path import pytest -from pathlib import Path from .generate_last_commit_file import COMMIT_DATE_FORMAT diff --git a/utils/thumbnails.py b/utils/thumbnails.py index 12115b428b5..8c9e5bb551c 100755 --- a/utils/thumbnails.py +++ b/utils/thumbnails.py @@ -13,14 +13,13 @@ # for details. # -import os import atexit +import os import sys from pathlib import Path import grass.script as gs - tmp_grad_abs = None tmp_grad_rel = None diff --git a/utils/update_version.py b/utils/update_version.py index 8cab889a528..c96459342ad 100755 --- a/utils/update_version.py +++ b/utils/update_version.py @@ -2,12 +2,11 @@ """Update VERSION file to release and development versions""" -import sys +import argparse import datetime -from types import SimpleNamespace +import sys from pathlib import Path - -import argparse +from types import SimpleNamespace def read_version_file(): From 85a694cbd799124a71a9150cc219c19247592dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sun, 2 Nov 2025 22:55:19 +0000 Subject: [PATCH 3/9] CQ: Fix I001 import sorting in man/ --- man/build.py | 2 +- man/build_check.py | 5 +++-- man/build_check_rest.py | 4 ++-- man/build_class.py | 20 +++++++++--------- man/build_class_graphical.py | 28 ++++++++++++------------- man/build_class_rest.py | 16 +++++++------- man/build_full_index.py | 15 +++++++------ man/build_full_index_rest.py | 16 +++++++------- man/build_graphical_index.py | 2 +- man/build_index.py | 8 +++---- man/build_index_rest.py | 6 +++--- man/build_keywords.py | 2 +- man/build_manual_gallery.py | 8 +++---- man/build_topics.py | 14 ++++++------- man/mkdocs/scripts/hook_list_scripts.py | 3 ++- man/parser_standard_options.py | 3 +-- pyproject.toml | 1 - 17 files changed, 75 insertions(+), 78 deletions(-) diff --git a/man/build.py b/man/build.py index a7e9f5817c9..a802b818adb 100644 --- a/man/build.py +++ b/man/build.py @@ -103,7 +103,7 @@ def get_files(man_dir, cls=None, ignore_gui=True, extension: str = "html"): def write_header(f: IO, title, ismain=False, body_width="99%", template: str = "html"): if template == "html": - from build_html import header1_tmpl, macosx_tmpl, header2_tmpl + from build_html import header1_tmpl, header2_tmpl, macosx_tmpl else: from build_md import header1_tmpl, header2_tmpl f.write(header1_tmpl.substitute(title=title)) diff --git a/man/build_check.py b/man/build_check.py index 1dc578c56af..bdb3ce64596 100644 --- a/man/build_check.py +++ b/man/build_check.py @@ -6,12 +6,13 @@ # Markus Neteler # Glynn Clements -import sys import os +import sys -from build import message_tmpl, get_files, read_file from build_html import man_dir +from build import get_files, message_tmpl, read_file + os.chdir(man_dir) sys.stdout.write(message_tmpl.substitute(man_dir=man_dir)) diff --git a/man/build_check_rest.py b/man/build_check_rest.py index f9868dfd697..fbdff214542 100644 --- a/man/build_check_rest.py +++ b/man/build_check_rest.py @@ -6,10 +6,10 @@ # Markus Neteler # Glynn Clements -import sys import os +import sys -from build_rest import rest_dir, message_tmpl, rest_files, read_file +from build_rest import message_tmpl, read_file, rest_dir, rest_files os.chdir(rest_dir) diff --git a/man/build_class.py b/man/build_class.py index 822bad6bd3d..a97d6ea8655 100644 --- a/man/build_class.py +++ b/man/build_class.py @@ -6,8 +6,8 @@ # Markus Neteler # Glynn Clements -import sys import os +import sys no_intro_page_classes = ["display", "general", "miscellaneous", "postscript"] @@ -15,19 +15,19 @@ def build_class(ext): if ext == "html": from build_html import ( - modclass_tmpl, - get_desc, desc2_tmpl, - modclass_intro_tmpl, + get_desc, man_dir, + modclass_intro_tmpl, + modclass_tmpl, ) else: from build_md import ( - modclass_tmpl, - get_desc, desc2_tmpl, - modclass_intro_tmpl, + get_desc, man_dir, + modclass_intro_tmpl, + modclass_tmpl, ) os.chdir(man_dir) @@ -74,12 +74,12 @@ def build_class(ext): year = sys.argv[3] from build import ( - to_title, check_for_desc_override, - replace_file, get_files, - write_header, + replace_file, + to_title, write_footer, + write_header, ) build_class("html") diff --git a/man/build_class_graphical.py b/man/build_class_graphical.py index 4b67a69998b..661f454a4d4 100644 --- a/man/build_class_graphical.py +++ b/man/build_class_graphical.py @@ -13,30 +13,28 @@ # ############################################################################# -import sys -import os import fnmatch +import os +import sys + +import build_md +from build_html import ( + get_desc, + header1_tmpl, + man_dir, + modclass_intro_tmpl, +) from build import ( + check_for_desc_override, default_year, + get_files, grass_version, + replace_file, to_title, - get_files, - check_for_desc_override, write_footer, - replace_file, -) - -from build_html import ( - header1_tmpl, - modclass_intro_tmpl, - get_desc, - man_dir, ) -import build_md - - graphical_index_style = """\