This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new 642450c  Fix the order of functions in several modules
642450c is described below

commit 642450c76c16b82756a662f9b39f4c87771afbc7
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Apr 14 20:27:52 2025 +0100

    Fix the order of functions in several modules
---
 atr/config.py              | 14 ++++-----
 atr/metadata.py            |  8 ++---
 atr/server.py              | 76 +++++++++++++++++++++++-----------------------
 atr/ssh.py                 | 54 ++++++++++++++++----------------
 atr/user.py                |  8 ++---
 atr/util.py                | 12 ++++----
 atr/worker.py              | 36 +++++++++++-----------
 scripts/interface_order.py | 19 +++++++++---
 8 files changed, 118 insertions(+), 109 deletions(-)

diff --git a/atr/config.py b/atr/config.py
index 4fa9464..5cb2d5b 100644
--- a/atr/config.py
+++ b/atr/config.py
@@ -90,6 +90,13 @@ _CONFIG_DICT: Final = {
 }
 
 
+def get() -> type[AppConfig]:
+    try:
+        return _CONFIG_DICT[get_mode()]
+    except KeyError:
+        exit("Error: Invalid <mode>. Expected values [Debug, Production, 
Profiling].")
+
+
 def get_mode() -> Mode:
     global _global_mode
 
@@ -102,10 +109,3 @@ def get_mode() -> Mode:
             _global_mode = Mode.Debug
 
     return _global_mode
-
-
-def get() -> type[AppConfig]:
-    try:
-        return _CONFIG_DICT[get_mode()]
-    except KeyError:
-        exit("Error: Invalid <mode>. Expected values [Debug, Production, 
Profiling].")
diff --git a/atr/metadata.py b/atr/metadata.py
index a262ebf..8833679 100644
--- a/atr/metadata.py
+++ b/atr/metadata.py
@@ -16,6 +16,10 @@
 # under the License.
 
 
+def _get_undefined() -> tuple[str, str]:
+    return "undefined", "undefined"
+
+
 def _get_version_from_git() -> tuple[str, str] | None:
     """Returns the version when within a development environment."""
 
@@ -62,10 +66,6 @@ def _get_version_from_version_module() -> tuple[str, str] | 
None:
         return None
 
 
-def _get_undefined() -> tuple[str, str]:
-    return "undefined", "undefined"
-
-
 # Try to determine the version from a development environment first.
 # If this fails, try to get it from environment variables that are set when 
building a docker image.
 # We don't use __version__ and __commit__ as these are not reserved words in 
Python
diff --git a/atr/server.py b/atr/server.py
index a87e45b..f49ce1e 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -60,35 +60,13 @@ class ApiOnlyOpenAPIProvider(quart_schema.OpenAPIProvider):
                 yield rule
 
 
-def register_routes(app: base.QuartApp) -> ModuleType:
-    # NOTE: These imports are for their side effects only
-    import atr.routes.modules as modules
-
-    # Add a global error handler to show helpful error messages with tracebacks
-    @app.errorhandler(Exception)
-    async def handle_any_exception(error: Exception) -> Any:
-        import traceback
-
-        # Required to give to the error.html template
-        tb = traceback.format_exc()
-        app.logger.exception("Unhandled exception")
-        return await quart.render_template("error.html", error=str(error), 
traceback=tb, status_code=500), 500
-
-    @app.errorhandler(base.ASFQuartException)
-    async def handle_asfquart_exception(error: base.ASFQuartException) -> Any:
-        # TODO: Figure out why pyright doesn't know about this attribute
-        if not hasattr(error, "errorcode"):
-            errorcode = 500
-        else:
-            errorcode = getattr(error, "errorcode")
-        return await quart.render_template("error.html", error=str(error), 
status_code=errorcode), errorcode
-
-    # Add a global error handler in case a page does not exist.
-    @app.errorhandler(404)
-    async def handle_not_found(error: Exception) -> Any:
-        return await quart.render_template("notfound.html", error="404 Not 
Found", traceback="", status_code=404), 404
-
-    return modules
+def app_create_base(app_config: type[config.AppConfig]) -> base.QuartApp:
+    """Create the base Quart application."""
+    if asfquart.construct is ...:
+        raise ValueError("asfquart.construct is not set")
+    app = asfquart.construct(__name__)
+    app.config.from_object(app_config)
+    return app
 
 
 def app_dirs_setup(app_config: type[config.AppConfig]) -> None:
@@ -103,15 +81,6 @@ def app_dirs_setup(app_config: type[config.AppConfig]) -> 
None:
     util.get_release_dir().mkdir(parents=True, exist_ok=True)
 
 
-def app_create_base(app_config: type[config.AppConfig]) -> base.QuartApp:
-    """Create the base Quart application."""
-    if asfquart.construct is ...:
-        raise ValueError("asfquart.construct is not set")
-    app = asfquart.construct(__name__)
-    app.config.from_object(app_config)
-    return app
-
-
 def app_setup_api_docs(app: base.QuartApp) -> None:
     """Configure OpenAPI documentation."""
     import quart_schema
@@ -253,6 +222,37 @@ def main() -> None:
     app.run(port=8080, ssl_keyfile="key.pem", ssl_certfile="cert.pem")
 
 
+def register_routes(app: base.QuartApp) -> ModuleType:
+    # NOTE: These imports are for their side effects only
+    import atr.routes.modules as modules
+
+    # Add a global error handler to show helpful error messages with tracebacks
+    @app.errorhandler(Exception)
+    async def handle_any_exception(error: Exception) -> Any:
+        import traceback
+
+        # Required to give to the error.html template
+        tb = traceback.format_exc()
+        app.logger.exception("Unhandled exception")
+        return await quart.render_template("error.html", error=str(error), 
traceback=tb, status_code=500), 500
+
+    @app.errorhandler(base.ASFQuartException)
+    async def handle_asfquart_exception(error: base.ASFQuartException) -> Any:
+        # TODO: Figure out why pyright doesn't know about this attribute
+        if not hasattr(error, "errorcode"):
+            errorcode = 500
+        else:
+            errorcode = getattr(error, "errorcode")
+        return await quart.render_template("error.html", error=str(error), 
status_code=errorcode), errorcode
+
+    # Add a global error handler in case a page does not exist.
+    @app.errorhandler(404)
+    async def handle_not_found(error: Exception) -> Any:
+        return await quart.render_template("notfound.html", error="404 Not 
Found", traceback="", status_code=404), 404
+
+    return modules
+
+
 # FIXME: when running in SSL mode, you will receive these exceptions upon 
termination at times:
 #        ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application 
data after close notify (_ssl.c:2706)
 #        related ticket: https://github.com/pgjones/hypercorn/issues/261
diff --git a/atr/ssh.py b/atr/ssh.py
index 2d7c769..8f7f8bd 100644
--- a/atr/ssh.py
+++ b/atr/ssh.py
@@ -294,6 +294,33 @@ def _fail(proc: asyncssh.SSHServerProcess, message: str, 
return_value: T) -> T:
     return return_value
 
 
+async def _handle_client(process: asyncssh.SSHServerProcess) -> None:
+    """Process client command by executing it and redirecting I/O."""
+    asf_uid = process.get_extra_info("username")
+    _LOGGER.info(f"Handling command for authenticated user: {asf_uid}")
+
+    if not process.command:
+        process.stderr.write(b"ATR SSH error: No command specified\n")
+        process.exit(1)
+        return
+
+    _LOGGER.info(f"Command received: {process.command}")
+    argv = process.command.split()
+
+    simple_validation_error, path_index = _command_simple_validate(argv)
+    if simple_validation_error:
+        process.stderr.write(f"ATR SSH error: 
{simple_validation_error}\nCommand: {process.command}\n".encode())
+        process.exit(1)
+        return
+
+    validation_results = await _command_validate(process, argv, path_index)
+    if not validation_results:
+        return
+    project_name, version_name = validation_results
+
+    await _process_validated_rsync(process, argv, path_index, project_name, 
version_name)
+
+
 async def _process_validated_rsync(
     process: asyncssh.SSHServerProcess,
     argv: list[str],
@@ -337,30 +364,3 @@ async def _process_validated_rsync(
         _fail(process, f"Internal error processing revision: {e}", None)
         if not process.is_closing():
             process.exit(1)
-
-
-async def _handle_client(process: asyncssh.SSHServerProcess) -> None:
-    """Process client command by executing it and redirecting I/O."""
-    asf_uid = process.get_extra_info("username")
-    _LOGGER.info(f"Handling command for authenticated user: {asf_uid}")
-
-    if not process.command:
-        process.stderr.write(b"ATR SSH error: No command specified\n")
-        process.exit(1)
-        return
-
-    _LOGGER.info(f"Command received: {process.command}")
-    argv = process.command.split()
-
-    simple_validation_error, path_index = _command_simple_validate(argv)
-    if simple_validation_error:
-        process.stderr.write(f"ATR SSH error: 
{simple_validation_error}\nCommand: {process.command}\n".encode())
-        process.exit(1)
-        return
-
-    validation_results = await _command_validate(process, argv, path_index)
-    if not validation_results:
-        return
-    project_name, version_name = validation_results
-
-    await _process_validated_rsync(process, argv, path_index, project_name, 
version_name)
diff --git a/atr/user.py b/atr/user.py
index 5cc163f..333fd62 100644
--- a/atr/user.py
+++ b/atr/user.py
@@ -47,16 +47,16 @@ def is_admin(user_id: str | None) -> bool:
     return user_id in get_admin_users()
 
 
-def is_committer(committee: models.Committee | None, uid: str) -> bool:
+def is_committee_member(committee: models.Committee | None, uid: str) -> bool:
     if committee is None:
         return False
-    return any((committer_uid == uid) for committer_uid in 
committee.committers)
+    return any((member_uid == uid) for member_uid in 
committee.committee_members)
 
 
-def is_committee_member(committee: models.Committee | None, uid: str) -> bool:
+def is_committer(committee: models.Committee | None, uid: str) -> bool:
     if committee is None:
         return False
-    return any((member_uid == uid) for member_uid in 
committee.committee_members)
+    return any((committer_uid == uid) for committer_uid in 
committee.committers)
 
 
 async def projects(uid: str, committee_only: bool = False) -> 
list[models.Project]:
diff --git a/atr/util.py b/atr/util.py
index ffc0403..6f5b178 100644
--- a/atr/util.py
+++ b/atr/util.py
@@ -236,22 +236,22 @@ def get_phase_dir() -> pathlib.Path:
     return pathlib.Path(config.get().PHASE_STORAGE_DIR)
 
 
-def get_release_candidate_draft_dir() -> pathlib.Path:
-    return pathlib.Path(config.get().PHASE_STORAGE_DIR) / 
"release-candidate-draft"
-
-
 def get_release_candidate_dir() -> pathlib.Path:
     return pathlib.Path(config.get().PHASE_STORAGE_DIR) / "release-candidate"
 
 
-def get_release_preview_dir() -> pathlib.Path:
-    return pathlib.Path(config.get().PHASE_STORAGE_DIR) / "release-preview"
+def get_release_candidate_draft_dir() -> pathlib.Path:
+    return pathlib.Path(config.get().PHASE_STORAGE_DIR) / 
"release-candidate-draft"
 
 
 def get_release_dir() -> pathlib.Path:
     return pathlib.Path(config.get().PHASE_STORAGE_DIR) / "release"
 
 
+def get_release_preview_dir() -> pathlib.Path:
+    return pathlib.Path(config.get().PHASE_STORAGE_DIR) / "release-preview"
+
+
 def is_user_viewing_as_admin(uid: str | None) -> bool:
     """Check whether a user is currently viewing the site with active admin 
privileges."""
     if not user.is_admin(uid):
diff --git a/atr/worker.py b/atr/worker.py
index 4cc55e9..24a2d05 100644
--- a/atr/worker.py
+++ b/atr/worker.py
@@ -174,24 +174,6 @@ async def _task_next_claim() -> tuple[int, str, list[str] 
| dict[str, Any]] | No
             return None
 
 
-async def _task_result_process(
-    task_id: int, task_results: tuple[Any, ...], status: models.TaskStatus, 
error: str | None = None
-) -> None:
-    """Process and store task results in the database."""
-    async with db.session() as data:
-        async with data.begin():
-            # Find the task by ID
-            task_obj = await data.task(id=task_id).get()
-            if task_obj:
-                # Update task properties
-                task_obj.status = status
-                task_obj.completed = datetime.datetime.now(datetime.UTC)
-                task_obj.result = task_results
-
-                if (status == task.FAILED) and error:
-                    task_obj.error = error
-
-
 async def _task_process(task_id: int, task_type: str, task_args: list[str] | 
dict[str, Any]) -> None:
     """Process a claimed task."""
     _LOGGER.info(f"Processing task {task_id} ({task_type}) with raw args 
{task_args}")
@@ -261,6 +243,24 @@ async def _task_process(task_id: int, task_type: str, 
task_args: list[str] | dic
     await _task_result_process(task_id, task_results, status, error)
 
 
+async def _task_result_process(
+    task_id: int, task_results: tuple[Any, ...], status: models.TaskStatus, 
error: str | None = None
+) -> None:
+    """Process and store task results in the database."""
+    async with db.session() as data:
+        async with data.begin():
+            # Find the task by ID
+            task_obj = await data.task(id=task_id).get()
+            if task_obj:
+                # Update task properties
+                task_obj.status = status
+                task_obj.completed = datetime.datetime.now(datetime.UTC)
+                task_obj.result = task_results
+
+                if (status == task.FAILED) and error:
+                    task_obj.error = error
+
+
 # Worker functions
 
 
diff --git a/scripts/interface_order.py b/scripts/interface_order.py
index 332bab4..c288847 100644
--- a/scripts/interface_order.py
+++ b/scripts/interface_order.py
@@ -16,8 +16,8 @@ class ExitCode(enum.IntEnum):
 def _extract_top_level_function_names(tree: ast.Module) -> list[str]:
     function_names: list[str] = []
     for node in tree.body:
-        if isinstance(node, ast.FunctionDef):
-            function_names.append(node.name)
+        if isinstance(node, ast.AsyncFunctionDef) or isinstance(node, 
ast.FunctionDef):
+            function_names.append(_toggle_sortability(node.name))
     return function_names
 
 
@@ -40,6 +40,13 @@ def _read_file_content(file_path: pathlib.Path) -> str | 
None:
         return None
 
 
+def _toggle_sortability(name: str) -> str:
+    if name.startswith("_"):
+        return name[1:]
+    else:
+        return "_" + name
+
+
 def _verify_names_are_sorted(names: Sequence[str], filename: str) -> bool:
     is_sorted = all(names[i] <= names[i + 1] for i in range(len(names) - 1))
     if is_sorted:
@@ -47,8 +54,10 @@ def _verify_names_are_sorted(names: Sequence[str], filename: 
str) -> bool:
 
     for i in range(len(names) - 1):
         if names[i] > names[i + 1]:
+            a = _toggle_sortability(names[i])
+            b = _toggle_sortability(names[i + 1])
             print(
-                f"Error: Function '{names[i + 1]}' in {filename} is not 
ordered correctly relative to '{names[i]}'",
+                f"Error: Function '{b}' in {filename} is not ordered correctly 
relative to '{a}'",
                 file=sys.stderr,
             )
     return False
@@ -72,11 +81,11 @@ def main() -> None:
     function_names = _extract_top_level_function_names(tree)
 
     if not function_names:
-        print(f"No top-level functions found in {file_path}. Nothing to check")
+        print(f"No top level functions found in {file_path}. Nothing to check")
         sys.exit(ExitCode.SUCCESS)
 
     if _verify_names_are_sorted(function_names, str(file_path)):
-        print(f"Top-level functions in {file_path} are alphabetically ordered")
+        print(f"Top level functions in {file_path} are alphabetically ordered")
         sys.exit(ExitCode.SUCCESS)
     else:
         sys.exit(ExitCode.FAILURE)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to