Skip to content

Fix stringcase dependency with setuptools 78.0.0#565

Merged
koxudaxi merged 1 commit intomainfrom
issue-481-stringcase-dependency
Apr 28, 2026
Merged

Fix stringcase dependency with setuptools 78.0.0#565
koxudaxi merged 1 commit intomainfrom
issue-481-stringcase-dependency

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Apr 28, 2026

Fixes: #481

Summary

  • Replace the runtime use of the unmaintained stringcase package with local case conversion helpers for the behavior used by the parser.
  • Remove stringcase from project dependencies and the uv lockfile.
  • Add parser tests that pin the legacy case conversion behavior used in generated operation names, paths, and arguments.

Checks

  • uv run pytest -q
  • uv run tox -e fix
  • uv run tox -e type
  • uv run tox -e pkg_meta

Summary by CodeRabbit

  • Refactor

    • Replaced an external string-casing dependency with an internal implementation to centralize and standardize name conversions without changing public interfaces.
  • Tests

    • Added tests validating legacy casing behavior across varied inputs to ensure consistent snake/camel/pascal conversions and preserve prior outputs.
  • Chores

    • Removed the now-unused external dependency from project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Walkthrough

Replaces the external stringcase dependency with internal regex-based snakecase, camelcase, and pascalcase helpers; updates parser naming call sites to use them; removes stringcase from project dependencies; and adds tests validating legacy casing behavior.

Changes

Cohort / File(s) Summary
Parser / Case helpers
fastapi_code_generator/parser.py
Introduces local regex-based snakecase, camelcase, pascalcase, memoized helpers and regex callbacks; updates UsefulStr properties and all internal naming conversions (arguments, paths, function names, OpenAPI parameter normalization, multipart file field naming) to use the new helpers; removes stringcase import.
Project configuration
pyproject.toml
Removes stringcase>=1.2,<2 from project dependencies.
Tests
tests/test_parser.py
Adds imports for snakecase and UsefulStr; adds parametrized tests asserting snakecase() outputs and UsefulStr .snakecase/.camelcase/.pascalcase properties match legacy conversions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through tokens, regex in paw,
Replacing a module I once saw.
snake_case, camelCase, Pascal aligned,
Small helpers stitched, tidy and kind.
A joyful nibble — code well-defined.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of the PR: replacing the problematic stringcase dependency to fix compatibility with setuptools 78.0.0.
Linked Issues check ✅ Passed The PR fully addresses issue #481 by removing the stringcase dependency and implementing local case-conversion helpers (snakecase, camelcase, pascalcase) with test coverage ensuring legacy behavior compatibility.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: replacing stringcase with internal functions, removing the dependency, and adding tests to validate the replacement behavior.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-481-stringcase-dependency

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.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

📚 Docs Preview: https://pr-565.fastapi-code-generator.pages.dev

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 28, 2026

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 1 untouched benchmark


Comparing issue-481-stringcase-dependency (ac52746) with main (e9f2965)

Open in CodSpeed

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
tests/test_parser.py (1)

28-33: Consider broadening camel/pascal compatibility cases.

Line 28 currently validates one representative value. A small parametrized matrix would make future behavior drift less likely.

Suggested test extension
+@pytest.mark.parametrize(
+    ("value", "camel_expected", "pascal_expected"),
+    [
+        ("sample_name", "sampleName", "SampleName"),
+        ("sampleName", "sampleName", "SampleName"),
+        ("SampleName", "sampleName", "SampleName"),
+        ("", "", ""),
+    ],
+)
+def test_useful_str_case_helpers_cover_multiple_input_shapes(
+    value: str, camel_expected: str, pascal_expected: str
+) -> None:
+    useful = UsefulStr(value)
+    assert useful.camelcase == camel_expected
+    assert useful.pascalcase == pascal_expected
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_parser.py` around lines 28 - 33, The test
test_useful_str_case_helpers_match_legacy_stringcase_behavior currently checks
only one input; expand it into a parametrized test that iterates multiple input
strings and their expected snakecase, camelcase, and pascalcase outputs to catch
regressions. Use the UsefulStr constructor in each case and assert
UsefulStr(...).snakecase, .camelcase, and .pascalcase against expected values
for a small matrix (e.g., inputs with hyphens, spaces, acronyms,
leading/trailing underscores) so the behavior of UsefulStr and its properties is
validated across variants.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/test_parser.py`:
- Around line 28-33: The test
test_useful_str_case_helpers_match_legacy_stringcase_behavior currently checks
only one input; expand it into a parametrized test that iterates multiple input
strings and their expected snakecase, camelcase, and pascalcase outputs to catch
regressions. Use the UsefulStr constructor in each case and assert
UsefulStr(...).snakecase, .camelcase, and .pascalcase against expected values
for a small matrix (e.g., inputs with hyphens, spaces, acronyms,
leading/trailing underscores) so the behavior of UsefulStr and its properties is
validated across variants.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bfa61c27-9ac3-4000-82d8-b281b099ff69

📥 Commits

Reviewing files that changed from the base of the PR and between e9f2965 and 35901fe.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • fastapi_code_generator/parser.py
  • pyproject.toml
  • tests/test_parser.py
💤 Files with no reviewable changes (1)
  • pyproject.toml

@koxudaxi koxudaxi force-pushed the issue-481-stringcase-dependency branch from 35901fe to 499a328 Compare April 28, 2026 03:14
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (e9f2965) to head (ac52746).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #565   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           17        17           
  Lines         1204      1244   +40     
  Branches       126       129    +3     
=========================================
+ Hits          1204      1244   +40     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
fastapi_code_generator/parser.py (1)

545-607: ⚠️ Potential issue | 🟠 Major

Don't let multipart overwrite an existing body argument.

When a request body contains both JSON and multipart content, arguments[0] depends on dict order, so one of the request payloads is silently dropped. The new mixed-content test only checks request_body_fields, so this regression is currently unguarded. Either reject mixed body types explicitly or preserve both pieces in _temporary_operation instead of overwriting _request.

Possible guard
         if 'multipart/form-data' in request_body.content:
             ...
-        self._temporary_operation['_request'] = arguments[0] if arguments else None
+        if len(arguments) > 1:
+            raise ValueError("Mixed request-body content types are not supported")
+        self._temporary_operation['_request'] = arguments[0] if arguments else None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fastapi_code_generator/parser.py` around lines 545 - 607, The code currently
lets a later multipart/form-data branch overwrite an earlier JSON body because
_temporary_operation['_request'] is set to arguments[0] after iterating media
types; fix by detecting mixed body content inside the loop and either (A) reject
mixed JSON+multipart bodies with a clear exception (e.g. raise ValueError
including request name) when you encounter a JSON body and later a multipart
media_type, or (B) preserve both by storing all body-like arguments (replace
_temporary_operation['_request'] = arguments[0] with
_temporary_operation['_request'] = arguments if len(arguments) > 1 else
arguments[0]) and adjust downstream code to handle a list; implement the chosen
approach near the end of the method where arguments is assembled and reference
Argument, _get_upload_file_type, request_body, media_type, and
_temporary_operation to locate changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@fastapi_code_generator/parser.py`:
- Around line 67-82: The initial re.sub in camelcase currently deletes
characters across delimiters and mangles inputs like "sample_name"; change the
cleaning step in camelcase (used by pascalcase) to normalize non-alphanumeric
runs instead of removing surrounding word characters — e.g., replace sequences
of non-alphanumeric characters with a single delimiter/space (use a pattern like
r"[^A-Za-z0-9]+") on str(value') so subsequent re.sub(r"[\-_\.\s]([a-z])",
_uppercase_group, ...) can correctly uppercase the following letter; keep
pascalcase calling camelcase and then capitalizing the first character.

---

Outside diff comments:
In `@fastapi_code_generator/parser.py`:
- Around line 545-607: The code currently lets a later multipart/form-data
branch overwrite an earlier JSON body because _temporary_operation['_request']
is set to arguments[0] after iterating media types; fix by detecting mixed body
content inside the loop and either (A) reject mixed JSON+multipart bodies with a
clear exception (e.g. raise ValueError including request name) when you
encounter a JSON body and later a multipart media_type, or (B) preserve both by
storing all body-like arguments (replace _temporary_operation['_request'] =
arguments[0] with _temporary_operation['_request'] = arguments if len(arguments)
> 1 else arguments[0]) and adjust downstream code to handle a list; implement
the chosen approach near the end of the method where arguments is assembled and
reference Argument, _get_upload_file_type, request_body, media_type, and
_temporary_operation to locate changes.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 084be36f-6c86-4aa5-8d24-ddffbebd2315

📥 Commits

Reviewing files that changed from the base of the PR and between 35901fe and 499a328.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • fastapi_code_generator/parser.py
  • pyproject.toml
  • tests/test_parser.py
💤 Files with no reviewable changes (1)
  • pyproject.toml

Comment thread fastapi_code_generator/parser.py Outdated
@koxudaxi koxudaxi force-pushed the issue-481-stringcase-dependency branch from 499a328 to ac52746 Compare April 28, 2026 03:18
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
tests/test_parser.py (1)

28-44: Consider expanding UsefulStr case matrix with delimiter-heavy inputs.

Adding cases like pet-id, pet.id, and {petId} here would better guard camelcase/pascalcase behavior for the naming patterns this PR targets.

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

In `@tests/test_parser.py` around lines 28 - 44, The current test matrix for
UsefulStr (attributes snakecase, camelcase, pascalcase) misses delimiter-heavy
inputs; update the parametrized cases in
test_useful_str_case_helpers_match_legacy_stringcase_behavior to include
examples like "pet-id", "pet.id", and "{petId}" (and their expected
snake/camel/pascal outputs) so UsefulStr.snakecase, UsefulStr.camelcase, and
UsefulStr.pascalcase are verified for hyphen, dot, and brace-wrapped camel
inputs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/test_parser.py`:
- Around line 28-44: The current test matrix for UsefulStr (attributes
snakecase, camelcase, pascalcase) misses delimiter-heavy inputs; update the
parametrized cases in
test_useful_str_case_helpers_match_legacy_stringcase_behavior to include
examples like "pet-id", "pet.id", and "{petId}" (and their expected
snake/camel/pascal outputs) so UsefulStr.snakecase, UsefulStr.camelcase, and
UsefulStr.pascalcase are verified for hyphen, dot, and brace-wrapped camel
inputs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5b354f4e-f3ac-46b3-a0a2-5c39dee425b7

📥 Commits

Reviewing files that changed from the base of the PR and between 499a328 and ac52746.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • fastapi_code_generator/parser.py
  • pyproject.toml
  • tests/test_parser.py
💤 Files with no reviewable changes (1)
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • fastapi_code_generator/parser.py

@koxudaxi koxudaxi marked this pull request as ready for review April 28, 2026 05:03
@koxudaxi koxudaxi merged commit 23a9e75 into main Apr 28, 2026
44 checks passed
@koxudaxi koxudaxi deleted the issue-481-stringcase-dependency branch April 28, 2026 05:04
@github-actions github-actions Bot added the breaking-change-analyzed PR has been checked for release draft updates label Apr 28, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: The breaking-change label is absent, so this PR is treated as a non-breaking release update.


This analysis was performed by repository automation using PR labels and the ## Breaking Changes section.

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

Labels

breaking-change-analyzed PR has been checked for release draft updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix stringcase dependency with setuptools 78.0.0

1 participant