Skip to content

🏷️ improve types in tests#39

Merged
techouse merged 5 commits intomainfrom
chore/pyright-tests
Jan 31, 2026
Merged

🏷️ improve types in tests#39
techouse merged 5 commits intomainfrom
chore/pyright-tests

Conversation

@techouse
Copy link
Owner

@techouse techouse commented Jan 31, 2026

This pull request makes several improvements to the type annotations and test structure for custom encoder/decoder hooks in the qs_codec library. The main changes are the generalization of type signatures for decoder functions to allow any return type, and a refactor of tests to consistently use a helper function for decoder invocation. There are also minor updates to configuration files.

Type annotation improvements:

  • The decoder and legacy_decoder attributes in DecodeOptions (in src/qs_codec/models/decode_options.py) now allow any return type (t.Optional[t.Any]), instead of being restricted to str. This change propagates to all related function signatures and adapters. [1] [2] [3] [4] [5]
  • The serialize_date option in both EncodeOptions and the _encode function is updated to accept either a callable or a string, improving flexibility for date serialization. [1] [2]

Test refactoring:

  • All tests in tests/unit/decode_options_test.py are updated to use a require_decoder helper function to retrieve the decoder, instead of directly accessing opts.decoder. This standardizes test invocation and improves clarity. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17]

Configuration update:

  • The mypy configuration in pyproject.toml now excludes the .tox directory to prevent type checking in virtual environments.

Summary by CodeRabbit

  • New Features

    • Date serialization option now accepts either a callable or a string.
    • Decoder return types expanded to allow any value type.
  • Tests

    • Added helpers for encoder configuration and updated tests for typing robustness.
    • Multiple tests adjusted with typing ignores and safer attribute access.
  • Chores

    • Updated project config for miscellaneous excludes and added VS Code ignores.

✏️ Tip: You can customize this high-level summary in your review settings.

@techouse techouse self-assigned this Jan 31, 2026
@techouse techouse added the test label Jan 31, 2026
@techouse techouse requested a review from Copilot January 31, 2026 12:40
@coderabbitai
Copy link

coderabbitai bot commented Jan 31, 2026

📝 Walkthrough

Walkthrough

Updated type annotations: serialize_date now accepts callable or string; decoder return types broadened to Any. Tests refactored to use helper functions and type-ignore adjustments. pyproject mypy excludes extended and .gitignore updated. No runtime behavior changes to core logic.

Changes

Cohort / File(s) Summary
Config
pyproject.toml, .gitignore
Added .tox to mypy exclude (collapsed list); added .vscode/ ignore entry.
Encoding surface
src/qs_codec/encode.py, src/qs_codec/models/encode_options.py
serialize_date type widened from Callable[[datetime], Optional[str]] to Union[Callable[[datetime], Optional[str]], str] (defaults unchanged; runtime still checks callability).
Decoding surface
src/qs_codec/models/decode_options.py
Decoder signatures broadened from Optional[Callable[..., Optional[str]]] to Optional[Callable[..., Optional[Any]]] and related internal annotations updated.
Test helpers & usage
tests/unit/decode_options_test.py, tests/unit/encode_test.py, tests/unit/example_test.py
Added require_decoder(), DecoderCallable, options_with_encoder(), and decimal_encoder(); tests updated to assign encoders via helpers.
Test typing tweaks
tests/unit/decode_test.py, tests/unit/encode_options_test.py, tests/unit/utils_test.py, tests/unit/weakref_test.py
Added type: ignore annotations, removed or relaxed local type annotations, replaced direct __func__ access with guarded getattr, and normalized timezone references (datetime.UTCdatetime.timezone.utc).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ✅ increase coverage #28: touches Decode/Encode option typings and related tests; aligns with the decoder typing and test refactor in this PR.

Suggested labels

python

Poem

🐰
Hop-hop, the types did shift and play,
Dates accept strings or callables today,
Decoders welcome any kind of thing,
Tests now dance with helpers—what joy they bring!
Configs trimmed, the CI hums hooray.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is comprehensive and well-structured, covering type annotation improvements, test refactoring, and configuration updates. However, it does not follow the required template structure (missing checklist sections like 'Type of change', 'How Has This Been Tested', and final checklist items). Reorganize the description to follow the template structure: add 'Type of change' section, 'How Has This Been Tested' section, and complete the final checklist to ensure consistency with repository standards.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'improve types in tests' accurately reflects the main changes in the PR—specifically the type annotation improvements and test refactoring related to types. It is concise and clear.

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

✨ 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 chore/pyright-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.

@techouse
Copy link
Owner Author

@codex review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request improves type annotations and test structure across the qs_codec library. The primary change is generalizing the return type of decoder functions from str to Any, allowing custom decoders to return arbitrary types. Additionally, tests are refactored to use a helper function for consistent decoder invocation, and minor type-related improvements are made throughout the codebase.

Changes:

  • Type annotations for decoder and legacy_decoder in DecodeOptions now allow returning any type instead of only strings
  • Test files standardized to use require_decoder() helper function instead of direct decoder access
  • Configuration update to exclude .tox directory from mypy checking

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/unit/weakref_test.py Added type annotations for nested list variables and type ignore comment for __hash__ assignment
tests/unit/utils_test.py Added type ignore comments for test cases intentionally passing incorrect argument types to utility functions
tests/unit/example_test.py Updated encoder/decoder test setup to use option objects directly; replaced deprecated datetime.UTC with datetime.timezone.utc
tests/unit/encode_test.py Introduced options_with_encoder() helper and decimal_encoder() function to reduce test code duplication; added type cast for filter parameter
tests/unit/encode_options_test.py Updated encoder identity assertions to use getattr() with fallback for safer attribute comparison
tests/unit/decode_test.py Added type ignore comment for intentional invalid argument test
tests/unit/decode_options_test.py Refactored all tests to use new require_decoder() helper function for consistent decoder retrieval
src/qs_codec/models/encode_options.py Updated serialize_date type to allow both callable and string types
src/qs_codec/models/decode_options.py Changed decoder return types from str to Any across all decoder-related signatures
src/qs_codec/encode.py Updated serialize_date parameter type in _encode() function to match option model changes
pyproject.toml Condensed mypy exclusion list to single line and added .tox directory

@codacy-production
Copy link

codacy-production bot commented Jan 31, 2026

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.00% (target: -1.00%) 100.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (7091425) 1267 1267 100.00%
Head commit (221cfd6) 1267 (+0) 1267 (+0) 100.00% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#39) 4 4 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

@codecov
Copy link

codecov bot commented Jan 31, 2026

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #39   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           17        17           
  Lines         1267      1267           
=========================================
  Hits          1267      1267           

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

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@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

Caution

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

⚠️ Outside diff range comments (1)
tests/unit/encode_test.py (1)

102-131: ⚠️ Potential issue | 🟡 Minor

Remove unused f-string prefixes to satisfy Ruff/Flake8 (F541).

Six f-strings in the decimal test cases lack interpolation and should be plain strings.

🧹 Suggested fix
-            pytest.param([_PI], None, f"0=3.141592653589793115997963468544185161590576171875", id="list-decimal"),
+            pytest.param([_PI], None, "0=3.141592653589793115997963468544185161590576171875", id="list-decimal"),
@@
-                f"0=3.141592653589793115997963468544185161590576171875n",
+                "0=3.141592653589793115997963468544185161590576171875n",
@@
-            pytest.param({"a": _PI}, None, f"a=3.141592653589793115997963468544185161590576171875", id="dict-decimal"),
+            pytest.param({"a": _PI}, None, "a=3.141592653589793115997963468544185161590576171875", id="dict-decimal"),
@@
-                f"a=3.141592653589793115997963468544185161590576171875n",
+                "a=3.141592653589793115997963468544185161590576171875n",
@@
-                f"a[]=3.141592653589793115997963468544185161590576171875",
+                "a[]=3.141592653589793115997963468544185161590576171875",
@@
-                f"a[]=3.141592653589793115997963468544185161590576171875n",
+                "a[]=3.141592653589793115997963468544185161590576171875n",
🤖 Fix all issues with AI agents
In `@tests/unit/decode_options_test.py`:
- Around line 113-121: Rename the unused parameter s in the nested test function
dec inside test_user_decoder_typeerror_is_not_swallowed to _s to follow the
Python convention for intentionally unused arguments and silence Ruff's ARG001;
locate the def dec(s: t.Optional[str]) -> t.Optional[str]: declaration and
change the parameter name to _s while leaving the body (which raises TypeError)
and the rest of the test (opts, require_decoder, pytest.raises) unchanged.
- Around line 346-349: The test decoder function dec inside
test_single_decoder_acts_like_legacy_when_ignoring_kind currently declares
unused varargs (*args, **kwargs) triggering Ruff ARG001; fix by removing the
unused parameters or renaming them to _args and **_kwargs (or otherwise using a
single underscore prefix) so they are recognized as intentionally unused; update
the dec definition accordingly to eliminate the linter warning while preserving
its behavior.
🧹 Nitpick comments (1)
tests/unit/encode_test.py (1)

30-37: Pass charset/format through to EncodeUtils.encode.

decimal_encoder ignores the bound charset/format, which makes it less faithful to options.

♻️ Suggested refactor
 def decimal_encoder(
     value: t.Any,
     charset: t.Optional[Charset] = None,
     format: t.Optional[Format] = None,
 ) -> str:
-    _ = charset
-    _ = format
-    return f"{EncodeUtils.encode(value)}n" if isinstance(value, Decimal) else EncodeUtils.encode(value)
+    encoded = EncodeUtils.encode(value, charset=charset, format=format)
+    return f"{encoded}n" if isinstance(value, Decimal) else encoded

@techouse techouse merged commit 6fbbb50 into main Jan 31, 2026
23 checks passed
@techouse techouse deleted the chore/pyright-tests branch January 31, 2026 13:30
@coderabbitai coderabbitai bot mentioned this pull request Feb 1, 2026
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