Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ogenstad
Copy link
Contributor

@ogenstad ogenstad commented Oct 14, 2025

Mainly an update to pyproject.toml to have Ruff target Python 3.12 as we don't support Infrahub on earlier versions.

The other changes are to introduce new ruff violations due to this along with a number of automated changes to align with our current version of Python.

Summary by CodeRabbit

  • Refactor
    • Modernized codebase to use Python 3.12+ type system features and updated internal type annotations for improved maintainability.

@github-actions github-actions bot added the group/backend Issue related to the backend (API Server, Git Agent) label Oct 14, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

Walkthrough

This pull request modernizes Python typing syntax and enum declarations across the codebase. Multiple enum classes are converted from (str, Enum) to StrEnum for consistency. Generic class and function signatures are updated to use modern PEP 695 syntax, removing explicit Generic inheritance in favor of bracket notation. Type alias declarations are simplified by removing TypeAlias annotations. The project's target Python version is incremented from 3.10 to 3.12 in pyproject.toml, along with adjustments to linting rules. Additionally, a few enum members are added, and imports are reorganized accordingly.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Switch ruff to target Python 3.12" is clear, specific, and directly related to a real part of the changeset. It correctly captures the stated primary objective from the PR: updating pyproject.toml to change the Ruff target version from Python 3.10 to 3.12. However, the title does not fully capture the substantive scope of the changeset, which includes extensive code modernization across dozens of files (StrEnum conversions, PEP 695 generic syntax, TypeAlias removals) that represent the majority of the changes. While these code changes are driven by and aligned with the Python 3.12 target, the title focuses narrowly on the configuration change rather than the broader code modernization effort.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pog-ruff-target-python3.12

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 14, 2025

CodSpeed Performance Report

Merging #7387 will not alter performance

Comparing pog-ruff-target-python3.12 (1dc94a1) with develop (77d439f)

Summary

✅ 10 untouched

@ogenstad ogenstad force-pushed the pog-ruff-target-python3.12 branch from a65f990 to 3d811e5 Compare October 14, 2025 14:46
@ogenstad ogenstad force-pushed the pog-ruff-target-python3.12 branch from 3d811e5 to 1dc94a1 Compare October 23, 2025 18:27
@ogenstad ogenstad marked this pull request as ready for review October 28, 2025 15:14
@ogenstad ogenstad requested a review from a team as a code owner October 28, 2025 15:14
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
pyproject.toml (1)

24-24: Python version constraint is verbose but correct.

The constraint "^3.12, < 3.13" is logically equivalent to "^3.12" alone, since the caret operator (^) already caps the major version. While the explicit upper bound is clear and acceptable, you could simplify to python = "^3.12" for conciseness. This is optional.

backend/infrahub/dependencies/interface.py (2)

3-3: Remove the redundant TypeVar import.

With PEP 695 syntax (Python 3.12+), the TypeVar import is no longer needed since type parameters are declared inline in the class signature.

Apply this diff:

-from typing import TypeVar
+from typing import TYPE_CHECKING

Note: Only keep the typing import if other typing constructs are needed elsewhere in the file.


8-8: Remove the redundant TypeVar declaration.

With PEP 695 syntax at line 17, this separate TypeVar declaration is no longer needed. The type parameter T is now declared inline in the class signature.

Apply this diff:

-T = TypeVar("T")
-
backend/infrahub/validators/tasks.py (1)

12-12: Remove the redundant TypeVar declaration.

With PEP 695 syntax at line 15, this separate TypeVar declaration is no longer needed. The type parameter with bound constraint is now declared inline in the function signature as [ValidatorType: CoreValidator].

Apply this diff:

-ValidatorType = TypeVar("ValidatorType", bound=CoreValidator)
-
backend/infrahub/core/diff/model/diff.py (1)

280-281: Consider migrating ModifiedPathType to StrEnum.

ModifiedPathType has a string value member (DATA = "data") but wasn't migrated to StrEnum in this refactor. For consistency with the rest of the codebase changes, this enum could also benefit from using StrEnum instead of plain Enum.

-class ModifiedPathType(Enum):
+class ModifiedPathType(StrEnum):
     DATA = "data"
backend/infrahub/utils.py (1)

79-85: Modern generic syntax applied correctly.

The PEP 695 syntax improves the function signature. Note that the module-level TypeVar at line 8 appears unused now and could be removed if no other code references it.

If AnyClass at line 8 isn't used elsewhere, consider removing it:

-AnyClass = TypeVar("AnyClass", bound=type)
-
-
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77d439f and 1dc94a1.

📒 Files selected for processing (24)
  • backend/infrahub/auth.py (2 hunks)
  • backend/infrahub/cli/db.py (2 hunks)
  • backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py (2 hunks)
  • backend/infrahub/config.py (5 hunks)
  • backend/infrahub/constants/database.py (2 hunks)
  • backend/infrahub/core/diff/model/diff.py (2 hunks)
  • backend/infrahub/core/graph/constraints.py (2 hunks)
  • backend/infrahub/core/manager.py (1 hunks)
  • backend/infrahub/core/node/node_property_attribute.py (2 hunks)
  • backend/infrahub/core/schema/__init__.py (2 hunks)
  • backend/infrahub/core/validators/enum.py (1 hunks)
  • backend/infrahub/dependencies/interface.py (2 hunks)
  • backend/infrahub/events/constants.py (1 hunks)
  • backend/infrahub/graphql/analyzer.py (3 hunks)
  • backend/infrahub/graphql/mutations/relationship.py (2 hunks)
  • backend/infrahub/patch/constants.py (1 hunks)
  • backend/infrahub/telemetry/constants.py (1 hunks)
  • backend/infrahub/trigger/models.py (2 hunks)
  • backend/infrahub/utils.py (1 hunks)
  • backend/infrahub/validators/tasks.py (1 hunks)
  • models/infrastructure_edge.py (2 hunks)
  • pyproject.toml (2 hunks)
  • python_testcontainers/infrahub_testcontainers/models.py (1 hunks)
  • tasks/shared.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
backend/**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run backend tests with pytest or via invoke tasks

Files:

  • backend/infrahub/dependencies/interface.py
  • backend/infrahub/core/graph/constraints.py
  • backend/infrahub/auth.py
  • backend/infrahub/graphql/analyzer.py
  • backend/infrahub/core/manager.py
  • backend/infrahub/core/schema/__init__.py
  • backend/infrahub/core/node/node_property_attribute.py
  • backend/infrahub/cli/db.py
  • backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py
  • backend/infrahub/core/validators/enum.py
  • backend/infrahub/events/constants.py
  • backend/infrahub/core/diff/model/diff.py
  • backend/infrahub/telemetry/constants.py
  • backend/infrahub/graphql/mutations/relationship.py
  • backend/infrahub/trigger/models.py
  • backend/infrahub/config.py
  • backend/infrahub/constants/database.py
  • backend/infrahub/patch/constants.py
  • backend/infrahub/utils.py
  • backend/infrahub/validators/tasks.py
**/*.py

📄 CodeRabbit inference engine (.github/instructions/python-docstring.instructions.md)

**/*.py: Use triple double quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include a brief one-line description at the top of each docstring
Add a detailed description section when additional context is needed
Document function/method parameters under an Args/Parameters section without typing information
Include a Returns section describing the return value
Include a Raises section listing possible exceptions
Provide an Examples section demonstrating usage when helpful

Use ruff and mypy to validate and lint Python files

**/*.py: Use type hints for all Python function parameters and return values
Prefer asynchronous code in Python when feasible
Define asynchronous Python functions with async def
Use await for asynchronous calls in Python
Use Pydantic models instead of standard dataclasses
Use ruff and mypy for linting and type checking

**/*.py: Use type hints for all Python function parameters and return values
Use async/await whenever possible in Python code
Define asynchronous functions with async def
Await asynchronous calls with await
Use Pydantic models instead of standard dataclasses for data modeling
Use triple quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include docstring sections when applicable: one-line summary, optional details, Args (without types), Returns, Raises, Examples
Validate and lint Python with ruff and mypy

Files:

  • backend/infrahub/dependencies/interface.py
  • backend/infrahub/core/graph/constraints.py
  • backend/infrahub/auth.py
  • backend/infrahub/graphql/analyzer.py
  • backend/infrahub/core/manager.py
  • backend/infrahub/core/schema/__init__.py
  • backend/infrahub/core/node/node_property_attribute.py
  • backend/infrahub/cli/db.py
  • models/infrastructure_edge.py
  • backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py
  • backend/infrahub/core/validators/enum.py
  • backend/infrahub/events/constants.py
  • backend/infrahub/core/diff/model/diff.py
  • backend/infrahub/telemetry/constants.py
  • backend/infrahub/graphql/mutations/relationship.py
  • tasks/shared.py
  • backend/infrahub/trigger/models.py
  • backend/infrahub/config.py
  • python_testcontainers/infrahub_testcontainers/models.py
  • backend/infrahub/constants/database.py
  • backend/infrahub/patch/constants.py
  • backend/infrahub/utils.py
  • backend/infrahub/validators/tasks.py
{pyproject.toml,poetry.lock}

📄 CodeRabbit inference engine (.github/instructions/tooling.instructions.md)

Use Poetry to manage the Python project and its dependencies

Files:

  • pyproject.toml
pyproject.toml

📄 CodeRabbit inference engine (CLAUDE.md)

Use Poetry to manage the Python project and dependencies

Files:

  • pyproject.toml
🧠 Learnings (1)
📚 Learning: 2025-10-09T13:23:41.482Z
Learnt from: CR
PR: opsmill/infrahub#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-09T13:23:41.482Z
Learning: Applies to **/*.py : Validate and lint Python with ruff and mypy

Applied to files:

  • pyproject.toml
🧬 Code graph analysis (4)
backend/infrahub/core/manager.py (3)
backend/infrahub/core/node/__init__.py (1)
  • get_schema (106-107)
backend/infrahub/api/schema.py (1)
  • get_schema (176-208)
backend/infrahub/core/protocols_base.py (1)
  • get_schema (74-74)
backend/infrahub/core/schema/__init__.py (5)
backend/infrahub/core/schema/node_schema.py (1)
  • NodeSchema (15-150)
backend/infrahub/core/protocols_base.py (3)
  • NodeSchema (19-19)
  • ProfileSchema (23-23)
  • TemplateSchema (27-27)
backend/infrahub/core/schema/profile_schema.py (1)
  • ProfileSchema (9-46)
backend/infrahub/core/schema/template_schema.py (1)
  • TemplateSchema (9-44)
backend/infrahub/core/schema/generic_schema.py (1)
  • GenericSchema (14-54)
tasks/shared.py (1)
backend/infrahub/constants/database.py (1)
  • DatabaseType (4-6)
backend/infrahub/constants/database.py (1)
tasks/shared.py (1)
  • DatabaseType (20-22)
🔇 Additional comments (30)
pyproject.toml (4)

462-462: Ruff target-version correctly updated to py312.

The target version now aligns with the updated Python version constraint. This ensures ruff linting rules are calibrated to Python 3.12 features and syntax.


752-757: New per-file ignore for async file operations in test_schema_migration.py.

The ASYNC230 rule (async functions opening files with blocking methods) is now specifically ignored for this test file. Verify that this is the intended behavior—i.e., that blocking file I/O in async tests is unavoidable or acceptable in this context.


42-42: Python 3.12 compatibility: conditional tomli dependency is correct.

The tomli dependency (line 42) is correctly gated behind python = "<3.11", so it will not be installed for Python 3.12+ (which includes tomllib in the standard library). The ruff target-version update on line 462 is aligned with this change.

Also applies to: 462-462


734-750: ASYNC109 rule is valid and appropriately applied for the test file.

All rules verified:

  • ASYNC109 is a valid rule in ruff 0.11.9 that checks for async functions with timeout parameters and enforces structured concurrency patterns—appropriate to silence in tests.
  • PT rules (PT003, PT006, PT007, PT011, PT012, PT013, PT018, PT021) all exist and are correctly applied to the test-specific file backend/tests/integration_docker/test_schema_migration.py in the per-file-ignores section.
  • All rules are marked with the comment "Review and change the below later," indicating they are intentionally silenced pending future review.

The configuration is valid and consistent with ruff 0.11.9.

backend/infrahub/events/constants.py (1)

1-8: LGTM! Clean migration to StrEnum.

The conversion from (str, Enum) to StrEnum is the idiomatic approach for string-based enums in Python 3.11+. This change aligns with the PR's objective to modernize the codebase for Python 3.12.

backend/infrahub/dependencies/interface.py (1)

17-20: LGTM! Proper use of PEP 695 generic class syntax.

The modernized syntax class DependencyBuilder[T](ABC): is the idiomatic way to declare generic classes in Python 3.12+.

tasks/shared.py (2)

7-7: LGTM! Clean migration to StrEnum.

The conversion from (str, Enum) to StrEnum for DatabaseType is the idiomatic approach for string-based enums in Python 3.12+.

Also applies to: 20-22


25-29: LGTM! Enum modernization with new member.

The conversion to StrEnum is correct. The new DEBUG = "debug" member appears to be a legitimate addition to the namespace options.

backend/infrahub/validators/tasks.py (1)

15-40: LGTM! Proper use of PEP 695 generic function syntax.

The modernized syntax async def start_validator[ValidatorType: CoreValidator](...) is the idiomatic way to declare generic functions with bounded type parameters in Python 3.12+.

backend/infrahub/telemetry/constants.py (1)

1-9: LGTM! Clean migration to StrEnum.

The conversion from (str, Enum) to StrEnum is the idiomatic approach for string-based enums in Python 3.11+. This change aligns with the PR's objective to modernize the codebase for Python 3.12.

python_testcontainers/infrahub_testcontainers/models.py (1)

2-12: LGTM! Clean migration to StrEnum.

The conversion from (str, Enum) to StrEnum is the idiomatic approach for string-based enums in Python 3.11+. This change aligns with the PR's objective to modernize the codebase for Python 3.12.

backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py (1)

2-16: LGTM! Clean migration to StrEnum.

The conversion from (str, Enum) to StrEnum is the idiomatic approach for string-based enums in Python 3.11+. This change aligns with the PR's objective to modernize the codebase for Python 3.12.

backend/infrahub/cli/db.py (1)

9-9: LGTM! Clean migration to StrEnum.

The conversion from (str, Enum) to StrEnum for both ConstraintAction and IndexAction is the idiomatic approach for string-based enums in Python 3.11+. This change aligns with the PR's objective to modernize the codebase for Python 3.12.

Also applies to: 78-87

backend/infrahub/graphql/mutations/relationship.py (1)

3-3: LGTM: Clean migration to StrEnum.

The migration from (str, Enum) to StrEnum is correct and maintains equivalent runtime behavior while adopting modern Python 3.12 best practices for string-based enumerations.

Also applies to: 51-54

backend/infrahub/core/node/node_property_attribute.py (1)

5-5: LGTM: Modern PEP 695 generic syntax adopted.

The migration from Generic[T] inheritance to bracket notation [T] is correct and leverages Python 3.12's PEP 695 syntax for cleaner generic type declarations without changing runtime behavior.

Also applies to: 24-24

backend/infrahub/core/validators/enum.py (1)

1-1: LGTM: ConstraintIdentifier correctly migrated to StrEnum.

The migration maintains all enum members and their string values while adopting the modern StrEnum base class, consistent with the codebase-wide refactor to Python 3.12.

Also applies to: 4-12

backend/infrahub/core/diff/model/diff.py (1)

3-3: LGTM: DiffElementType migrated to StrEnum.

The DiffElementType enum correctly adopts StrEnum for its string-based members, maintaining consistency with the broader codebase refactor.

Also applies to: 274-277

backend/infrahub/patch/constants.py (1)

1-1: LGTM: PatchPlanFilename cleanly migrated to StrEnum.

The migration correctly updates this filename enumeration to use StrEnum, maintaining all member values while adopting modern Python 3.12 conventions.

Also applies to: 4-13

backend/infrahub/auth.py (1)

5-5: LGTM: AuthType correctly migrated to StrEnum.

The authentication type enumeration has been properly migrated to StrEnum, maintaining all member values (NONE, JWT, API) while modernizing the type declaration for Python 3.12.

Also applies to: 38-41

backend/infrahub/core/graph/constraints.py (1)

3-3: LGTM: GraphPropertyType migrated to StrEnum.

The graph property type enumeration has been correctly updated to use StrEnum, maintaining all database type string values while adopting Python 3.12 best practices.

Also applies to: 15-20

models/infrastructure_edge.py (1)

6-6: LGTM: DevicePatternName migrated to StrEnum.

The device pattern enumeration correctly adopts StrEnum for its string-based device type members (LEAF, CORE, EDGE), maintaining consistency with the codebase-wide Python 3.12 modernization.

Also applies to: 447-450

backend/infrahub/core/manager.py (1)

62-67: LGTM! Modern generic function syntax.

The migration to PEP 695 generic function syntax is correct and improves readability.

backend/infrahub/trigger/models.py (1)

4-4: LGTM! Clean StrEnum migration.

The switch from (str, Enum) to StrEnum is a good modernization that simplifies the enum declaration.

Also applies to: 33-33

backend/infrahub/constants/database.py (1)

1-1: LGTM! Consistent StrEnum migration with new runtime options.

All enum classes correctly migrated to StrEnum. The new Neo4jRuntime members (PIPELINED and PARALLEL) align with Neo4j's available runtime options.

Also applies to: 4-6, 9-15, 18-22, 25-27

backend/infrahub/graphql/analyzer.py (1)

6-6: LGTM! StrEnum migration with properly integrated new members.

The enum migrations are consistent, and the new members (ContextType.OBJECT and GraphQLOperation.UNDEFINED) are properly integrated into the class methods and default values.

Also applies to: 52-73, 83-98

backend/infrahub/core/schema/__init__.py (1)

4-4: LGTM! Type alias syntax modernized.

The simplified type alias syntax (removing TypeAlias annotations) aligns with Python 3.12 best practices and maintains the same type information.

Also applies to: 24-25

backend/infrahub/config.py (4)

6-8: LGTM! Correct imports for Python 3.12.

The tomllib import is correct for Python 3.11+ (standard library) and the StrEnum import enables cleaner enum declarations.


51-172: LGTM! Comprehensive StrEnum migration.

All enum classes consistently migrated from (str, Enum) to StrEnum, improving code clarity and leveraging Python 3.11+ features.


815-822: LGTM! New enterprise features property properly implemented.

The enterprise_features computed property correctly derives enabled features from the policy settings and is properly exposed at both the PolicySettings and Settings levels.

Also applies to: 965-967


983-983: LGTM! Correct usage of tomllib.

The tomllib.loads() usage is appropriate for Python 3.11+ where tomllib is part of the standard library.

Comment on lines +20 to 22
class DatabaseType(StrEnum):
NEO4J = "neo4j"
MEMGRAPH = "memgraph"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify: Potential duplication of DatabaseType enum.

The DatabaseType enum with identical members (NEO4J, MEMGRAPH) also exists in backend/infrahub/constants/database.py. Consider consolidating to a single definition and importing where needed to avoid maintenance issues.

Run the following script to check if these enums should be consolidated:


🏁 Script executed:

#!/bin/bash
# Search for DatabaseType enum definitions
ast-grep --pattern 'class DatabaseType($$$) {
  $$$
}'

Length of output: 0


I'll search for all DatabaseType enum definitions more broadly to verify the duplication claim.


🏁 Script executed:

#!/bin/bash
# Search for all DatabaseType class definitions
echo "=== Searching for DatabaseType definitions ==="
rg -n "class DatabaseType" -A 3

echo ""
echo "=== Searching for imports of DatabaseType ==="
rg -n "from.*DatabaseType|import.*DatabaseType" -C 2

Length of output: 4420


🏁 Script executed:

#!/bin/bash
# Check if tasks/shared.py imports DatabaseType from anywhere
echo "=== Imports at top of tasks/shared.py ==="
head -30 tasks/shared.py | rg -n "import|from"

echo ""
echo "=== All DatabaseType usages in tasks/shared.py ==="
rg -n "DatabaseType" tasks/shared.py

Length of output: 977


Remove duplicate DatabaseType enum and import from canonical location.

The DatabaseType enum is duplicated in tasks/shared.py (lines 20-22) and already defined canonically in backend/infrahub/constants/database.py. Since tasks/shared.py uses DatabaseType in 8 places and tasks/release.py in the same directory successfully imports from infrahub.constants.database, consolidate by:

  1. Remove the local enum definition (lines 20-22)
  2. Add from infrahub.constants.database import DatabaseType to imports
🤖 Prompt for AI Agents
In tasks/shared.py around lines 20 to 22, remove the duplicated local
DatabaseType enum definition and instead import the canonical one; delete the
class DatabaseType block (lines 20-22) and add an import line at the top: from
infrahub.constants.database import DatabaseType, then run a quick search to
ensure all local references continue to work (no further changes needed since
tasks/release.py already imports from infrahub.constants.database).

@ogenstad ogenstad merged commit 64537b7 into develop Oct 29, 2025
125 of 130 checks passed
@ogenstad ogenstad deleted the pog-ruff-target-python3.12 branch October 29, 2025 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/backend Issue related to the backend (API Server, Git Agent)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants