Skip to content

test(consistent): preserve legacy parameterized semantics#5388

Closed
njzjz-bot wants to merge 1 commit intodeepmodeling:masterfrom
njzjz-bot:fix/parameterized-legacy-semantics
Closed

test(consistent): preserve legacy parameterized semantics#5388
njzjz-bot wants to merge 1 commit intodeepmodeling:masterfrom
njzjz-bot:fix/parameterized-legacy-semantics

Conversation

@njzjz-bot
Copy link
Copy Markdown
Contributor

@njzjz-bot njzjz-bot commented Apr 10, 2026

Summary

Why

In the review discussion for #5378, option A was to keep the original parameterized() behavior stable and introduce a separate helper for curated-case suites. This PR implements that split directly:

  • existing users of parameterized() keep the old behavior
  • heavy consistency suites move to parameterized_cases()

That keeps the CI-matrix reduction and reviewable curated coverage from #5378 without changing legacy semantics for unrelated tests.

Notes

Authored by OpenClaw (model: gpt-5.4)

Summary by CodeRabbit

  • Tests
    • Introduced a new parameterized_cases decorator for flexible test parameterization.
    • Refactored test suites to use curated case sets instead of automatic Cartesian product generation, improving test clarity and targeting specific coverage scenarios.
    • Updated multiple descriptor test modules with structured, reusable test case definitions.

Adopt the curated descriptor matrices from PR deepmodeling#5378, keep the new parameterized_cases helper, and preserve the legacy parameterized() class-name behavior for existing tests.

This follows option A from review discussion: add an explicit helper for curated cases without changing the original Cartesian-product helper semantics.

Authored by OpenClaw (model: gpt-5.4)
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a new parameterized_cases decorator for structured test parameterization and migrates four test files from inline Cartesian-product parameter tuples to a curated case-based approach. The changes standardize parameter management across descriptor tests while maintaining existing test coverage.

Changes

Cohort / File(s) Summary
Core Parameterization Infrastructure
source/tests/consistent/common.py
Added parameterized_cases decorator and _parameterized_with_cases helper function for generating test subclasses from explicit parameter tuples. Includes dynamic name sanitization (replacing non-alphanumeric characters with underscores) and numeric suffix collision handling. Updated __all__ to export parameterize_func, parameterized, and parameterized_cases.
DPA1 Test Migration
source/tests/consistent/descriptor/test_dpa1.py
Replaced @parameterized(...) with @parameterized_cases(*DPA1_CURATED_CASES). Added DPA1_CASE_FIELDS, DPA1_BASELINE_CASE, dpa1_case() helper, and DPA1_CURATED_CASES to centralize and curate parameter combinations across TestDPA1 and TestDPA1DescriptorAPI classes.
DPA2 Test Migration
source/tests/consistent/descriptor/test_dpa2.py
Replaced @parameterized(...) with @parameterized_cases(*DPA2_CURATED_CASES). Added structured case definitions and modified parameter usage: set_davg_zero is now sourced from parameters instead of hardcoded to True. Updated tuple unpacking order for repformer_direct_dist and repformer_update_g1_has_conv retrieval.
SE A Test Migration
source/tests/consistent/descriptor/test_se_e2_a.py
Consolidated three separate @parameterized(...) decorators across TestSeA, TestSeADescriptorAPI, and TestSeAStat into structured case definitions: SE_A_CURATED_CASES, SE_A_DESCRIPTOR_API_CASES, and SE_A_STAT_CASES. Added SE_A_CASE_FIELDS, SE_A_BASELINE_CASE, and se_a_case() helper for deterministic parameter ordering and targeted override combinations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'preserve legacy parameterized semantics' clearly and concisely summarizes the main change: introducing a new parameterized_cases() decorator while maintaining backward compatibility with the existing parameterized() behavior.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
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: 2

🧹 Nitpick comments (1)
source/tests/consistent/common.py (1)

779-797: Consider adding a shared validated case-builder next to parameterized_cases().

The new decorator is shared, but DPA1/DPA2/SeA each still carry their own *_CASE_FIELDS / baseline / *_case() trio. A small helper here that materializes tuples from a baseline and rejects unknown override keys would remove that duplication and turn typoed overrides into immediate failures instead of silently shrinking curated coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/tests/consistent/common.py` around lines 779 - 797, Add a shared,
validated case-builder to centralize the pattern used by DPA1/DPA2/SeA:
implement a helper (e.g., build_validated_cases or make_case_tuples) adjacent to
parameterized_cases that takes a baseline mapping, a list of override dicts, and
an explicit allowed/ordered field list (the current *_CASE_FIELDS), validates
that each override contains only known keys (raise on unknown keys), merges
overrides into the baseline in the specified field order and returns tuples
suitable for _parameterized_with_cases; update DPA1/DPA2/SeA to call this helper
instead of duplicating their baseline/ *_case() trio so typos in override keys
fail fast and tuple ordering remains consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@source/tests/consistent/descriptor/test_dpa1.py`:
- Around line 83-126: The curated cases all inherit smooth_type_embedding=True
from DPA1_BASELINE_CASE which causes skip_tf() to exclude TensorFlow tests;
update DPA1_CURATED_CASES to include at least one TF-compatible entry by calling
dpa1_case(...) with smooth_type_embedding=False (e.g. add
dpa1_case(smooth_type_embedding=False) or another existing case variant that
specifies smooth_type_embedding=False) so TestDPA1.test_tf_* can run.

In `@source/tests/consistent/descriptor/test_dpa2.py`:
- Line 275: The tuple destructures in test_dpa2.py include an unused binding
repformer_update_g1_has_conv which triggers linter errors; update each
destructure (including the occurrences around the listed sites) to either remove
that element from the unpack pattern if not needed or rename it to
_repformer_update_g1_has_conv to mark it intentionally ignored (search for
repformer_update_g1_has_conv in the file and adjust the unpack in the helper
calls such as the tuples used by the methods that only use precision or nothing
from self.param), then run ruff check . to ensure no remaining unused-binding
warnings.

---

Nitpick comments:
In `@source/tests/consistent/common.py`:
- Around line 779-797: Add a shared, validated case-builder to centralize the
pattern used by DPA1/DPA2/SeA: implement a helper (e.g., build_validated_cases
or make_case_tuples) adjacent to parameterized_cases that takes a baseline
mapping, a list of override dicts, and an explicit allowed/ordered field list
(the current *_CASE_FIELDS), validates that each override contains only known
keys (raise on unknown keys), merges overrides into the baseline in the
specified field order and returns tuples suitable for _parameterized_with_cases;
update DPA1/DPA2/SeA to call this helper instead of duplicating their baseline/
*_case() trio so typos in override keys fail fast and tuple ordering remains
consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0b67d4e7-e263-4e27-b5f4-17b2c62ceeb9

📥 Commits

Reviewing files that changed from the base of the PR and between d7ee913 and bfdb116.

📒 Files selected for processing (4)
  • source/tests/consistent/common.py
  • source/tests/consistent/descriptor/test_dpa1.py
  • source/tests/consistent/descriptor/test_dpa2.py
  • source/tests/consistent/descriptor/test_se_e2_a.py

Comment on lines +83 to 126
DPA1_BASELINE_CASE = {
"tebd_dim": 4,
"tebd_input_mode": "concat",
"resnet_dt": True,
"type_one_side": True,
"attn": 20,
"attn_layer": 2,
"attn_dotr": True,
"excluded_types": [],
"env_protection": 0.0,
"set_davg_zero": True,
"scaling_factor": 1.0,
"normalize": True,
"temperature": 1.0,
"ln_eps": 1e-5,
"smooth_type_embedding": True,
"concat_output_tebd": True,
"precision": "float64",
"use_econf_tebd": False,
"use_tebd_bias": False,
}


def dpa1_case(**overrides: Any) -> tuple:
case = DPA1_BASELINE_CASE | overrides
return tuple(case[field] for field in DPA1_CASE_FIELDS)


DPA1_CURATED_CASES = (
# Baseline coverage.
dpa1_case(),
# Alternate tebd input plumbing.
dpa1_case(tebd_input_mode="strip"),
# High-risk descriptor toggles.
dpa1_case(excluded_types=[[0, 1]]),
dpa1_case(set_davg_zero=False),
dpa1_case(normalize=False),
# Attention edge cases: disabled temperature path vs zero-layer path.
dpa1_case(temperature=None),
dpa1_case(attn_layer=0, temperature=None),
# econf-specific path with both tebd input modes.
dpa1_case(use_econf_tebd=True),
dpa1_case(tebd_input_mode="strip", use_econf_tebd=True),
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The curated DPA1 matrix now skips TensorFlow entirely.

skip_tf() treats smooth_type_embedding=True as unsupported, and every entry in DPA1_CURATED_CASES inherits that value from the baseline. So TestDPA1.test_tf_* will never execute anymore. Add at least one TF-compatible curated case if this suite is still supposed to cover TensorFlow.

💡 Minimal fix
 DPA1_CURATED_CASES = (
     # Baseline coverage.
     dpa1_case(),
+    # Keep one TF-compatible case alive.
+    dpa1_case(smooth_type_embedding=False),
     # Alternate tebd input plumbing.
     dpa1_case(tebd_input_mode="strip"),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
DPA1_BASELINE_CASE = {
"tebd_dim": 4,
"tebd_input_mode": "concat",
"resnet_dt": True,
"type_one_side": True,
"attn": 20,
"attn_layer": 2,
"attn_dotr": True,
"excluded_types": [],
"env_protection": 0.0,
"set_davg_zero": True,
"scaling_factor": 1.0,
"normalize": True,
"temperature": 1.0,
"ln_eps": 1e-5,
"smooth_type_embedding": True,
"concat_output_tebd": True,
"precision": "float64",
"use_econf_tebd": False,
"use_tebd_bias": False,
}
def dpa1_case(**overrides: Any) -> tuple:
case = DPA1_BASELINE_CASE | overrides
return tuple(case[field] for field in DPA1_CASE_FIELDS)
DPA1_CURATED_CASES = (
# Baseline coverage.
dpa1_case(),
# Alternate tebd input plumbing.
dpa1_case(tebd_input_mode="strip"),
# High-risk descriptor toggles.
dpa1_case(excluded_types=[[0, 1]]),
dpa1_case(set_davg_zero=False),
dpa1_case(normalize=False),
# Attention edge cases: disabled temperature path vs zero-layer path.
dpa1_case(temperature=None),
dpa1_case(attn_layer=0, temperature=None),
# econf-specific path with both tebd input modes.
dpa1_case(use_econf_tebd=True),
dpa1_case(tebd_input_mode="strip", use_econf_tebd=True),
)
DPA1_BASELINE_CASE = {
"tebd_dim": 4,
"tebd_input_mode": "concat",
"resnet_dt": True,
"type_one_side": True,
"attn": 20,
"attn_layer": 2,
"attn_dotr": True,
"excluded_types": [],
"env_protection": 0.0,
"set_davg_zero": True,
"scaling_factor": 1.0,
"normalize": True,
"temperature": 1.0,
"ln_eps": 1e-5,
"smooth_type_embedding": True,
"concat_output_tebd": True,
"precision": "float64",
"use_econf_tebd": False,
"use_tebd_bias": False,
}
def dpa1_case(**overrides: Any) -> tuple:
case = DPA1_BASELINE_CASE | overrides
return tuple(case[field] for field in DPA1_CASE_FIELDS)
DPA1_CURATED_CASES = (
# Baseline coverage.
dpa1_case(),
# Keep one TF-compatible case alive.
dpa1_case(smooth_type_embedding=False),
# Alternate tebd input plumbing.
dpa1_case(tebd_input_mode="strip"),
# High-risk descriptor toggles.
dpa1_case(excluded_types=[[0, 1]]),
dpa1_case(set_davg_zero=False),
dpa1_case(normalize=False),
# Attention edge cases: disabled temperature path vs zero-layer path.
dpa1_case(temperature=None),
dpa1_case(attn_layer=0, temperature=None),
# econf-specific path with both tebd input modes.
dpa1_case(use_econf_tebd=True),
dpa1_case(tebd_input_mode="strip", use_econf_tebd=True),
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/tests/consistent/descriptor/test_dpa1.py` around lines 83 - 126, The
curated cases all inherit smooth_type_embedding=True from DPA1_BASELINE_CASE
which causes skip_tf() to exclude TensorFlow tests; update DPA1_CURATED_CASES to
include at least one TF-compatible entry by calling dpa1_case(...) with
smooth_type_embedding=False (e.g. add dpa1_case(smooth_type_embedding=False) or
another existing case variant that specifies smooth_type_embedding=False) so
TestDPA1.test_tf_* can run.

repinit_use_three_body,
repformer_update_g1_has_conv,
repformer_direct_dist,
repformer_update_g1_has_conv,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Drop or underscore the new dead bindings in these tuple destructures.

repformer_update_g1_has_conv is not read at any of these sites, and most of these helpers only use precision or nothing from self.param. Static analysis is already flagging each occurrence, so either unpack only the fields each method needs or rename this slot to _repformer_update_g1_has_conv where it is intentionally ignored. As per coding guidelines, **/*.py: Install linter and run ruff check . before committing changes or the CI will fail.

Also applies to: 308-308, 341-341, 374-374, 451-451, 557-557, 596-596

🧰 Tools
🪛 Ruff (0.15.9)

[warning] 275-275: Unpacked variable repformer_update_g1_has_conv is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/tests/consistent/descriptor/test_dpa2.py` at line 275, The tuple
destructures in test_dpa2.py include an unused binding
repformer_update_g1_has_conv which triggers linter errors; update each
destructure (including the occurrences around the listed sites) to either remove
that element from the unpack pattern if not needed or rename it to
_repformer_update_g1_has_conv to mark it intentionally ignored (search for
repformer_update_g1_has_conv in the file and adjust the unpack in the helper
calls such as the tuples used by the methods that only use precision or nothing
from self.param), then run ruff check . to ensure no remaining unused-binding
warnings.

@njzjz-bot njzjz-bot closed this Apr 10, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.45%. Comparing base (d7ee913) to head (bfdb116).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5388   +/-   ##
=======================================
  Coverage   80.45%   80.45%           
=======================================
  Files         814      814           
  Lines       84438    84438           
  Branches     4050     4051    +1     
=======================================
+ Hits        67935    67936    +1     
  Misses      15279    15279           
+ Partials     1224     1223    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant