Skip to content

Conversation

@huynguyengl99
Copy link

@huynguyengl99 huynguyengl99 commented Jan 22, 2026

Close #647

@huynguyengl99
Copy link
Author

Hi @bckohan and @JohananOppongAmoateng, this PR is based on the type annotations I added in the typeshed repo. Could you take a look at it? Also, if everything looks good, could you approve the GitHub workflows to run, @bckohan?

@huynguyengl99
Copy link
Author

Hi @bckohan, could you re-approve the workflow run? I’ve updated the tests, so I expect it should pass now.

There are still quite a few typing errors, but I think we can address them in future commits in this PR—either when I have more time, or with the help of @JohananOppongAmoateng.

@codecov
Copy link

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 97.80439% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.11%. Comparing base (de28147) to head (5d3784d).

Files with missing lines Patch % Lines
src/polymorphic/query.py 96.10% 1 Missing and 2 partials ⚠️
src/polymorphic/admin/generic.py 84.61% 2 Missing ⚠️
src/polymorphic/admin/helpers.py 88.88% 1 Missing and 1 partial ⚠️
src/polymorphic/deletion.py 89.47% 2 Missing ⚠️
src/polymorphic/admin/inlines.py 96.66% 0 Missing and 1 partial ⚠️
src/polymorphic/utils.py 96.77% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #856      +/-   ##
==========================================
+ Coverage   90.98%   91.11%   +0.13%     
==========================================
  Files          28       28              
  Lines        1730     1868     +138     
  Branches      267      274       +7     
==========================================
+ Hits         1574     1702     +128     
- Misses        104      110       +6     
- Partials       52       56       +4     

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

@huynguyengl99
Copy link
Author

Hi @bckohan , could you re-approve the workflow run?

@huynguyengl99
Copy link
Author

Hi @bckohan, cc @JohananOppongAmoateng

I’ve finished addressing all remaining typing issues in the recent commits on this branch. Here’s a brief summary of the current state and some context around the decisions made:

Summary

  • Due to the complexity of the project and the need to support both mypy and pyright, the current implementation requires:
    • 3 # pyright: ignore comments
    • 63 # type: ignore comments
    • 47 explicit cast(...) calls
  • I made a strong effort to minimize the use of ignore comments and casts. The remaining ones are, to the best of my judgment, the most compact and reasonable solutions given the constraints.

Rationale

  • One major reason for these workarounds is that we use inline type hints, while projects like Django and Django REST Framework rely on separate type stub packages.
  • Inline typing makes certain cases harder, but I believe this approach will help us long-term and avoids the need to constantly sync a separate typeshed-style repo with the main codebase.
  • This PR is quite large, and I’ve spent a significant amount of time on it. I’d really appreciate it if you could review it when possible to catch any incorrect or suboptimal type hints early — that will help avoid larger conflicts later.

Supporting both typed and non-typed users

I’ve tried to ensure compatibility for both typed and non-typed users. For example:

_ModelT = TypeVar(
    "_ModelT",
    bound=PolymorphicModel,
    default=PolymorphicModel,
)

if TYPE_CHECKING:
    _ModelAdminBase = admin.ModelAdmin[_ModelT]
else:
    _ModelAdminBase = admin.ModelAdmin

class PolymorphicChildModelAdmin(_ModelAdminBase, Generic[_ModelT]):
    ...
  • I haven’t tested this pattern extensively yet, but the test suite is currently passing, so it should be working as expected.

On cast(...) vs type: ignore

  • Where mypy complains, I generally prefer using cast(...) instead of # type: ignore. For example:
return cast(type[BaseGenericPolymorphicInlineFormSet], FormSet)
  • While this may add a bit of inconvenience during development, I think explicit casts are clearer and better communicate intent — especially when dealing with Django’s heavy metaprogramming.
  • Unfortunately, I don’t see a cleaner alternative in these cases, so I hope the casts are reasonable and acceptable.

Looking forward to your feedback. Thanks a lot for taking the time to review this — I hope we can get this PR merged soon.

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.

Add type hints for django-polymorphic

2 participants