Skip to content

Add a last-resort fallback for uppercase environment names with digits - #257

Open
codeofwxz wants to merge 3 commits into
rnag:mainfrom
codeofwxz:fix-uppercase-digit-env-fallback
Open

codeofwxz wants to merge 3 commits into
rnag:mainfrom
codeofwxz:fix-uppercase-digit-env-fallback

Conversation

@codeofwxz

@codeofwxz codeofwxz commented Sep 12, 2026 •

Copy link
Copy Markdown

Related #250.

With the default ENV lookup strategy, a field named CC_2TEST only checks CC_2_TEST and cc_2_test. A same-named environment variable or dotenv entry is therefore ignored, and the field keeps its default or raises MissingVars.

This change adds the original spelling as a final fallback only for ASCII uppercase environment identifiers whose normalization consists exclusively of inserting underscores between digits and uppercase letters. For example, the lookup order becomes CC_2_TEST, cc_2_test, then CC_2TEST. Existing normalized keys still win when multiple spellings are present, including when their value is an empty string.

The shared snake-case conversion is unchanged. FIELD_FIRST, STRICT, explicit alias precedence, and prefix handling retain their existing behavior. Mixed-case names, punctuation, and names whose normalization also collapses repeated underscores do not gain this fallback. The ENV strategy docstring describes the new lookup behavior. This is a proposed limited compatibility fix, not a previously confirmed maintainer policy.

Validation:

  • The 20 new regression cases go from 9 failures / 11 passes on the original implementation to all passing. They cover environment and explicit synthetic dotenv input, inheritance, digit positions, candidate order, prefixes, aliases, missing fields/defaults, and other strategies.
  • The environment suite passes all 77 tests on Python 3.12.14 and 3.14.4.
  • Full unit tests on both versions: 903 passed, 1 failed, 2 skipped, 6 xfailed, 4 xpassed. The unchanged baseline has 883 passed and the same remaining statuses. The one failure is the existing v0 dotenv date assertion (2021-12-18 versus 2021-12-17). These are not full-suite passes; Python 3.14 coverage is 89% under the existing coverage configuration.
  • The configured pre-commit hooks pass, as do sdist/wheel builds and twine check.
  • The documented Flake8/Pylint commands were attempted. Flake8 has the same 1,782 diagnostics as the baseline after accounting for shifted line numbers. Pylint diagnostics on the two changed production files are unchanged; the new test file passes Pylint independently. Repository-wide lint is not clean on the baseline.

Tests ran on Windows using a task-local synthetic process environment. The full supported Python/PyPy and Linux CI matrix has not been run locally.

The README's EnvWizard feature list now documents the numeric-name fallback and the priority of existing normalized keys, including empty values.

Copilot AI lite review requested due to automatic review settings September 12, 2026 15:36

Copilot AI 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.

🔵 Needs a closer look

Add coverage confirming normalized keys with empty-string values retain precedence.

Pull request overview

Adds a narrowly scoped fallback for uppercase environment names containing digit-to-letter boundaries while preserving existing lookup precedence.

Changes:

  • Implements the fallback candidate logic.
  • Documents updated ENV lookup behavior.
  • Adds regression coverage for numeric names, precedence, aliases, prefixes, and strategies.
File summaries
File Description
tests/unit/environ/test_numeric_names.py Regression tests for numeric environment names
dataclass_wizard/utils/_string_conv.py Implements the fallback candidate logic
dataclass_wizard/enums.py Documents the new lookup behavior
Review details

Suppressed comments (1)

tests/unit/environ/test_numeric_names.py:26

  • The PR description explicitly guarantees that a normalized key still wins when its value is an empty string, but this precedence parameterization only exercises non-empty values. Add an empty-string case so a future truthiness check cannot regress this behavior without being caught.
@pytest.mark.parametrize('values, expected', [
    ({'CC_2TEST': 'original'}, 'original'),
    ({'CC_2TEST': 'original', 'cc_2_test': 'snake'}, 'snake'),
    ({'CC_2TEST': 'original', 'cc_2_test': 'snake', 'CC_2_TEST': 'upper'},
     'upper'),
])
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codeofwxz

Copy link
Copy Markdown
Author

Added three precedence cases covering empty normalized values while the original spelling remains non-empty. Both normalized candidates retain priority, including when both are empty. All 80 environment tests pass on Python 3.12 and 3.14; this update changes tests only.

The full-suite and platform-validation limitations recorded in the PR description remain unchanged; this update does not claim a full-suite or CI pass.

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.

2 participants