appinfra 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- appinfra-0.1.0/.claude/commands/grade-framework.md +744 -0
- appinfra-0.1.0/.github/workflows/release.yml +91 -0
- appinfra-0.1.0/.github/workflows/test-docker.yml +72 -0
- appinfra-0.1.0/.github/workflows/test-native.yml +59 -0
- appinfra-0.1.0/.gitignore +30 -0
- appinfra-0.1.0/CHANGELOG.md +37 -0
- appinfra-0.1.0/CONTRIBUTING.md +295 -0
- appinfra-0.1.0/LICENSE +201 -0
- appinfra-0.1.0/Makefile +42 -0
- appinfra-0.1.0/PKG-INFO +43 -0
- appinfra-0.1.0/README.md +457 -0
- appinfra-0.1.0/SECURITY.md +641 -0
- appinfra-0.1.0/appinfra/__init__.py +112 -0
- appinfra-0.1.0/appinfra/_build_info.py +8 -0
- appinfra-0.1.0/appinfra/app/__init__.py +128 -0
- appinfra-0.1.0/appinfra/app/args.py +37 -0
- appinfra-0.1.0/appinfra/app/builder/__init__.py +52 -0
- appinfra-0.1.0/appinfra/app/builder/app.py +738 -0
- appinfra-0.1.0/appinfra/app/builder/config.py +315 -0
- appinfra-0.1.0/appinfra/app/builder/configurer/__init__.py +20 -0
- appinfra-0.1.0/appinfra/app/builder/configurer/advanced.py +115 -0
- appinfra-0.1.0/appinfra/app/builder/configurer/logging.py +286 -0
- appinfra-0.1.0/appinfra/app/builder/configurer/server.py +164 -0
- appinfra-0.1.0/appinfra/app/builder/configurer/tool.py +135 -0
- appinfra-0.1.0/appinfra/app/builder/configurer/version.py +202 -0
- appinfra-0.1.0/appinfra/app/builder/hook.py +338 -0
- appinfra-0.1.0/appinfra/app/builder/middleware.py +286 -0
- appinfra-0.1.0/appinfra/app/builder/plugin.py +262 -0
- appinfra-0.1.0/appinfra/app/builder/tool.py +267 -0
- appinfra-0.1.0/appinfra/app/builder/validation.py +374 -0
- appinfra-0.1.0/appinfra/app/cli/__init__.py +14 -0
- appinfra-0.1.0/appinfra/app/cli/commands.py +91 -0
- appinfra-0.1.0/appinfra/app/cli/help.py +93 -0
- appinfra-0.1.0/appinfra/app/cli/parser.py +68 -0
- appinfra-0.1.0/appinfra/app/constants.py +14 -0
- appinfra-0.1.0/appinfra/app/core/__init__.py +21 -0
- appinfra-0.1.0/appinfra/app/core/app.py +692 -0
- appinfra-0.1.0/appinfra/app/core/config.py +317 -0
- appinfra-0.1.0/appinfra/app/core/lifecycle.py +479 -0
- appinfra-0.1.0/appinfra/app/core/logging_utils.py +335 -0
- appinfra-0.1.0/appinfra/app/core/shutdown.py +75 -0
- appinfra-0.1.0/appinfra/app/decorators.py +600 -0
- appinfra-0.1.0/appinfra/app/decorators.pyi +172 -0
- appinfra-0.1.0/appinfra/app/docs/__init__.py +23 -0
- appinfra-0.1.0/appinfra/app/docs/generator.py +325 -0
- appinfra-0.1.0/appinfra/app/errors.py +125 -0
- appinfra-0.1.0/appinfra/app/fastapi/__init__.py +130 -0
- appinfra-0.1.0/appinfra/app/fastapi/builder/__init__.py +7 -0
- appinfra-0.1.0/appinfra/app/fastapi/builder/route.py +191 -0
- appinfra-0.1.0/appinfra/app/fastapi/builder/server.py +229 -0
- appinfra-0.1.0/appinfra/app/fastapi/builder/subprocess.py +189 -0
- appinfra-0.1.0/appinfra/app/fastapi/builder/uvicorn.py +95 -0
- appinfra-0.1.0/appinfra/app/fastapi/config/__init__.py +11 -0
- appinfra-0.1.0/appinfra/app/fastapi/config/api.py +54 -0
- appinfra-0.1.0/appinfra/app/fastapi/config/ipc.py +31 -0
- appinfra-0.1.0/appinfra/app/fastapi/config/uvicorn.py +64 -0
- appinfra-0.1.0/appinfra/app/fastapi/plugin.py +156 -0
- appinfra-0.1.0/appinfra/app/fastapi/runtime/__init__.py +11 -0
- appinfra-0.1.0/appinfra/app/fastapi/runtime/adapter.py +230 -0
- appinfra-0.1.0/appinfra/app/fastapi/runtime/ipc.py +278 -0
- appinfra-0.1.0/appinfra/app/fastapi/runtime/logging.py +78 -0
- appinfra-0.1.0/appinfra/app/fastapi/runtime/server.py +297 -0
- appinfra-0.1.0/appinfra/app/fastapi/runtime/subprocess.py +247 -0
- appinfra-0.1.0/appinfra/app/server/__init__.py +31 -0
- appinfra-0.1.0/appinfra/app/server/base.py +251 -0
- appinfra-0.1.0/appinfra/app/server/handlers.py +152 -0
- appinfra-0.1.0/appinfra/app/server/routes.py +116 -0
- appinfra-0.1.0/appinfra/app/testing.py +71 -0
- appinfra-0.1.0/appinfra/app/tools/__init__.py +14 -0
- appinfra-0.1.0/appinfra/app/tools/base.py +347 -0
- appinfra-0.1.0/appinfra/app/tools/group.py +190 -0
- appinfra-0.1.0/appinfra/app/tools/protocol.py +128 -0
- appinfra-0.1.0/appinfra/app/tools/registry.py +143 -0
- appinfra-0.1.0/appinfra/app/tracing/__init__.py +10 -0
- appinfra-0.1.0/appinfra/app/tracing/traceable.py +176 -0
- appinfra-0.1.0/appinfra/app/utils.py +4 -0
- appinfra-0.1.0/appinfra/cli/__init__.py +14 -0
- appinfra-0.1.0/appinfra/cli/cli.py +73 -0
- appinfra-0.1.0/appinfra/cli/output.py +142 -0
- appinfra-0.1.0/appinfra/cli/tools/__init__.py +0 -0
- appinfra-0.1.0/appinfra/cli/tools/check_functions.py +816 -0
- appinfra-0.1.0/appinfra/cli/tools/code_quality.py +67 -0
- appinfra-0.1.0/appinfra/cli/tools/completion_tool.py +266 -0
- appinfra-0.1.0/appinfra/cli/tools/config_tool.py +185 -0
- appinfra-0.1.0/appinfra/cli/tools/docs_tool.py +791 -0
- appinfra-0.1.0/appinfra/cli/tools/doctor_tool.py +360 -0
- appinfra-0.1.0/appinfra/cli/tools/etc_path_tool.py +59 -0
- appinfra-0.1.0/appinfra/cli/tools/scaffold/Makefile.framework.in +46 -0
- appinfra-0.1.0/appinfra/cli/tools/scaffold/Makefile.standalone.in +70 -0
- appinfra-0.1.0/appinfra/cli/tools/scaffold/__init__.py +0 -0
- appinfra-0.1.0/appinfra/cli/tools/scaffold_tool.py +494 -0
- appinfra-0.1.0/appinfra/cli/tools/scripts_path_tool.py +33 -0
- appinfra-0.1.0/appinfra/cli/tools/version_tool.py +230 -0
- appinfra-0.1.0/appinfra/config/__init__.py +67 -0
- appinfra-0.1.0/appinfra/config/config.py +761 -0
- appinfra-0.1.0/appinfra/config/constants.py +6 -0
- appinfra-0.1.0/appinfra/config/schemas.py +209 -0
- appinfra-0.1.0/appinfra/config/watcher.py +361 -0
- appinfra-0.1.0/appinfra/db/README.md +354 -0
- appinfra-0.1.0/appinfra/db/__init__.py +11 -0
- appinfra-0.1.0/appinfra/db/db.py +275 -0
- appinfra-0.1.0/appinfra/db/pg/__init__.py +4 -0
- appinfra-0.1.0/appinfra/db/pg/connection.py +185 -0
- appinfra-0.1.0/appinfra/db/pg/core.py +264 -0
- appinfra-0.1.0/appinfra/db/pg/interface.py +78 -0
- appinfra-0.1.0/appinfra/db/pg/pg.py +270 -0
- appinfra-0.1.0/appinfra/db/pg/reconnection.py +158 -0
- appinfra-0.1.0/appinfra/db/pg/session.py +153 -0
- appinfra-0.1.0/appinfra/deprecation.py +60 -0
- appinfra-0.1.0/appinfra/dict.py +118 -0
- appinfra-0.1.0/appinfra/docs/README.md +248 -0
- appinfra-0.1.0/appinfra/docs/api/app-builder.md +249 -0
- appinfra-0.1.0/appinfra/docs/api/app.md +206 -0
- appinfra-0.1.0/appinfra/docs/api/database.md +143 -0
- appinfra-0.1.0/appinfra/docs/api/exceptions.md +109 -0
- appinfra-0.1.0/appinfra/docs/api/fastapi.md +497 -0
- appinfra-0.1.0/appinfra/docs/api/index.md +156 -0
- appinfra-0.1.0/appinfra/docs/api/logging.md +295 -0
- appinfra-0.1.0/appinfra/docs/api/time.md +321 -0
- appinfra-0.1.0/appinfra/docs/api/ui.md +251 -0
- appinfra-0.1.0/appinfra/docs/api/utilities.md +314 -0
- appinfra-0.1.0/appinfra/docs/api/version.md +301 -0
- appinfra-0.1.0/appinfra/docs/getting-started.md +502 -0
- appinfra-0.1.0/appinfra/docs/guides/api-stability.md +168 -0
- appinfra-0.1.0/appinfra/docs/guides/config-based-logging.md +68 -0
- appinfra-0.1.0/appinfra/docs/guides/contributing.md +295 -0
- appinfra-0.1.0/appinfra/docs/guides/coverage-targets.md +62 -0
- appinfra-0.1.0/appinfra/docs/guides/environment-variables.md +331 -0
- appinfra-0.1.0/appinfra/docs/guides/framework-integration.md +264 -0
- appinfra-0.1.0/appinfra/docs/guides/hot-reload-logging.md +431 -0
- appinfra-0.1.0/appinfra/docs/guides/logging-builder.md +196 -0
- appinfra-0.1.0/appinfra/docs/guides/makefile-customization.md +897 -0
- appinfra-0.1.0/appinfra/docs/guides/pg-test-helper.md +86 -0
- appinfra-0.1.0/appinfra/docs/guides/test-naming-standards.md +344 -0
- appinfra-0.1.0/appinfra/docs/guides/virtual-environment.md +73 -0
- appinfra-0.1.0/appinfra/docs/index.md +54 -0
- appinfra-0.1.0/appinfra/dot_dict.py +328 -0
- appinfra-0.1.0/appinfra/etc/README.md +709 -0
- appinfra-0.1.0/appinfra/etc/fastapi.yaml +69 -0
- appinfra-0.1.0/appinfra/etc/infra.yaml +39 -0
- appinfra-0.1.0/appinfra/etc/lg.yaml +63 -0
- appinfra-0.1.0/appinfra/etc/mkdocs.yaml +86 -0
- appinfra-0.1.0/appinfra/etc/pg.yaml +81 -0
- appinfra-0.1.0/appinfra/ewma.py +85 -0
- appinfra-0.1.0/appinfra/examples/01_basics/README.md +57 -0
- appinfra-0.1.0/appinfra/examples/01_basics/hello_world.py +57 -0
- appinfra-0.1.0/appinfra/examples/01_basics/hello_world_with_cfg.py +85 -0
- appinfra-0.1.0/appinfra/examples/02_app_framework/README.md +125 -0
- appinfra-0.1.0/appinfra/examples/02_app_framework/app_with_commands.py +58 -0
- appinfra-0.1.0/appinfra/examples/02_app_framework/app_with_subtools.py +108 -0
- appinfra-0.1.0/appinfra/examples/02_app_framework/app_with_ticker.py +92 -0
- appinfra-0.1.0/appinfra/examples/02_app_framework/app_with_tool.py +64 -0
- appinfra-0.1.0/appinfra/examples/02_app_framework/app_with_tool_builders.py +109 -0
- appinfra-0.1.0/appinfra/examples/03_logging/README.md +185 -0
- appinfra-0.1.0/appinfra/examples/03_logging/database_logging.py +677 -0
- appinfra-0.1.0/appinfra/examples/03_logging/disabled_logging_example.py +253 -0
- appinfra-0.1.0/appinfra/examples/03_logging/location_color_example.py +241 -0
- appinfra-0.1.0/appinfra/examples/03_logging/logging_builder_example.py +628 -0
- appinfra-0.1.0/appinfra/examples/03_logging/topic_logging_config.yaml +80 -0
- appinfra-0.1.0/appinfra/examples/03_logging/topic_logging_example.py +341 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/README.md +216 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/env_overrides_example.py +357 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/01_basic_database.yaml +6 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/01_basic_main.yaml +6 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/02_nested_level1.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/02_nested_level2.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/02_nested_level3.yaml +3 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/02_nested_main.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/03_variables_databases.yaml +8 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/03_variables_main.yaml +10 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/04_multiple_cache.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/04_multiple_database.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/04_multiple_logging.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/04_multiple_main.yaml +8 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/05_organized_main.yaml +7 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/06_env_dev.yaml +5 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/06_env_prod.yaml +5 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/07_circular_a.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/07_circular_b.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/common.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/database/config.yaml +5 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/database/connection.yaml +5 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/database/pool.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/env/dev/database.yaml +6 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/env/prod/database.yaml +6 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/hot_reload.yaml +22 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/logging/config.yaml +4 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/etc/logging/handlers.yaml +9 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/hot_reload_example.py +166 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/tool_config_access.py +174 -0
- appinfra-0.1.0/appinfra/examples/04_configuration/yaml_include_example.py +364 -0
- appinfra-0.1.0/appinfra/examples/05_database/README.md +216 -0
- appinfra-0.1.0/appinfra/examples/05_database/advanced_critical_flush.py +330 -0
- appinfra-0.1.0/appinfra/examples/05_database/basic_critical_flush_example.py +262 -0
- appinfra-0.1.0/appinfra/examples/05_database/pg_test_helper_custom_config.py +266 -0
- appinfra-0.1.0/appinfra/examples/05_database/pg_test_helper_example.py +806 -0
- appinfra-0.1.0/appinfra/examples/06_advanced/README.md +217 -0
- appinfra-0.1.0/appinfra/examples/06_advanced/generator_usage_example.py +128 -0
- appinfra-0.1.0/appinfra/examples/06_advanced/graceful_shutdown_demo.py +225 -0
- appinfra-0.1.0/appinfra/examples/06_advanced/tcp_server.py +112 -0
- appinfra-0.1.0/appinfra/examples/06_advanced/ticker_standalone.py +42 -0
- appinfra-0.1.0/appinfra/examples/07_fastapi/fastapi_server.py +249 -0
- appinfra-0.1.0/appinfra/examples/08_decorators/README.md +285 -0
- appinfra-0.1.0/appinfra/examples/08_decorators/hierarchical_commands.py +105 -0
- appinfra-0.1.0/appinfra/examples/08_decorators/mixed_approach.py +212 -0
- appinfra-0.1.0/appinfra/examples/08_decorators/simple_decorator.py +70 -0
- appinfra-0.1.0/appinfra/examples/09_ui/README.md +69 -0
- appinfra-0.1.0/appinfra/examples/09_ui/deploy_tool.py +329 -0
- appinfra-0.1.0/appinfra/examples/09_ui/interactive_prompts.py +225 -0
- appinfra-0.1.0/appinfra/examples/09_ui/progress_logger_example.py +203 -0
- appinfra-0.1.0/appinfra/examples/09_ui/rich_output.py +138 -0
- appinfra-0.1.0/appinfra/examples/09_ui/scrollable_selection.py +147 -0
- appinfra-0.1.0/appinfra/examples/09_ui/secret_masking.py +206 -0
- appinfra-0.1.0/appinfra/examples/09_ui/spinners_and_progress.py +678 -0
- appinfra-0.1.0/appinfra/examples/10_plugins/README.md +100 -0
- appinfra-0.1.0/appinfra/examples/10_plugins/example_plugins.py +205 -0
- appinfra-0.1.0/appinfra/examples/11_docs/docs_generation.py +239 -0
- appinfra-0.1.0/appinfra/examples/12_version_tracking/README.md +113 -0
- appinfra-0.1.0/appinfra/examples/12_version_tracking/standalone_tracker.py +66 -0
- appinfra-0.1.0/appinfra/examples/12_version_tracking/version_tracking_demo.py +120 -0
- appinfra-0.1.0/appinfra/examples/README.md +185 -0
- appinfra-0.1.0/appinfra/exceptions.py +172 -0
- appinfra-0.1.0/appinfra/log/__init__.py +346 -0
- appinfra-0.1.0/appinfra/log/builder/__init__.py +91 -0
- appinfra-0.1.0/appinfra/log/builder/builder.py +358 -0
- appinfra-0.1.0/appinfra/log/builder/console.py +159 -0
- appinfra-0.1.0/appinfra/log/builder/database/__init__.py +24 -0
- appinfra-0.1.0/appinfra/log/builder/database/builder.py +375 -0
- appinfra-0.1.0/appinfra/log/builder/database/config.py +154 -0
- appinfra-0.1.0/appinfra/log/builder/database/handler.py +216 -0
- appinfra-0.1.0/appinfra/log/builder/file.py +301 -0
- appinfra-0.1.0/appinfra/log/builder/interface.py +236 -0
- appinfra-0.1.0/appinfra/log/builder/json.py +533 -0
- appinfra-0.1.0/appinfra/log/builder/quick.py +439 -0
- appinfra-0.1.0/appinfra/log/callback.py +196 -0
- appinfra-0.1.0/appinfra/log/colors.py +184 -0
- appinfra-0.1.0/appinfra/log/config.py +170 -0
- appinfra-0.1.0/appinfra/log/config_holder.py +138 -0
- appinfra-0.1.0/appinfra/log/constants.py +44 -0
- appinfra-0.1.0/appinfra/log/exceptions.py +40 -0
- appinfra-0.1.0/appinfra/log/factory.py +355 -0
- appinfra-0.1.0/appinfra/log/formatters.py +508 -0
- appinfra-0.1.0/appinfra/log/handler_factory.py +504 -0
- appinfra-0.1.0/appinfra/log/level_manager.py +436 -0
- appinfra-0.1.0/appinfra/log/logger.py +340 -0
- appinfra-0.1.0/appinfra/log/reloader.py +116 -0
- appinfra-0.1.0/appinfra/net/README.md +283 -0
- appinfra-0.1.0/appinfra/net/__init__.py +21 -0
- appinfra-0.1.0/appinfra/net/exceptions.py +30 -0
- appinfra-0.1.0/appinfra/net/http.py +114 -0
- appinfra-0.1.0/appinfra/net/tcp.py +351 -0
- appinfra-0.1.0/appinfra/observability/__init__.py +10 -0
- appinfra-0.1.0/appinfra/observability/hooks.py +261 -0
- appinfra-0.1.0/appinfra/rate_limit.py +62 -0
- appinfra-0.1.0/appinfra/regex_utils.py +264 -0
- appinfra-0.1.0/appinfra/scripts/check.sh +573 -0
- appinfra-0.1.0/appinfra/scripts/cicd-test.sh +101 -0
- appinfra-0.1.0/appinfra/scripts/docker/pg/docker-compose.repl.yaml +76 -0
- appinfra-0.1.0/appinfra/scripts/docker/pg/docker-compose.single.yaml +24 -0
- appinfra-0.1.0/appinfra/scripts/docker/pg/pg_hba.conf +13 -0
- appinfra-0.1.0/appinfra/scripts/docs-config.sh +63 -0
- appinfra-0.1.0/appinfra/scripts/install_deps.py +15 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.all +40 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.cicd +57 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.clean +53 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.config +184 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.dev +201 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.docs +37 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.env +109 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.help +59 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.install +60 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.pg +215 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.pytest +167 -0
- appinfra-0.1.0/appinfra/scripts/make/Makefile.utils +15 -0
- appinfra-0.1.0/appinfra/scripts/pg-config.sh +52 -0
- appinfra-0.1.0/appinfra/scripts/pg-info.sh +162 -0
- appinfra-0.1.0/appinfra/scripts/type-hint.sh +50 -0
- appinfra-0.1.0/appinfra/scripts/yaml2json.sh +5 -0
- appinfra-0.1.0/appinfra/security/__init__.py +35 -0
- appinfra-0.1.0/appinfra/security/filter.py +125 -0
- appinfra-0.1.0/appinfra/security/masking.py +232 -0
- appinfra-0.1.0/appinfra/security/patterns.py +96 -0
- appinfra-0.1.0/appinfra/size.py +286 -0
- appinfra-0.1.0/appinfra/subprocess/__init__.py +9 -0
- appinfra-0.1.0/appinfra/subprocess/context.py +137 -0
- appinfra-0.1.0/appinfra/time/README.md +256 -0
- appinfra-0.1.0/appinfra/time/__init__.py +74 -0
- appinfra-0.1.0/appinfra/time/date_range.py +162 -0
- appinfra-0.1.0/appinfra/time/delta.py +518 -0
- appinfra-0.1.0/appinfra/time/eta.py +113 -0
- appinfra-0.1.0/appinfra/time/sched.py +614 -0
- appinfra-0.1.0/appinfra/time/ticker.py +507 -0
- appinfra-0.1.0/appinfra/time/time.py +291 -0
- appinfra-0.1.0/appinfra/ui/__init__.py +88 -0
- appinfra-0.1.0/appinfra/ui/console.py +291 -0
- appinfra-0.1.0/appinfra/ui/fallback.py +219 -0
- appinfra-0.1.0/appinfra/ui/help.py +202 -0
- appinfra-0.1.0/appinfra/ui/progress_logger.py +323 -0
- appinfra-0.1.0/appinfra/ui/prompts.py +707 -0
- appinfra-0.1.0/appinfra/utils.py +40 -0
- appinfra-0.1.0/appinfra/version/__init__.py +48 -0
- appinfra-0.1.0/appinfra/version/actions.py +131 -0
- appinfra-0.1.0/appinfra/version/build_info.py +112 -0
- appinfra-0.1.0/appinfra/version/info.py +353 -0
- appinfra-0.1.0/appinfra/version/setup_hook.py +287 -0
- appinfra-0.1.0/appinfra/version/setuptools_hook.py +111 -0
- appinfra-0.1.0/appinfra/version/sources.py +371 -0
- appinfra-0.1.0/appinfra/version/tracker.py +159 -0
- appinfra-0.1.0/appinfra/yaml.py +1017 -0
- appinfra-0.1.0/appinfra.egg-info/PKG-INFO +43 -0
- appinfra-0.1.0/appinfra.egg-info/SOURCES.txt +645 -0
- appinfra-0.1.0/appinfra.egg-info/dependency_links.txt +1 -0
- appinfra-0.1.0/appinfra.egg-info/entry_points.txt +5 -0
- appinfra-0.1.0/appinfra.egg-info/requires.txt +38 -0
- appinfra-0.1.0/appinfra.egg-info/top_level.txt +1 -0
- appinfra-0.1.0/docs/LICENSE +201 -0
- appinfra-0.1.0/docs/README.md +248 -0
- appinfra-0.1.0/docs/SECURITY.md +641 -0
- appinfra-0.1.0/docs/api/app-builder.md +249 -0
- appinfra-0.1.0/docs/api/app.md +206 -0
- appinfra-0.1.0/docs/api/database.md +143 -0
- appinfra-0.1.0/docs/api/exceptions.md +109 -0
- appinfra-0.1.0/docs/api/fastapi.md +497 -0
- appinfra-0.1.0/docs/api/index.md +156 -0
- appinfra-0.1.0/docs/api/logging.md +295 -0
- appinfra-0.1.0/docs/api/time.md +321 -0
- appinfra-0.1.0/docs/api/ui.md +251 -0
- appinfra-0.1.0/docs/api/utilities.md +314 -0
- appinfra-0.1.0/docs/api/version.md +301 -0
- appinfra-0.1.0/docs/getting-started.md +502 -0
- appinfra-0.1.0/docs/guides/api-stability.md +168 -0
- appinfra-0.1.0/docs/guides/config-based-logging.md +68 -0
- appinfra-0.1.0/docs/guides/contributing.md +295 -0
- appinfra-0.1.0/docs/guides/coverage-targets.md +62 -0
- appinfra-0.1.0/docs/guides/environment-variables.md +331 -0
- appinfra-0.1.0/docs/guides/framework-integration.md +264 -0
- appinfra-0.1.0/docs/guides/hot-reload-logging.md +431 -0
- appinfra-0.1.0/docs/guides/logging-builder.md +196 -0
- appinfra-0.1.0/docs/guides/makefile-customization.md +897 -0
- appinfra-0.1.0/docs/guides/pg-test-helper.md +86 -0
- appinfra-0.1.0/docs/guides/test-naming-standards.md +344 -0
- appinfra-0.1.0/docs/guides/virtual-environment.md +73 -0
- appinfra-0.1.0/docs/index.md +54 -0
- appinfra-0.1.0/etc/README.md +709 -0
- appinfra-0.1.0/etc/fastapi.yaml +69 -0
- appinfra-0.1.0/etc/infra.yaml +39 -0
- appinfra-0.1.0/etc/lg.yaml +63 -0
- appinfra-0.1.0/etc/mkdocs.yaml +86 -0
- appinfra-0.1.0/etc/pg.yaml +81 -0
- appinfra-0.1.0/examples/01_basics/README.md +57 -0
- appinfra-0.1.0/examples/01_basics/hello_world.py +57 -0
- appinfra-0.1.0/examples/01_basics/hello_world_with_cfg.py +85 -0
- appinfra-0.1.0/examples/02_app_framework/README.md +125 -0
- appinfra-0.1.0/examples/02_app_framework/app_with_commands.py +58 -0
- appinfra-0.1.0/examples/02_app_framework/app_with_subtools.py +108 -0
- appinfra-0.1.0/examples/02_app_framework/app_with_ticker.py +92 -0
- appinfra-0.1.0/examples/02_app_framework/app_with_tool.py +64 -0
- appinfra-0.1.0/examples/02_app_framework/app_with_tool_builders.py +109 -0
- appinfra-0.1.0/examples/02a_app_using_framework/Makefile +84 -0
- appinfra-0.1.0/examples/03_logging/README.md +185 -0
- appinfra-0.1.0/examples/03_logging/database_logging.py +677 -0
- appinfra-0.1.0/examples/03_logging/disabled_logging_example.py +253 -0
- appinfra-0.1.0/examples/03_logging/location_color_example.py +241 -0
- appinfra-0.1.0/examples/03_logging/logging_builder_example.py +628 -0
- appinfra-0.1.0/examples/03_logging/topic_logging_config.yaml +80 -0
- appinfra-0.1.0/examples/03_logging/topic_logging_example.py +341 -0
- appinfra-0.1.0/examples/04_configuration/README.md +216 -0
- appinfra-0.1.0/examples/04_configuration/env_overrides_example.py +357 -0
- appinfra-0.1.0/examples/04_configuration/etc/01_basic_database.yaml +6 -0
- appinfra-0.1.0/examples/04_configuration/etc/01_basic_main.yaml +6 -0
- appinfra-0.1.0/examples/04_configuration/etc/02_nested_level1.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/02_nested_level2.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/02_nested_level3.yaml +3 -0
- appinfra-0.1.0/examples/04_configuration/etc/02_nested_main.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/03_variables_databases.yaml +8 -0
- appinfra-0.1.0/examples/04_configuration/etc/03_variables_main.yaml +10 -0
- appinfra-0.1.0/examples/04_configuration/etc/04_multiple_cache.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/04_multiple_database.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/04_multiple_logging.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/04_multiple_main.yaml +8 -0
- appinfra-0.1.0/examples/04_configuration/etc/05_organized_main.yaml +7 -0
- appinfra-0.1.0/examples/04_configuration/etc/06_env_dev.yaml +5 -0
- appinfra-0.1.0/examples/04_configuration/etc/06_env_prod.yaml +5 -0
- appinfra-0.1.0/examples/04_configuration/etc/07_circular_a.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/07_circular_b.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/common.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/database/config.yaml +5 -0
- appinfra-0.1.0/examples/04_configuration/etc/database/connection.yaml +5 -0
- appinfra-0.1.0/examples/04_configuration/etc/database/pool.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/env/dev/database.yaml +6 -0
- appinfra-0.1.0/examples/04_configuration/etc/env/prod/database.yaml +6 -0
- appinfra-0.1.0/examples/04_configuration/etc/hot_reload.yaml +22 -0
- appinfra-0.1.0/examples/04_configuration/etc/logging/config.yaml +4 -0
- appinfra-0.1.0/examples/04_configuration/etc/logging/handlers.yaml +9 -0
- appinfra-0.1.0/examples/04_configuration/hot_reload_example.py +166 -0
- appinfra-0.1.0/examples/04_configuration/tool_config_access.py +174 -0
- appinfra-0.1.0/examples/04_configuration/yaml_include_example.py +364 -0
- appinfra-0.1.0/examples/05_database/README.md +216 -0
- appinfra-0.1.0/examples/05_database/advanced_critical_flush.py +330 -0
- appinfra-0.1.0/examples/05_database/basic_critical_flush_example.py +262 -0
- appinfra-0.1.0/examples/05_database/pg_test_helper_custom_config.py +266 -0
- appinfra-0.1.0/examples/05_database/pg_test_helper_example.py +806 -0
- appinfra-0.1.0/examples/06_advanced/README.md +217 -0
- appinfra-0.1.0/examples/06_advanced/generator_usage_example.py +128 -0
- appinfra-0.1.0/examples/06_advanced/graceful_shutdown_demo.py +225 -0
- appinfra-0.1.0/examples/06_advanced/tcp_server.py +112 -0
- appinfra-0.1.0/examples/06_advanced/ticker_standalone.py +42 -0
- appinfra-0.1.0/examples/07_fastapi/fastapi_server.py +249 -0
- appinfra-0.1.0/examples/08_decorators/README.md +285 -0
- appinfra-0.1.0/examples/08_decorators/hierarchical_commands.py +105 -0
- appinfra-0.1.0/examples/08_decorators/mixed_approach.py +212 -0
- appinfra-0.1.0/examples/08_decorators/simple_decorator.py +70 -0
- appinfra-0.1.0/examples/09_ui/README.md +69 -0
- appinfra-0.1.0/examples/09_ui/deploy_tool.py +329 -0
- appinfra-0.1.0/examples/09_ui/interactive_prompts.py +225 -0
- appinfra-0.1.0/examples/09_ui/progress_logger_example.py +203 -0
- appinfra-0.1.0/examples/09_ui/rich_output.py +138 -0
- appinfra-0.1.0/examples/09_ui/scrollable_selection.py +147 -0
- appinfra-0.1.0/examples/09_ui/secret_masking.py +206 -0
- appinfra-0.1.0/examples/09_ui/spinners_and_progress.py +678 -0
- appinfra-0.1.0/examples/10_plugins/README.md +100 -0
- appinfra-0.1.0/examples/10_plugins/example_plugins.py +205 -0
- appinfra-0.1.0/examples/11_docs/docs_generation.py +239 -0
- appinfra-0.1.0/examples/12_version_tracking/README.md +113 -0
- appinfra-0.1.0/examples/12_version_tracking/standalone_tracker.py +66 -0
- appinfra-0.1.0/examples/12_version_tracking/version_tracking_demo.py +120 -0
- appinfra-0.1.0/examples/README.md +185 -0
- appinfra-0.1.0/pyproject.toml +193 -0
- appinfra-0.1.0/scripts/check.sh +573 -0
- appinfra-0.1.0/scripts/cicd/.env.local.example +18 -0
- appinfra-0.1.0/scripts/cicd/.env.test +25 -0
- appinfra-0.1.0/scripts/cicd/DOCKER_DEVELOPMENT.md +430 -0
- appinfra-0.1.0/scripts/cicd/Dockerfile +88 -0
- appinfra-0.1.0/scripts/cicd/docker-compose.override.py3.11.yml +12 -0
- appinfra-0.1.0/scripts/cicd/docker-compose.override.py3.12.yml +12 -0
- appinfra-0.1.0/scripts/cicd/docker-compose.override.py3.13.yml +12 -0
- appinfra-0.1.0/scripts/cicd/docker-compose.yml +88 -0
- appinfra-0.1.0/scripts/cicd-test.sh +101 -0
- appinfra-0.1.0/scripts/docker/pg/docker-compose.repl.yaml +76 -0
- appinfra-0.1.0/scripts/docker/pg/docker-compose.single.yaml +24 -0
- appinfra-0.1.0/scripts/docker/pg/pg_hba.conf +13 -0
- appinfra-0.1.0/scripts/docs-config.sh +63 -0
- appinfra-0.1.0/scripts/install_deps.py +15 -0
- appinfra-0.1.0/scripts/make/Makefile.all +40 -0
- appinfra-0.1.0/scripts/make/Makefile.cicd +57 -0
- appinfra-0.1.0/scripts/make/Makefile.clean +53 -0
- appinfra-0.1.0/scripts/make/Makefile.config +184 -0
- appinfra-0.1.0/scripts/make/Makefile.dev +201 -0
- appinfra-0.1.0/scripts/make/Makefile.docs +37 -0
- appinfra-0.1.0/scripts/make/Makefile.env +109 -0
- appinfra-0.1.0/scripts/make/Makefile.help +59 -0
- appinfra-0.1.0/scripts/make/Makefile.install +60 -0
- appinfra-0.1.0/scripts/make/Makefile.pg +215 -0
- appinfra-0.1.0/scripts/make/Makefile.pytest +167 -0
- appinfra-0.1.0/scripts/make/Makefile.utils +15 -0
- appinfra-0.1.0/scripts/pg-config.sh +52 -0
- appinfra-0.1.0/scripts/pg-info.sh +162 -0
- appinfra-0.1.0/scripts/type-hint.sh +50 -0
- appinfra-0.1.0/scripts/yaml2json.sh +5 -0
- appinfra-0.1.0/setup.cfg +7 -0
- appinfra-0.1.0/setup.py +104 -0
- appinfra-0.1.0/tests/cli/conftest.py +9 -0
- appinfra-0.1.0/tests/cli/test_cli.py +133 -0
- appinfra-0.1.0/tests/cli/test_completion_tool.py +143 -0
- appinfra-0.1.0/tests/cli/test_doctor_tool.py +385 -0
- appinfra-0.1.0/tests/cli/test_output.py +185 -0
- appinfra-0.1.0/tests/cli/tools/test_check_code.py +89 -0
- appinfra-0.1.0/tests/cli/tools/test_check_functions.py +1327 -0
- appinfra-0.1.0/tests/cli/tools/test_config_tool.py +650 -0
- appinfra-0.1.0/tests/cli/tools/test_docs_tool.py +1119 -0
- appinfra-0.1.0/tests/cli/tools/test_scaffold.py +752 -0
- appinfra-0.1.0/tests/conftest.py +158 -0
- appinfra-0.1.0/tests/e2e/README.md +250 -0
- appinfra-0.1.0/tests/e2e/__init__.py +41 -0
- appinfra-0.1.0/tests/e2e/complete_app_workflow.py.disabled +217 -0
- appinfra-0.1.0/tests/e2e/logging_pipeline_e2e.py.disabled +185 -0
- appinfra-0.1.0/tests/e2e/test_auto_config_workflow.py +382 -0
- appinfra-0.1.0/tests/e2e/test_cli_to_database_workflow.py +137 -0
- appinfra-0.1.0/tests/e2e/test_hot_reload_workflow.py +581 -0
- appinfra-0.1.0/tests/e2e/test_main_tool_workflow.py +227 -0
- appinfra-0.1.0/tests/e2e/test_pg_readonly_workflow.py +172 -0
- appinfra-0.1.0/tests/e2e/test_scaffold_workflow.py +350 -0
- appinfra-0.1.0/tests/e2e/test_size_workflow.py +145 -0
- appinfra-0.1.0/tests/e2e/test_subprocess_context.py +346 -0
- appinfra-0.1.0/tests/fixtures/__init__.py +1 -0
- appinfra-0.1.0/tests/fixtures/config.py +134 -0
- appinfra-0.1.0/tests/fixtures/database.py +96 -0
- appinfra-0.1.0/tests/fixtures/logging.py +109 -0
- appinfra-0.1.0/tests/fixtures/network.py +107 -0
- appinfra-0.1.0/tests/fixtures/path_resolution/config_no_paths.yaml +14 -0
- appinfra-0.1.0/tests/fixtures/path_resolution/config_with_paths.yaml +23 -0
- appinfra-0.1.0/tests/fixtures/path_resolution/includes/database_paths.yaml +9 -0
- appinfra-0.1.0/tests/fixtures/pg_integration.py +504 -0
- appinfra-0.1.0/tests/helpers/__init__.py +1 -0
- appinfra-0.1.0/tests/helpers/assertions.py +133 -0
- appinfra-0.1.0/tests/helpers/builders.py +146 -0
- appinfra-0.1.0/tests/helpers/parametrize.py +144 -0
- appinfra-0.1.0/tests/helpers/pg/__init__.py +11 -0
- appinfra-0.1.0/tests/helpers/pg/helper.py +277 -0
- appinfra-0.1.0/tests/helpers/pg/helper_core.py +299 -0
- appinfra-0.1.0/tests/infra/app/builder/configurer/test_advanced_configurer.py +401 -0
- appinfra-0.1.0/tests/infra/app/builder/configurer/test_logging.py +559 -0
- appinfra-0.1.0/tests/infra/app/builder/configurer/test_server_configurer.py +392 -0
- appinfra-0.1.0/tests/infra/app/builder/configurer/test_tool_configurer.py +351 -0
- appinfra-0.1.0/tests/infra/app/builder/configurer/test_version_configurer.py +514 -0
- appinfra-0.1.0/tests/infra/app/builder/test_app_builder.py +832 -0
- appinfra-0.1.0/tests/infra/app/builder/test_config.py +594 -0
- appinfra-0.1.0/tests/infra/app/builder/test_hook.py +685 -0
- appinfra-0.1.0/tests/infra/app/builder/test_middleware.py +672 -0
- appinfra-0.1.0/tests/infra/app/builder/test_plugin.py +825 -0
- appinfra-0.1.0/tests/infra/app/builder/test_standard_args_control.py +313 -0
- appinfra-0.1.0/tests/infra/app/builder/test_tool.py +627 -0
- appinfra-0.1.0/tests/infra/app/builder/test_validation.py +667 -0
- appinfra-0.1.0/tests/infra/app/cli/test_commands.py +337 -0
- appinfra-0.1.0/tests/infra/app/cli/test_help.py +304 -0
- appinfra-0.1.0/tests/infra/app/cli/test_parser.py +422 -0
- appinfra-0.1.0/tests/infra/app/core/__init__.py +0 -0
- appinfra-0.1.0/tests/infra/app/core/test_app.py +1279 -0
- appinfra-0.1.0/tests/infra/app/core/test_config.py +634 -0
- appinfra-0.1.0/tests/infra/app/core/test_lifecycle.py +793 -0
- appinfra-0.1.0/tests/infra/app/core/test_lifecycle_hot_reload.py +429 -0
- appinfra-0.1.0/tests/infra/app/core/test_logging_utils.py +717 -0
- appinfra-0.1.0/tests/infra/app/core/test_shutdown.py +137 -0
- appinfra-0.1.0/tests/infra/app/docs/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/app/docs/test_generator.py +587 -0
- appinfra-0.1.0/tests/infra/app/fastapi/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_adapter.py +340 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_builder.py +497 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_config.py +171 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_init.py +203 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_ipc.py +333 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_logging.py +57 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_plugin.py +196 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_server.py +439 -0
- appinfra-0.1.0/tests/infra/app/fastapi/test_subprocess.py +293 -0
- appinfra-0.1.0/tests/infra/app/server/test_base.py +597 -0
- appinfra-0.1.0/tests/infra/app/server/test_handlers.py +411 -0
- appinfra-0.1.0/tests/infra/app/server/test_routes.py +339 -0
- appinfra-0.1.0/tests/infra/app/test_app_utils.py +21 -0
- appinfra-0.1.0/tests/infra/app/test_appbuilder_topic_logging.py +269 -0
- appinfra-0.1.0/tests/infra/app/test_decorators.py +697 -0
- appinfra-0.1.0/tests/infra/app/test_errors.py +296 -0
- appinfra-0.1.0/tests/infra/app/test_testing.py +54 -0
- appinfra-0.1.0/tests/infra/app/tools/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/app/tools/test_base.py +727 -0
- appinfra-0.1.0/tests/infra/app/tools/test_group.py +687 -0
- appinfra-0.1.0/tests/infra/app/tools/test_protocol.py +324 -0
- appinfra-0.1.0/tests/infra/app/tools/test_registry.py +528 -0
- appinfra-0.1.0/tests/infra/app/tracing/__init__.py +0 -0
- appinfra-0.1.0/tests/infra/app/tracing/test_traceable.py +492 -0
- appinfra-0.1.0/tests/infra/cli/tools/test_version_tool.py +353 -0
- appinfra-0.1.0/tests/infra/config/__init__.py +0 -0
- appinfra-0.1.0/tests/infra/config/test_config.py +1219 -0
- appinfra-0.1.0/tests/infra/config/test_init.py +80 -0
- appinfra-0.1.0/tests/infra/config/test_schemas.py +120 -0
- appinfra-0.1.0/tests/infra/config/test_watcher.py +855 -0
- appinfra-0.1.0/tests/infra/db/pg/test_connection.py +212 -0
- appinfra-0.1.0/tests/infra/db/pg/test_core.py +322 -0
- appinfra-0.1.0/tests/infra/db/pg/test_db_interface.py +315 -0
- appinfra-0.1.0/tests/infra/db/pg/test_pg_errors.py +219 -0
- appinfra-0.1.0/tests/infra/db/pg/test_reconnection.py +270 -0
- appinfra-0.1.0/tests/infra/db/pg/test_session.py +264 -0
- appinfra-0.1.0/tests/infra/db/test_db.py +732 -0
- appinfra-0.1.0/tests/infra/log/builder/database/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/log/builder/database/test_builder.py +319 -0
- appinfra-0.1.0/tests/infra/log/builder/database/test_config.py +280 -0
- appinfra-0.1.0/tests/infra/log/builder/database/test_handler.py +605 -0
- appinfra-0.1.0/tests/infra/log/builder/test_builder.py +501 -0
- appinfra-0.1.0/tests/infra/log/builder/test_console.py +344 -0
- appinfra-0.1.0/tests/infra/log/builder/test_file.py +514 -0
- appinfra-0.1.0/tests/infra/log/builder/test_interface.py +398 -0
- appinfra-0.1.0/tests/infra/log/builder/test_json.py +1006 -0
- appinfra-0.1.0/tests/infra/log/builder/test_quick.py +692 -0
- appinfra-0.1.0/tests/infra/log/test_capture_all_loggers.py +276 -0
- appinfra-0.1.0/tests/infra/log/test_colors.py +150 -0
- appinfra-0.1.0/tests/infra/log/test_config_holder.py +171 -0
- appinfra-0.1.0/tests/infra/log/test_factory.py +378 -0
- appinfra-0.1.0/tests/infra/log/test_factory_topic_integration.py +146 -0
- appinfra-0.1.0/tests/infra/log/test_formatters.py +840 -0
- appinfra-0.1.0/tests/infra/log/test_handler_factory.py +669 -0
- appinfra-0.1.0/tests/infra/log/test_init.py +100 -0
- appinfra-0.1.0/tests/infra/log/test_level_manager.py +478 -0
- appinfra-0.1.0/tests/infra/log/test_logger.py +1054 -0
- appinfra-0.1.0/tests/infra/net/test_tcp.py +750 -0
- appinfra-0.1.0/tests/infra/observability/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/observability/test_hooks.py +563 -0
- appinfra-0.1.0/tests/infra/security/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/security/test_filter.py +171 -0
- appinfra-0.1.0/tests/infra/security/test_masking.py +210 -0
- appinfra-0.1.0/tests/infra/test_deprecation.py +294 -0
- appinfra-0.1.0/tests/infra/test_dict.py +461 -0
- appinfra-0.1.0/tests/infra/test_dot_dict.py +354 -0
- appinfra-0.1.0/tests/infra/test_ewma.py +134 -0
- appinfra-0.1.0/tests/infra/test_exceptions.py +306 -0
- appinfra-0.1.0/tests/infra/test_rate_limit.py +213 -0
- appinfra-0.1.0/tests/infra/test_regex_utils.py +246 -0
- appinfra-0.1.0/tests/infra/test_size.py +279 -0
- appinfra-0.1.0/tests/infra/test_utils.py +137 -0
- appinfra-0.1.0/tests/infra/test_yaml.py +1869 -0
- appinfra-0.1.0/tests/infra/time/test_date_range.py +287 -0
- appinfra-0.1.0/tests/infra/time/test_delta.py +662 -0
- appinfra-0.1.0/tests/infra/time/test_eta.py +205 -0
- appinfra-0.1.0/tests/infra/time/test_sched.py +811 -0
- appinfra-0.1.0/tests/infra/time/test_ticker.py +1025 -0
- appinfra-0.1.0/tests/infra/time/test_time.py +390 -0
- appinfra-0.1.0/tests/infra/ui/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/ui/test_console.py +408 -0
- appinfra-0.1.0/tests/infra/ui/test_fallback.py +177 -0
- appinfra-0.1.0/tests/infra/ui/test_help.py +480 -0
- appinfra-0.1.0/tests/infra/ui/test_progress_logger.py +491 -0
- appinfra-0.1.0/tests/infra/ui/test_prompts.py +963 -0
- appinfra-0.1.0/tests/infra/version/__init__.py +1 -0
- appinfra-0.1.0/tests/infra/version/test_actions.py +255 -0
- appinfra-0.1.0/tests/infra/version/test_build_info.py +195 -0
- appinfra-0.1.0/tests/infra/version/test_info.py +487 -0
- appinfra-0.1.0/tests/infra/version/test_setup_hook.py +479 -0
- appinfra-0.1.0/tests/infra/version/test_setuptools_hook.py +233 -0
- appinfra-0.1.0/tests/infra/version/test_sources.py +531 -0
- appinfra-0.1.0/tests/infra/version/test_tracker.py +301 -0
- appinfra-0.1.0/tests/integration/__init__.py +0 -0
- appinfra-0.1.0/tests/integration/test_pg_class.py +641 -0
- appinfra-0.1.0/tests/integration/test_pg_fixtures.py +423 -0
- appinfra-0.1.0/tests/performance/__init__.py +0 -0
- appinfra-0.1.0/tests/performance/db/__init__.py +0 -0
- appinfra-0.1.0/tests/performance/db/test_connection_pool.py +41 -0
- appinfra-0.1.0/tests/performance/test_logging_throughput.py +143 -0
- appinfra-0.1.0/tests/performance/test_regex_timeout.py +50 -0
- appinfra-0.1.0/tests/performance/test_ticker_accuracy.py +65 -0
- appinfra-0.1.0/tests/property/test_delta_properties.py +78 -0
- appinfra-0.1.0/tests/property/test_dot_dict_properties.py +127 -0
- appinfra-0.1.0/tests/property/test_regex_properties.py +84 -0
- appinfra-0.1.0/tests/security/conftest.py +153 -0
- appinfra-0.1.0/tests/security/helpers/__init__.py +15 -0
- appinfra-0.1.0/tests/security/helpers/assertions.py +141 -0
- appinfra-0.1.0/tests/security/payloads/__init__.py +43 -0
- appinfra-0.1.0/tests/security/payloads/injection.py +63 -0
- appinfra-0.1.0/tests/security/payloads/redos.py +55 -0
- appinfra-0.1.0/tests/security/payloads/resource_exhaustion.py +107 -0
- appinfra-0.1.0/tests/security/payloads/traversal.py +56 -0
- appinfra-0.1.0/tests/security/test_config_security.py +481 -0
- appinfra-0.1.0/tests/security/test_database_security.py +372 -0
- appinfra-0.1.0/tests/security/test_e2e_security.py +293 -0
- appinfra-0.1.0/tests/security/test_logging_security.py +252 -0
- appinfra-0.1.0/tests/security/test_regex_security.py +247 -0
- appinfra-0.1.0/tests/security/test_validation_security.py +370 -0
- appinfra-0.1.0/tests/security/test_yaml_security.py +260 -0
|
@@ -0,0 +1,744 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Analyze the infrastructure framework, provide comprehensive grading, and suggest
|
|
3
|
+
improvements
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ⚠️ CRITICAL: OUTPUT REQUIREMENTS
|
|
7
|
+
|
|
8
|
+
**WRITE THE COMPLETE GRADING REPORT TO `.GRADING.md` FILE**
|
|
9
|
+
|
|
10
|
+
- Use the Write tool to create/overwrite `.GRADING.md` with your full analysis
|
|
11
|
+
- The file should contain ALL sections below in markdown format
|
|
12
|
+
- This is NOT optional - the report MUST be written to the file
|
|
13
|
+
- After writing the file, provide a brief summary to the user
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
Analyze this Python infrastructure framework comprehensively and provide:
|
|
18
|
+
|
|
19
|
+
## 🔍 DETERMINE PROJECT TYPE
|
|
20
|
+
|
|
21
|
+
**CRITICAL: Read README.md to identify project type before grading:**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Read README.md to detect project type from Scope & Philosophy section
|
|
25
|
+
head -50 README.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Look for explicit scope information:**
|
|
29
|
+
- Check for "Scope & Philosophy" or "Scope" section in README
|
|
30
|
+
- Look for keywords: "library", "framework", "reusable components" → LIBRARY
|
|
31
|
+
- Look for keywords: "application", "service", "deployed" → APPLICATION
|
|
32
|
+
- Check "In Scope" / "Out of Scope" / "Best For" / "Not For" declarations
|
|
33
|
+
|
|
34
|
+
**If README contains "Scope & Philosophy" section:**
|
|
35
|
+
- Use the explicit scope information to determine type
|
|
36
|
+
- Note any specific constraints (e.g., "PostgreSQL-only", "CLI framework not web framework")
|
|
37
|
+
- Identify what's explicitly out of scope
|
|
38
|
+
|
|
39
|
+
**If no explicit scope section exists:**
|
|
40
|
+
- Fall back to indicators:
|
|
41
|
+
- PyPI publishing mentioned → likely library
|
|
42
|
+
- Deployment guides for the project itself → likely application
|
|
43
|
+
- "Install via pip" → library
|
|
44
|
+
- "Run this service" → application
|
|
45
|
+
|
|
46
|
+
**Why This Matters:**
|
|
47
|
+
**Production readiness criteria differ significantly:**
|
|
48
|
+
|
|
49
|
+
| Criteria | Library | Application |
|
|
50
|
+
|----------|---------|-------------|
|
|
51
|
+
| Health checks | ❌ Not applicable (library doesn't run) | ✅ Required (/health endpoint) |
|
|
52
|
+
| Deployment guide | ❌ Not applicable (users deploy THEIR apps) | ✅ Required (how to deploy THIS app) |
|
|
53
|
+
| Metrics/observability | ✅ Hooks/abstractions for users to integrate | ✅ Built-in metrics endpoints |
|
|
54
|
+
| PyPI publishing | ✅ Critical for distribution | ❌ Not applicable |
|
|
55
|
+
| Integration examples | ✅ Show how to use in production apps | ⚠️ Less critical |
|
|
56
|
+
| API stability | ✅ Critical (semver, deprecation policy) | ⚠️ Less critical (internal APIs) |
|
|
57
|
+
| Production usage guide | ✅ How to use library in production settings | ✅ How to run application in production |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 0. VERIFICATION STEPS - Run These First
|
|
62
|
+
|
|
63
|
+
**FIRST: Delete any existing grading report to avoid bias:**
|
|
64
|
+
```bash
|
|
65
|
+
# Remove old .GRADING.md file if it exists
|
|
66
|
+
rm -f .GRADING.md
|
|
67
|
+
```
|
|
68
|
+
- This prevents reading old analysis and being influenced by previous grading
|
|
69
|
+
- Critical: Do this BEFORE any analysis begins
|
|
70
|
+
|
|
71
|
+
**Before starting analysis, verify these critical facts:**
|
|
72
|
+
|
|
73
|
+
### LICENSE File
|
|
74
|
+
```bash
|
|
75
|
+
# Check LICENSE file exists and read first 20 lines
|
|
76
|
+
ls -la LICENSE
|
|
77
|
+
head -20 LICENSE
|
|
78
|
+
```
|
|
79
|
+
- Verify it contains actual license text (Apache, MIT, BSD, etc.)
|
|
80
|
+
- If file is empty or binary, that's a critical issue
|
|
81
|
+
- If file doesn't exist, that's a blocker
|
|
82
|
+
|
|
83
|
+
### CHANGELOG File
|
|
84
|
+
```bash
|
|
85
|
+
# Check CHANGELOG.md exists and read first 30 lines
|
|
86
|
+
ls -la CHANGELOG.md
|
|
87
|
+
head -30 CHANGELOG.md
|
|
88
|
+
```
|
|
89
|
+
- **IMPORTANT:** Actually READ this file before claiming it's missing
|
|
90
|
+
- Verify the file exists before making claims about its absence
|
|
91
|
+
- Check it contains actual changelog entries (versions, dates, changes)
|
|
92
|
+
- Common formats: Keep a Changelog, conventional commits
|
|
93
|
+
- If file doesn't exist, note it as a documentation gap (not a blocker)
|
|
94
|
+
|
|
95
|
+
### Test Files Location
|
|
96
|
+
```bash
|
|
97
|
+
# Check for tests in standard locations
|
|
98
|
+
find . -type d -name "tests" -o -name "test"
|
|
99
|
+
find ./tests -name "*.py" 2>/dev/null | wc -l
|
|
100
|
+
find . -name "test_*.py" -o -name "*_test.py" | head -20
|
|
101
|
+
```
|
|
102
|
+
- Tests may be in: `./tests/`, `./test/`, `infra/tests/`, or mixed with source
|
|
103
|
+
- Count test files accurately before making claims
|
|
104
|
+
- If README claims X tests but you find Y, investigate why
|
|
105
|
+
|
|
106
|
+
### Test Execution & Coverage - CRITICAL: RUN THE TESTS
|
|
107
|
+
|
|
108
|
+
**IMPORTANT: Actually run the test suite to get real metrics:**
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# 1. Run all tests (unit, integration, performance, security, e2e)
|
|
112
|
+
make test.all
|
|
113
|
+
|
|
114
|
+
# 2. Generate coverage report
|
|
115
|
+
make test.coverage
|
|
116
|
+
|
|
117
|
+
# 3. Display coverage summary
|
|
118
|
+
~/.venv/bin/python -m coverage report
|
|
119
|
+
|
|
120
|
+
# 4. Verify test collection count
|
|
121
|
+
~/.venv/bin/python -m pytest --collect-only 2>&1 | grep "collected"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**What to capture:**
|
|
125
|
+
- Total tests run (passed/failed/skipped)
|
|
126
|
+
- Test execution time
|
|
127
|
+
- Actual coverage percentage (not README claims)
|
|
128
|
+
- Coverage by module (which modules have gaps)
|
|
129
|
+
- Any test failures or errors
|
|
130
|
+
|
|
131
|
+
**If tests fail:**
|
|
132
|
+
- Document which tests failed and why
|
|
133
|
+
- This is CRITICAL information for the grading
|
|
134
|
+
- Don't just report "tests passed" - show actual results
|
|
135
|
+
- Test failures may reveal bugs, missing dependencies, or config issues
|
|
136
|
+
|
|
137
|
+
**Cross-check with your file count:**
|
|
138
|
+
- If you found 70 test files but pytest collected 2,308 tests → explain (multiple tests per file)
|
|
139
|
+
- If coverage report shows 85% but README claims 93% → report discrepancy
|
|
140
|
+
|
|
141
|
+
### Type Hints Coverage - CRITICAL: RUN THE SCRIPT
|
|
142
|
+
|
|
143
|
+
**IMPORTANT: Use the automated script to get real type hint coverage:**
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Run type hint coverage report
|
|
147
|
+
./scripts/type-hint.sh
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**This script will:**
|
|
151
|
+
- Run mypy on all production code (appinfra/, cli/)
|
|
152
|
+
- Count files successfully checked by mypy
|
|
153
|
+
- Count total production Python files
|
|
154
|
+
- Calculate and display coverage percentage
|
|
155
|
+
- Show mypy configuration from pyproject.toml
|
|
156
|
+
|
|
157
|
+
**What to capture:**
|
|
158
|
+
- "Files with complete type hints: X"
|
|
159
|
+
- "Total production files: Y"
|
|
160
|
+
- "Coverage: Z%"
|
|
161
|
+
- Mypy config showing `disallow_untyped_defs = true`
|
|
162
|
+
|
|
163
|
+
**Key insight:**
|
|
164
|
+
If mypy passes with `disallow_untyped_defs = true` enabled, this **PROVES** that all checked files
|
|
165
|
+
have complete type hints. Any file without type hints would FAIL mypy with this strict setting.
|
|
166
|
+
|
|
167
|
+
**Use these exact numbers in the grading report** - never estimate or guess type hint coverage.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 🚫 BASELINE GATES - Check These First
|
|
172
|
+
|
|
173
|
+
**Before grading quality, verify baseline requirements exist. Missing baselines cap the maximum
|
|
174
|
+
possible grade.**
|
|
175
|
+
|
|
176
|
+
### Gate 1: Legal Requirements
|
|
177
|
+
```bash
|
|
178
|
+
ls -la LICENSE && head -5 LICENSE
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
| Result | Action |
|
|
182
|
+
|--------|--------|
|
|
183
|
+
| LICENSE missing or empty | **STOP. Grade capped at F.** Cannot legally use/distribute. |
|
|
184
|
+
| LICENSE exists with valid text | Proceed to Gate 2 |
|
|
185
|
+
|
|
186
|
+
### Gate 2: Tests Must Pass
|
|
187
|
+
```bash
|
|
188
|
+
make test.all
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Result | Action |
|
|
192
|
+
|--------|--------|
|
|
193
|
+
| Tests fail (non-zero exit) | **Grade capped at D.** Document failures, investigate cause. |
|
|
194
|
+
| Tests pass with >50% skipped | Note as concern, proceed with caution |
|
|
195
|
+
| Tests pass normally | Proceed to Gate 3 |
|
|
196
|
+
|
|
197
|
+
### Gate 3: Core Files Exist
|
|
198
|
+
```bash
|
|
199
|
+
ls README.md pyproject.toml
|
|
200
|
+
ls -d tests/ 2>/dev/null || ls -d test/ 2>/dev/null
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
| Missing Item | Impact |
|
|
204
|
+
|--------------|--------|
|
|
205
|
+
| README.md | Documentation grade capped at 5/10 |
|
|
206
|
+
| pyproject.toml | Dependencies grade capped at 5/10 |
|
|
207
|
+
| No test directory | Testing grade is 0/10 |
|
|
208
|
+
|
|
209
|
+
### Gate 4: Can Import Package
|
|
210
|
+
```bash
|
|
211
|
+
~/.venv/bin/python -c "import appinfra; print(appinfra.__version__)"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
| Result | Action |
|
|
215
|
+
|--------|--------|
|
|
216
|
+
| Import fails | **Grade capped at D.** Package is broken. |
|
|
217
|
+
| Import succeeds | Proceed to full grading |
|
|
218
|
+
|
|
219
|
+
**Only proceed to comprehensive grading if all gates pass or you've documented the cap.**
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## ⚠️ IMPORTANT VERIFICATION REQUIREMENT
|
|
224
|
+
|
|
225
|
+
Before grading type hint coverage:
|
|
226
|
+
1. ✅ Run `./scripts/type-hint.sh` to get actual coverage
|
|
227
|
+
2. ✅ Use exact numbers from script output
|
|
228
|
+
3. ✅ Verify script shows mypy config has `disallow_untyped_defs = true`
|
|
229
|
+
4. ❌ NEVER estimate or guess type hint coverage
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 1. COMPREHENSIVE GRADING
|
|
234
|
+
|
|
235
|
+
Grade each category on a 10-point scale with detailed justification:
|
|
236
|
+
|
|
237
|
+
### Architecture & Design
|
|
238
|
+
- Design patterns used (Builder, Factory, Protocol, etc.)
|
|
239
|
+
- Module organization and cohesion
|
|
240
|
+
- Abstraction quality (see rubric below)
|
|
241
|
+
- Technical debt (deprecated APIs, global state)
|
|
242
|
+
- API consistency (see rubric below)
|
|
243
|
+
|
|
244
|
+
**Rubric: Abstraction Quality**
|
|
245
|
+
| Score | Criteria | Verification |
|
|
246
|
+
|-------|----------|--------------|
|
|
247
|
+
| Excellent | No leaky abstractions; users never need to understand internals | `grep -r "internal\|private\|_" <pkg>/__init__.py` - internals not exported |
|
|
248
|
+
| Good | Rare leaks; internals documented when exposed | Check if internal details appear in public API docs |
|
|
249
|
+
| Acceptable | Some leaks but workarounds documented | Users can accomplish tasks without reading source |
|
|
250
|
+
| Poor | Users must read source to use effectively | Examples require understanding of internals |
|
|
251
|
+
|
|
252
|
+
**Rubric: API Consistency**
|
|
253
|
+
| Score | Criteria | Verification |
|
|
254
|
+
|-------|----------|--------------|
|
|
255
|
+
| Excellent | Similar operations have identical signatures; naming is predictable | `grep -rn "def " <pkg>/ \| head -30` - check naming patterns |
|
|
256
|
+
| Good | Mostly consistent with documented exceptions | Inconsistencies are intentional and documented |
|
|
257
|
+
| Acceptable | Some inconsistencies but learnable | Can predict API after learning a few examples |
|
|
258
|
+
| Poor | Inconsistent naming, signatures vary unpredictably | Each function feels like a different library |
|
|
259
|
+
|
|
260
|
+
**How to verify:**
|
|
261
|
+
```bash
|
|
262
|
+
# Check for consistent naming patterns
|
|
263
|
+
grep -rn "def get_\|def fetch_\|def retrieve_" <package>/ # Should use ONE pattern
|
|
264
|
+
|
|
265
|
+
# Check for consistent return types
|
|
266
|
+
grep -rn "-> None:\|-> bool:\|-> int:" <package>/ # Similar functions should return similar types
|
|
267
|
+
|
|
268
|
+
# Check __all__ exports for clean public API
|
|
269
|
+
grep -A20 "__all__" <package>/__init__.py
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Code Quality
|
|
273
|
+
- Type hints coverage
|
|
274
|
+
- Function sizes (should be 20-30 lines per guidelines) - **Run `./cli/cli.py cq cf --format=detailed` to check**
|
|
275
|
+
- Documentation completeness
|
|
276
|
+
- Naming consistency
|
|
277
|
+
- Production-ready error handling (no print() statements in executable code)
|
|
278
|
+
- **IMPORTANT: Verifying print() statements** - Many print() occurrences may be in docstrings, comments, or documentation
|
|
279
|
+
- **Pattern to check**: Use `grep -rn "print(" --include="*.py" path/` to get all occurrences
|
|
280
|
+
- **Then verify which are executable vs. documentation**:
|
|
281
|
+
- **Executable**: Inside function bodies, not in docstrings/comments
|
|
282
|
+
- **Documentation**: In module/function/class docstrings, README files, comment blocks, example code
|
|
283
|
+
- **Check the context** of each occurrence before counting
|
|
284
|
+
- **Example**: `ticker.py` may show 12 print() but only 4 are executable (rest in docstrings)
|
|
285
|
+
- **Don't count**: Docstring examples, README files, comment blocks, example scripts in `examples/`
|
|
286
|
+
|
|
287
|
+
### Security
|
|
288
|
+
- Input validation
|
|
289
|
+
- Resource limits
|
|
290
|
+
- Vulnerability assessment (YAML parsing, path traversal, ReDoS)
|
|
291
|
+
- Credential handling
|
|
292
|
+
- Example security
|
|
293
|
+
|
|
294
|
+
### Testing
|
|
295
|
+
- **CRITICAL: Run the tests first** - Execute `make test.all` and `make test.coverage` before grading
|
|
296
|
+
- **Use actual results, not claims:**
|
|
297
|
+
- Report actual coverage % from `coverage report` (not README)
|
|
298
|
+
- Report actual test count from pytest output
|
|
299
|
+
- Document any test failures or errors
|
|
300
|
+
- Show execution time for different test categories
|
|
301
|
+
- Test coverage by category (unit, integration, performance, security, e2e)
|
|
302
|
+
- Test organization and structure
|
|
303
|
+
- Edge case coverage in critical paths
|
|
304
|
+
- Performance test assertions (actual benchmarks with thresholds, not just execution)
|
|
305
|
+
- Test isolation and independence
|
|
306
|
+
- **Cross-check**: If `pytest --collect-only` shows N tests but you found M files, explain discrepancy
|
|
307
|
+
- **Coverage gaps**: Identify modules with < 80% coverage from coverage report
|
|
308
|
+
|
|
309
|
+
### Documentation
|
|
310
|
+
- README quality (completeness, examples, structure)
|
|
311
|
+
- API documentation (docstrings, generated docs)
|
|
312
|
+
- Migration guides for deprecated APIs
|
|
313
|
+
- Security documentation (SECURITY.md quality)
|
|
314
|
+
- **LICENSE file**: READ the file (not just check presence) - verify it contains valid license text
|
|
315
|
+
- Common licenses: Apache 2.0, MIT, BSD, GPL
|
|
316
|
+
- If file exists but is empty/binary/corrupted, that's CRITICAL
|
|
317
|
+
- Check copyright year and attribution
|
|
318
|
+
|
|
319
|
+
### Production Readiness
|
|
320
|
+
|
|
321
|
+
**Grade based on project type (see "DETERMINE PROJECT TYPE FIRST" section above):**
|
|
322
|
+
|
|
323
|
+
#### For Libraries:
|
|
324
|
+
- ✅ **API Stability:** Clear versioning (semver), deprecation warnings, backward compatibility policy
|
|
325
|
+
- ✅ **Package Distribution:** Published to PyPI, installable via pip, proper wheel distribution
|
|
326
|
+
- ✅ **Integration Guidance:** How to use library in production apps, configuration examples, best practices
|
|
327
|
+
- ✅ **Production Patterns:** Examples of production-grade usage (structured logging, connection pooling, etc.)
|
|
328
|
+
- ✅ **Error Handling:** Graceful errors, custom exceptions, resource cleanup (context managers)
|
|
329
|
+
- ✅ **Observability Hooks:** Callbacks/hooks for users to integrate metrics (not built-in dashboards)
|
|
330
|
+
- ❌ **NOT Expected:** Health check endpoints, deployment guides for the library itself, metrics dashboards
|
|
331
|
+
|
|
332
|
+
#### For Applications:
|
|
333
|
+
- ✅ **Graceful Shutdown:** Signal handlers, cleanup hooks, proper resource release
|
|
334
|
+
- ✅ **Health Checks:** /health endpoint, dependency checks
|
|
335
|
+
- ✅ **Metrics/Observability:** Built-in metrics endpoints (Prometheus, StatsD, etc.)
|
|
336
|
+
- ✅ **Deployment Guide:** How to deploy THIS application (Docker, K8s, systemd, etc.)
|
|
337
|
+
- ✅ **Error Recovery:** Retry logic, circuit breakers, fallback strategies
|
|
338
|
+
- ✅ **Version Management:** Runtime version checks, feature flags
|
|
339
|
+
|
|
340
|
+
#### Universal (Both Types):
|
|
341
|
+
- Error handling and recovery strategies
|
|
342
|
+
- Resource management (cleanup, context managers)
|
|
343
|
+
- Version management and compatibility
|
|
344
|
+
|
|
345
|
+
### Dependencies & Compatibility
|
|
346
|
+
- Python version support (check if supporting EOL versions)
|
|
347
|
+
- Dependency pinning (version ranges with upper bounds)
|
|
348
|
+
- CI/CD matrix testing
|
|
349
|
+
- Platform compatibility
|
|
350
|
+
- **Dependency security** - Check for known vulnerabilities:
|
|
351
|
+
```bash
|
|
352
|
+
# Check for known CVEs in dependencies
|
|
353
|
+
pip audit 2>/dev/null || pip install pip-audit && pip audit
|
|
354
|
+
|
|
355
|
+
# Alternative: safety check
|
|
356
|
+
safety check 2>/dev/null || echo "safety not installed"
|
|
357
|
+
```
|
|
358
|
+
- **License compatibility** - Ensure dependency licenses are compatible:
|
|
359
|
+
```bash
|
|
360
|
+
# List dependency licenses
|
|
361
|
+
pip-licenses --format=markdown 2>/dev/null || echo "pip-licenses not installed"
|
|
362
|
+
|
|
363
|
+
# Watch for: GPL in MIT/Apache projects, incompatible combinations
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## 2. CRITICAL ISSUES
|
|
367
|
+
|
|
368
|
+
Identify and prioritize:
|
|
369
|
+
- **Tier 0: Must-Fix** (before any release) - Legal blockers, breaking bugs
|
|
370
|
+
- **Tier 1: High-Impact** (before open-source) - Security, observability, docs
|
|
371
|
+
- **Tier 2: Quality** (before 1.0) - Technical debt, refactoring
|
|
372
|
+
- **Tier 3: Polish** (ongoing) - Nice-to-haves, future enhancements
|
|
373
|
+
|
|
374
|
+
For each issue provide:
|
|
375
|
+
- File location with line numbers
|
|
376
|
+
- Code example showing the problem
|
|
377
|
+
- Impact assessment
|
|
378
|
+
- Specific fix recommendation with code example
|
|
379
|
+
- Time estimate
|
|
380
|
+
|
|
381
|
+
**Note on Project Type:** Remember to frame issues based on whether this is a library or
|
|
382
|
+
application. For example:
|
|
383
|
+
- Library missing PyPI publishing → Tier 1 (high-impact)
|
|
384
|
+
- Library missing health check endpoint → Not an issue (libraries don't need this)
|
|
385
|
+
- Application missing deployment guide → Tier 1 (high-impact)
|
|
386
|
+
- Application missing PyPI publishing → Not applicable
|
|
387
|
+
|
|
388
|
+
## 3. KEY METRICS
|
|
389
|
+
|
|
390
|
+
Measure and report (use ACTUAL data from running commands):
|
|
391
|
+
- Total lines of code
|
|
392
|
+
- Number of implementation files
|
|
393
|
+
- Number of test files (from `find` command)
|
|
394
|
+
- Number of test functions (from `pytest --collect-only`)
|
|
395
|
+
- Test-to-code ratio
|
|
396
|
+
- **Actual test coverage** - from `coverage report` output, NOT README claims
|
|
397
|
+
- Overall coverage percentage
|
|
398
|
+
- Coverage by module (identify gaps)
|
|
399
|
+
- Lines covered vs total lines
|
|
400
|
+
- **Test execution results:**
|
|
401
|
+
- Total tests run
|
|
402
|
+
- Passed / Failed / Skipped counts
|
|
403
|
+
- Execution time by category
|
|
404
|
+
- Function size statistics (average, max) - **Use `./cli/cli.py cq cf --format=detailed` for this**
|
|
405
|
+
- Deprecated API usage
|
|
406
|
+
|
|
407
|
+
## 4. TRADE-OFFS & RECOMMENDATIONS
|
|
408
|
+
|
|
409
|
+
Analyze key decisions with options:
|
|
410
|
+
- Python version support strategy
|
|
411
|
+
- API design choices (multiple ways to do things)
|
|
412
|
+
- Observability approach
|
|
413
|
+
- Documentation strategy
|
|
414
|
+
|
|
415
|
+
For each, provide:
|
|
416
|
+
- Current state
|
|
417
|
+
- Options (A, B, C with pros/cons)
|
|
418
|
+
- Recommended approach with rationale
|
|
419
|
+
- Migration path if applicable
|
|
420
|
+
|
|
421
|
+
## 5. ACTIONABLE ROADMAP
|
|
422
|
+
|
|
423
|
+
Create phased plan:
|
|
424
|
+
- **Phase 1: Release Blockers** (days) - Time estimate, must-fix list
|
|
425
|
+
- **Phase 2: Quality & Hardening** (weeks) - High-priority improvements
|
|
426
|
+
- **Phase 3: Polish & Enhancement** (weeks) - Medium-priority
|
|
427
|
+
|
|
428
|
+
## 6. FINAL SCORECARD
|
|
429
|
+
|
|
430
|
+
### 📊 Category Weights (MANDATORY)
|
|
431
|
+
|
|
432
|
+
Use these exact weights when calculating the final score:
|
|
433
|
+
|
|
434
|
+
| Category | Weight | Rationale |
|
|
435
|
+
|----------|--------|-----------|
|
|
436
|
+
| Architecture & Design | 15% | Foundation quality affects everything |
|
|
437
|
+
| Code Quality | 20% | Largest category - daily developer experience |
|
|
438
|
+
| Security | 15% | Critical for production use |
|
|
439
|
+
| Testing | 15% | Confidence in correctness |
|
|
440
|
+
| Documentation | 10% | Important but less than code itself |
|
|
441
|
+
| Production Readiness | 15% | Real-world deployment concerns |
|
|
442
|
+
| Dependencies & Compatibility | 10% | Ecosystem integration |
|
|
443
|
+
| **Total** | **100%** | |
|
|
444
|
+
|
|
445
|
+
**Calculating Final Score:**
|
|
446
|
+
```
|
|
447
|
+
Final = (Arch × 0.15) + (Quality × 0.20) + (Security × 0.15) +
|
|
448
|
+
(Testing × 0.15) + (Docs × 0.10) + (ProdReady × 0.15) + (Deps × 0.10)
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
### 🚨 MANDATORY: Severity-Based Deduction Scale
|
|
454
|
+
|
|
455
|
+
**Deductions MUST match issue severity. Not all issues are equal.**
|
|
456
|
+
|
|
457
|
+
| Severity | Deduction | Criteria | Examples |
|
|
458
|
+
|----------|-----------|----------|----------|
|
|
459
|
+
| **Critical** | -2.0 to -3.0 | Blocks usage, legal/security risk | Missing LICENSE, security vuln, tests fail, data loss risk |
|
|
460
|
+
| **Major** | -1.0 to -1.5 | Significant gap in production readiness | No CI/CD, missing critical docs, no error handling |
|
|
461
|
+
| **Moderate** | -0.5 to -1.0 | Notable weakness but workable | Incomplete docs, minor security gaps, some coverage gaps |
|
|
462
|
+
| **Minor** | -0.25 to -0.5 | Polish issues, best practices | Missing auto-generated docs, style inconsistencies |
|
|
463
|
+
| **Trivial** | -0.1 to -0.25 | Nitpicks | Typos, minor formatting, optional enhancements |
|
|
464
|
+
|
|
465
|
+
**Severity Assessment Questions:**
|
|
466
|
+
1. Does this block someone from using the project? → Critical
|
|
467
|
+
2. Would this cause problems in production? → Major
|
|
468
|
+
3. Does this make the project harder to use/maintain? → Moderate
|
|
469
|
+
4. Is this a nice-to-have improvement? → Minor/Trivial
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
### 🚨 MANDATORY: Deduction Evidence Requirement
|
|
474
|
+
|
|
475
|
+
**YOU CANNOT MAKE A DEDUCTION WITHOUT INLINE PROOF.**
|
|
476
|
+
|
|
477
|
+
Every deduction MUST include verification evidence in this exact format:
|
|
478
|
+
|
|
479
|
+
```markdown
|
|
480
|
+
**Deduction (-X.X) [SEVERITY]: [Claim]**
|
|
481
|
+
|
|
482
|
+
Verification:
|
|
483
|
+
```bash
|
|
484
|
+
[Command you actually ran]
|
|
485
|
+
```
|
|
486
|
+
Result:
|
|
487
|
+
> [Actual output that proves the issue exists]
|
|
488
|
+
|
|
489
|
+
Severity Justification: [Why this severity level]
|
|
490
|
+
Therefore: [Brief explanation of why this justifies deduction]
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Examples of VALID deductions:**
|
|
494
|
+
|
|
495
|
+
```markdown
|
|
496
|
+
**Deduction (-2.0) [CRITICAL]: No LICENSE file**
|
|
497
|
+
|
|
498
|
+
Verification:
|
|
499
|
+
```bash
|
|
500
|
+
ls -la LICENSE
|
|
501
|
+
```
|
|
502
|
+
Result:
|
|
503
|
+
> ls: cannot access 'LICENSE': No such file or directory
|
|
504
|
+
|
|
505
|
+
Severity Justification: Legal blocker - cannot use or distribute without license
|
|
506
|
+
Therefore: Project cannot be legally used until license is added.
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
```markdown
|
|
510
|
+
**Deduction (-0.5) [MODERATE]: SECURITY.md missing**
|
|
511
|
+
|
|
512
|
+
Verification:
|
|
513
|
+
```bash
|
|
514
|
+
ls -la SECURITY.md
|
|
515
|
+
```
|
|
516
|
+
Result:
|
|
517
|
+
> ls: cannot access 'SECURITY.md': No such file or directory
|
|
518
|
+
|
|
519
|
+
Severity Justification: Important for production but not a blocker
|
|
520
|
+
Therefore: Security reporting process should be documented.
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Examples of INVALID deductions (will be rejected):**
|
|
524
|
+
|
|
525
|
+
```markdown
|
|
526
|
+
❌ **Deduction (-0.5): Documentation seems sparse**
|
|
527
|
+
→ No verification command shown, no severity
|
|
528
|
+
|
|
529
|
+
❌ **Deduction (-0.5): Error handling could be better**
|
|
530
|
+
→ No specific file:line reference, no evidence, vague
|
|
531
|
+
|
|
532
|
+
❌ **Deduction (-0.5): No CI/CD configuration**
|
|
533
|
+
→ Must run `ls .github/workflows/` first to prove it
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**The Rule:**
|
|
537
|
+
- If you cannot show a command you ran AND its output, you cannot make the deduction
|
|
538
|
+
- "I looked at the code" is not verification - show the grep/read command
|
|
539
|
+
- Pattern-matching assumptions are not evidence - prove it with commands
|
|
540
|
+
- Severity MUST be justified - why is this Critical vs Minor?
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
### ⚠️ MANDATORY: Score Justification Format
|
|
545
|
+
|
|
546
|
+
**For EACH category, you MUST use this exact format:**
|
|
547
|
+
|
|
548
|
+
```markdown
|
|
549
|
+
### [Category Name]: X/10
|
|
550
|
+
|
|
551
|
+
**If score is 10/10:**
|
|
552
|
+
- No weaknesses identified that justify deduction
|
|
553
|
+
|
|
554
|
+
**If score is < 10/10, MUST list:**
|
|
555
|
+
- **Deduction 1 (-0.5):** [Specific issue with file:line reference]
|
|
556
|
+
- Verification: `[command run]`
|
|
557
|
+
- Result: [output proving issue]
|
|
558
|
+
- **Deduction 2 (-0.5):** [Specific issue with file:line reference]
|
|
559
|
+
- Verification: `[command run]`
|
|
560
|
+
- Result: [output proving issue]
|
|
561
|
+
- **Total deductions:** -X points → Score: Y/10
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### 🛑 STOP: Pre-Write Consistency Check
|
|
565
|
+
|
|
566
|
+
**Before writing the scorecard to .GRADING.md, answer these questions for EACH category:**
|
|
567
|
+
|
|
568
|
+
| Category | Score | Weaknesses Listed? | If "None" → Should be 10? | Deductions Justified? |
|
|
569
|
+
|----------|-------|-------------------|---------------------------|----------------------|
|
|
570
|
+
| Architecture | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
571
|
+
| Code Quality | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
572
|
+
| Security | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
573
|
+
| Testing | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
574
|
+
| Documentation | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
575
|
+
| Production Ready | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
576
|
+
| Dependencies | ?/10 | Yes/None | ✓/✗ | Yes/No |
|
|
577
|
+
|
|
578
|
+
**Rules:**
|
|
579
|
+
1. If "Weaknesses Listed?" = "None" and Score < 10 → **FIX IT** (raise to 10 or add real weakness)
|
|
580
|
+
2. If "Deductions Justified?" = "No" → **FIX IT** (verify weakness or remove deduction)
|
|
581
|
+
3. Every 0.5 point deduction needs a specific, verified issue
|
|
582
|
+
|
|
583
|
+
### Common Scoring Mistakes to Avoid
|
|
584
|
+
|
|
585
|
+
❌ **WRONG:** "Weaknesses: None significant" + Score: 9.5/10
|
|
586
|
+
✅ **RIGHT:** "Weaknesses: None significant" + Score: 10/10
|
|
587
|
+
|
|
588
|
+
❌ **WRONG:** Deducting for things out of scope (library missing health checks)
|
|
589
|
+
✅ **RIGHT:** Only deduct for issues IN SCOPE for the project type
|
|
590
|
+
|
|
591
|
+
❌ **WRONG:** Arbitrary "nothing is perfect" deductions
|
|
592
|
+
✅ **RIGHT:** Every deduction tied to a specific, verifiable issue
|
|
593
|
+
|
|
594
|
+
### 📊 Score Calibration Guide
|
|
595
|
+
|
|
596
|
+
**What each score level means (use this to calibrate):**
|
|
597
|
+
|
|
598
|
+
| Score | Grade | Meaning | Characteristics |
|
|
599
|
+
|-------|-------|---------|-----------------|
|
|
600
|
+
| 10/10 | A+ | Exemplary | Could be a reference implementation; no meaningful improvements identified |
|
|
601
|
+
| 9-9.5/10 | A | Excellent | Production-ready with minor polish opportunities |
|
|
602
|
+
| 8-8.5/10 | A-/B+ | Very Good | Production-ready but has notable gaps to address |
|
|
603
|
+
| 7-7.5/10 | B | Good | Functional, needs work before production use |
|
|
604
|
+
| 6-6.5/10 | B-/C+ | Acceptable | Significant gaps but fundamentally sound |
|
|
605
|
+
| 5-5.5/10 | C | Mediocre | Major issues, not recommended for production |
|
|
606
|
+
| <5/10 | D/F | Poor | Fundamental problems, needs substantial rework |
|
|
607
|
+
|
|
608
|
+
**Calibration Questions:**
|
|
609
|
+
- Would I recommend this for a production project? → 8+ if yes
|
|
610
|
+
- Are there any blockers to using this? → <7 if yes
|
|
611
|
+
- Is this better than typical open-source projects? → 8+ if yes
|
|
612
|
+
- Would a senior engineer approve this code? → 7+ if yes
|
|
613
|
+
|
|
614
|
+
**The 10/10 Rule (Resolving the Paradox):**
|
|
615
|
+
|
|
616
|
+
There is NO "nothing is perfect" deduction. The scoring rules are:
|
|
617
|
+
|
|
618
|
+
1. **If you find no verifiable issues → Score is 10/10**
|
|
619
|
+
- You cannot deduct points without evidence
|
|
620
|
+
- "I feel like there should be something wrong" is not a valid deduction
|
|
621
|
+
|
|
622
|
+
2. **Before giving 10/10, verify you looked thoroughly:**
|
|
623
|
+
- Did you run the tests? Check coverage gaps?
|
|
624
|
+
- Did you grep for security issues (print, yaml.load, eval)?
|
|
625
|
+
- Did you check all documentation exists?
|
|
626
|
+
- Did you verify CI/CD, type hints, function sizes?
|
|
627
|
+
|
|
628
|
+
3. **10/10 means "no verified issues found" not "perfect in theory"**
|
|
629
|
+
- A category can be 10/10 if rigorous verification found nothing wrong
|
|
630
|
+
- This is achievable for well-maintained projects
|
|
631
|
+
|
|
632
|
+
**Calibration Against Reference Projects:**
|
|
633
|
+
- requests library: ~9.5/10 (excellent API, minor gaps)
|
|
634
|
+
- Flask: ~9.0/10 (great design, some complexity)
|
|
635
|
+
- pytest: ~9.5/10 (exemplary testing, plugin system)
|
|
636
|
+
- A new/unmaintained project: typically 6-7/10
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
### Final Scorecard Format
|
|
641
|
+
|
|
642
|
+
Summary table with:
|
|
643
|
+
- Category grades (A-F scale)
|
|
644
|
+
- Numerical scores (0-10)
|
|
645
|
+
- Weighted average
|
|
646
|
+
- Overall grade
|
|
647
|
+
|
|
648
|
+
**Include the completed consistency check table in the report to prove you did it.**
|
|
649
|
+
|
|
650
|
+
**Calibration statement (required):**
|
|
651
|
+
> "This project scores [X/10] overall, which places it in the [Exemplary/Excellent/Good/etc.] tier.
|
|
652
|
+
> Compared to similar projects, it is [above average/average/below average] because [reason]."
|
|
653
|
+
|
|
654
|
+
## IMPORTANT INSTRUCTIONS
|
|
655
|
+
|
|
656
|
+
- **RUN THE TESTS** - Execute `make test.all` and `make test.coverage` BEFORE grading
|
|
657
|
+
- **Use actual data, not claims** - Don't trust README stats, verify with commands
|
|
658
|
+
- **Be analytically rigorous** - Point out actual weaknesses, not just praise
|
|
659
|
+
- **Be specific** - Include file paths, line numbers, code examples
|
|
660
|
+
- **Be actionable** - Every issue needs a concrete fix with time estimate
|
|
661
|
+
- **Use evidence** - Base assessments on actual code inspection and test results
|
|
662
|
+
- **Check for breaking issues** - Especially deprecated Python features (like `abc.abstractproperty`)
|
|
663
|
+
- **Verify security** - Look for YAML vulnerabilities, path traversal, print() in production
|
|
664
|
+
- **Measure metrics** - Count files, lines, calculate ratios from actual commands
|
|
665
|
+
- **Document test failures** - If any tests fail, this is CRITICAL for grading
|
|
666
|
+
|
|
667
|
+
**Discover project structure first:**
|
|
668
|
+
```bash
|
|
669
|
+
# Find the main package directory (look for __init__.py with exports)
|
|
670
|
+
find . -name "__init__.py" -path "*/[a-z]*/*" | head -10
|
|
671
|
+
|
|
672
|
+
# Common patterns:
|
|
673
|
+
# - src/packagename/ (src layout)
|
|
674
|
+
# - packagename/ (flat layout)
|
|
675
|
+
# - Check pyproject.toml for [tool.setuptools.packages.find]
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
Focus analysis on the discovered package structure, typically:
|
|
679
|
+
- `<package>/app/` - Application framework (if exists)
|
|
680
|
+
- `<package>/log/` - Logging system (if exists)
|
|
681
|
+
- `<package>/db/` - Database layer (if exists)
|
|
682
|
+
- `<package>/` - Core modules
|
|
683
|
+
- Root configuration files (pyproject.toml, README.md, etc.)
|
|
684
|
+
|
|
685
|
+
## COMMON PITFALLS TO AVOID
|
|
686
|
+
|
|
687
|
+
0. **MOST CRITICAL: Verify before deducting**
|
|
688
|
+
- ❌ "Documentation seems sparse" → Did you count the lines? Read the file?
|
|
689
|
+
- ❌ "No CI/CD exists" → Did you run `ls .github/workflows/`?
|
|
690
|
+
- ❌ "Error handling is weak" → Did you read the actual error handling code?
|
|
691
|
+
- ❌ "Feature X is not documented" → Did you grep for it in docs/?
|
|
692
|
+
- ✅ Every deduction requires a verification command AND its output
|
|
693
|
+
- ✅ If you can't prove it with a command, you can't deduct for it
|
|
694
|
+
|
|
695
|
+
1. **MOST CRITICAL: Actually RUN the tests**
|
|
696
|
+
- ❌ Don't just read test files and assume they pass
|
|
697
|
+
- ❌ Don't trust README coverage claims without verification
|
|
698
|
+
- ✅ Run `make test.all` to see actual test results
|
|
699
|
+
- ✅ Run `make test.coverage` to get real coverage numbers
|
|
700
|
+
- ✅ Document any test failures - this affects the grade significantly
|
|
701
|
+
- If tests fail, investigate why (missing deps, config, bugs)
|
|
702
|
+
|
|
703
|
+
2. **LICENSE File**: Always READ it, don't just check file size
|
|
704
|
+
- Use `head -20 LICENSE` to see actual content
|
|
705
|
+
- Empty or binary LICENSE file is a critical blocker
|
|
706
|
+
|
|
707
|
+
3. **Test Files**: Search in multiple locations
|
|
708
|
+
- Use `find . -name "test_*.py"` not `find infra/ -name "test_*.py"`
|
|
709
|
+
- Check `./tests/`, `./test/`, and project subdirectories
|
|
710
|
+
- Cross-reference with `pytest --collect-only` output
|
|
711
|
+
|
|
712
|
+
4. **Test Count Discrepancies**: If numbers don't match, investigate
|
|
713
|
+
- pytest may find more tests (multiple tests per file)
|
|
714
|
+
- Test files may be excluded by pytest.ini
|
|
715
|
+
- Some files may be fixtures, not actual tests
|
|
716
|
+
|
|
717
|
+
5. **Don't Trust Assumptions**: Verify with actual commands
|
|
718
|
+
- If README says "93% coverage" → RUN `coverage report` to verify
|
|
719
|
+
- If you see 11KB LICENSE → read it to confirm it's valid
|
|
720
|
+
- If `find` returns 0 results → try different search patterns
|
|
721
|
+
- Test failures reveal real issues - don't ignore them
|
|
722
|
+
|
|
723
|
+
6. **Search Pattern Mistakes**:
|
|
724
|
+
- ❌ `grep -rn "print(" infra/` - only searches infra/
|
|
725
|
+
- ✅ `grep -rn "print(" .` - searches entire repo
|
|
726
|
+
- ❌ `find infra/ -name "*.py"` - misses tests/
|
|
727
|
+
- ✅ `find . -name "*.py"` - finds all Python files
|
|
728
|
+
|
|
729
|
+
7. **Negative Claims Require Proof** (claiming something is MISSING):
|
|
730
|
+
- Before claiming "X doesn't exist" or "Y is missing", you MUST run a command to verify
|
|
731
|
+
- Examples of claims that require verification:
|
|
732
|
+
- "No CI/CD" → `ls .github/workflows/`
|
|
733
|
+
- "No security docs" → `ls SECURITY.md` and `grep -r "security" docs/`
|
|
734
|
+
- "Feature undocumented" → `grep -rn "feature_name" docs/`
|
|
735
|
+
- "No error handling" → Read the actual code with `Read` tool
|
|
736
|
+
- If your verification command finds the thing exists, DO NOT make the deduction
|
|
737
|
+
- Pattern-matching ("this looks like it might be missing") is not evidence
|
|
738
|
+
|
|
739
|
+
8. **Complexity is not a defect when it's justified**:
|
|
740
|
+
- Don't deduct for "complexity" if:
|
|
741
|
+
- The complexity solves a real problem (e.g., subprocess isolation for GIL bypass)
|
|
742
|
+
- Simpler alternatives are available (e.g., direct mode vs subprocess mode)
|
|
743
|
+
- The complexity is well-documented
|
|
744
|
+
- Ask: "Is this complexity necessary and justified?" not "Is this complex?"
|