Skip to content

feat: support fractional CPU limits in operation resources - #34

Merged
GregoryKogan merged 2 commits into
mainfrom
dev
May 27, 2026
Merged

feat: support fractional CPU limits in operation resources#34
GregoryKogan merged 2 commits into
mainfrom
dev

Conversation

@GregoryKogan

@GregoryKogan GregoryKogan commented May 27, 2026

Copy link
Copy Markdown
Owner
  • Updated the cpu_limit parameter to accept fractional values in configuration files and code, enhancing flexibility for resource allocation.
  • Revised related documentation to clarify the usage of fractional CPU limits.
  • Added unit tests to validate acceptance and rejection of various CPU limit inputs, ensuring robust error handling and compliance with new specifications.

Summary by Sourcery

Support fractional CPU limits in operation resources and configuration.

New Features:

  • Allow operation cpu_limit to be configured as a fractional number instead of only integers.

Enhancements:

  • Relax cpu_limit validation to accept any positive finite numeric value while rejecting booleans.
  • Update operation resource docs to describe fractional CPU limits and their behavior.

Documentation:

  • Clarify in map and vanilla operation docs that cpu_limit may be fractional and provide example values.

Tests:

  • Add tests covering fractional cpu_limit values from code and config, including validation of zero, negative, and boolean inputs.

- Updated the `cpu_limit` parameter to accept fractional values in configuration files and code, enhancing flexibility for resource allocation.
- Revised related documentation to clarify the usage of fractional CPU limits.
- Added unit tests to validate acceptance and rejection of various CPU limit inputs, ensuring robust error handling and compliance with new specifications.
@GregoryKogan GregoryKogan self-assigned this May 27, 2026
@sourcery-ai

sourcery-ai Bot commented May 27, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds support for fractional CPU limits in operation resources by relaxing cpu_limit validation to positive numbers (including floats), updating config parsing to use floats, extending tests to cover fractional and invalid values, and updating documentation to describe the new behavior.

Sequence diagram for fractional cpu_limit parsing and validation

sequenceDiagram
    actor User
    participant Config
    participant Common as operations_common
    participant Resources as OperationResources
    participant Validator as _require_positive_cpu_limit

    User->>Common: extract_operation_resources
    Common->>Config: resources_config["cpu_limit"]
    Common->>Common: _get_config_value_with_default
    Common->>Common: _float_from_config_value
    Common->>Resources: OperationResources(cpu_limit)
    Resources->>Resources: __post_init__
    Resources->>Validator: _require_positive_cpu_limit(cpu_limit)
Loading

File-Level Changes

Change Details Files
Relax cpu_limit validation to allow positive fractional values and reject invalid types/values with clear errors.
  • Introduce _require_positive_cpu_limit validator that accepts ints and floats, rejects bools, non-numeric types, non-positive values, and non-finite numbers with specific error messages.
  • Switch OperationResources.post_init to use the new CPU-specific validator instead of the generic positive-resource validator.
  • Update OperationResources dataclass annotation so cpu_limit is typed as float and adjust the docstring to describe cpu_limit as a positive number allowing fractional cores.
yt_framework/yt/support/operation_resources.py
Ensure configuration parsing supports fractional cpu_limit values.
  • Add _float_from_config_value helper mirroring the existing int conversion helper.
  • Use the float conversion helper when reading cpu_limit from the resources configuration while leaving other fields unchanged.
  • Add a test that verifies extract_operation_resources correctly parses a fractional cpu_limit from the top-level config.
yt_framework/operations/common.py
tests/test_common.py
Strengthen unit tests around cpu_limit validation semantics, including fractional and invalid values.
  • Update the existing cpu_limit validation test to expect the new, more general error message wording for non-positive CPU limits.
  • Add tests ensuring fractional cpu_limit values are accepted while zero and negative fractional values raise ValueError, and bool cpu_limit raises TypeError.
tests/test_client_base.py
Document support for fractional cpu_limit values in operation resource examples and guidelines.
  • Update map operation docs to show cpu_limit as fractional-capable and explain that fractional values are passed through to YTsaurus.
  • Update vanilla operation docs to mention fractional cpu_limit in examples and resource guidelines, clarifying that more cores (including fractional) increase performance.
docs/operations/map.md
docs/operations/vanilla.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The OperationResources docstring now states that a non-positive cpu_limit raises ValueError, but _require_positive_cpu_limit raises TypeError for non-numeric (e.g., bool) inputs; consider aligning the documented and actual exception types or clarifying this distinction in the docstring.
  • Since _require_positive_cpu_limit explicitly guards against non-finite values with math.isfinite, it would be useful to add tests covering float('inf'), float('-inf'), and float('nan') to validate the intended behavior for these edge cases.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `OperationResources` docstring now states that a non-positive `cpu_limit` raises `ValueError`, but `_require_positive_cpu_limit` raises `TypeError` for non-numeric (e.g., bool) inputs; consider aligning the documented and actual exception types or clarifying this distinction in the docstring.
- Since `_require_positive_cpu_limit` explicitly guards against non-finite values with `math.isfinite`, it would be useful to add tests covering `float('inf')`, `float('-inf')`, and `float('nan')` to validate the intended behavior for these edge cases.

## Individual Comments

### Comment 1
<location path="yt_framework/operations/common.py" line_range="41-42" />
<code_context>
     return int(cast("Any", value))


+def _float_from_config_value(value: object) -> float:
+    return float(cast("Any", value))
+
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Boolean config values are now silently accepted as cpu_limit, bypassing the bool check in `_require_positive_cpu_limit`.

With `_float_from_config_value`, `true`/`false` from config become `1.0`/`0.0` and then pass `_require_positive_cpu_limit`, since the bool check only happens after conversion. Direct construction `OperationResources(cpu_limit=True)` still raises, so config vs constructor behavior diverges. To keep semantics consistent and reject bools in both paths, consider explicitly disallowing bools in `_float_from_config_value` (or using a helper that preserves `_require_positive_cpu_limit`’s type check).
</issue_to_address>

### Comment 2
<location path="tests/test_common.py" line_range="47-53" />
<code_context>
     assert res.cpu_limit == 8


+def test_extract_operation_resources_parses_fractional_cpu_limit() -> None:
+    cfg = OmegaConf.create({"cpu_limit": 0.5})
+    res = extract_operation_resources(cfg, _LOG)
+    assert res.cpu_limit == 0.5
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Consider adding a test for fractional cpu_limit inside the nested `resources` block as well.

Since `extract_operation_resources` also reads `resources.cpu_limit`, please add a sibling test using `OmegaConf.create({"resources": {"cpu_limit": 0.5}})` and asserting the extracted `cpu_limit` is `0.5`, to confirm nested configs follow the same semantics.

```suggestion
def test_extract_operation_resources_parses_fractional_cpu_limit() -> None:
    cfg = OmegaConf.create({"cpu_limit": 0.5})
    res = extract_operation_resources(cfg, _LOG)
    assert res.cpu_limit == 0.5


def test_extract_operation_resources_parses_fractional_cpu_limit_in_nested_resources() -> None:
    cfg = OmegaConf.create({"resources": {"cpu_limit": 0.5}})
    res = extract_operation_resources(cfg, _LOG)
    assert res.cpu_limit == 0.5


def test_extract_operation_resources_reads_nested_resources_block() -> None:
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +41 to +42
def _float_from_config_value(value: object) -> float:
return float(cast("Any", value))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Boolean config values are now silently accepted as cpu_limit, bypassing the bool check in _require_positive_cpu_limit.

With _float_from_config_value, true/false from config become 1.0/0.0 and then pass _require_positive_cpu_limit, since the bool check only happens after conversion. Direct construction OperationResources(cpu_limit=True) still raises, so config vs constructor behavior diverges. To keep semantics consistent and reject bools in both paths, consider explicitly disallowing bools in _float_from_config_value (or using a helper that preserves _require_positive_cpu_limit’s type check).

Comment thread tests/test_common.py
Comment on lines +47 to 53
def test_extract_operation_resources_parses_fractional_cpu_limit() -> None:
cfg = OmegaConf.create({"cpu_limit": 0.5})
res = extract_operation_resources(cfg, _LOG)
assert res.cpu_limit == 0.5


def test_extract_operation_resources_reads_nested_resources_block() -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): Consider adding a test for fractional cpu_limit inside the nested resources block as well.

Since extract_operation_resources also reads resources.cpu_limit, please add a sibling test using OmegaConf.create({"resources": {"cpu_limit": 0.5}}) and asserting the extracted cpu_limit is 0.5, to confirm nested configs follow the same semantics.

Suggested change
def test_extract_operation_resources_parses_fractional_cpu_limit() -> None:
cfg = OmegaConf.create({"cpu_limit": 0.5})
res = extract_operation_resources(cfg, _LOG)
assert res.cpu_limit == 0.5
def test_extract_operation_resources_reads_nested_resources_block() -> None:
def test_extract_operation_resources_parses_fractional_cpu_limit() -> None:
cfg = OmegaConf.create({"cpu_limit": 0.5})
res = extract_operation_resources(cfg, _LOG)
assert res.cpu_limit == 0.5
def test_extract_operation_resources_parses_fractional_cpu_limit_in_nested_resources() -> None:
cfg = OmegaConf.create({"resources": {"cpu_limit": 0.5}})
res = extract_operation_resources(cfg, _LOG)
assert res.cpu_limit == 0.5
def test_extract_operation_resources_reads_nested_resources_block() -> None:

- Introduced a new `validate_cpu_limit` function to ensure `cpu_limit` values are positive finite numbers and not of type `bool`.
- Added unit tests to validate rejection of non-finite and boolean CPU limit values, improving error handling and robustness.
- Updated existing tests to reflect changes in CPU limit validation logic, ensuring comprehensive coverage.
@GregoryKogan
GregoryKogan merged commit 1b91965 into main May 27, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant