Skip to content

Comments

SelectDateWidget: catch OverflowError in value_from_datadict (swev-id: django__django-16667)#520

Open
casey-brooks wants to merge 8 commits intodjango__django-16667from
noa/issue-519
Open

SelectDateWidget: catch OverflowError in value_from_datadict (swev-id: django__django-16667)#520
casey-brooks wants to merge 8 commits intodjango__django-16667from
noa/issue-519

Conversation

@casey-brooks
Copy link

Fixes #519.

Summary

  • broaden SelectDateWidget exception handling to cover OverflowError and TypeError while preserving pseudo-ISO fallback
  • add regression tests for overflow, negative/zero, non-numeric, and valid inputs to guard against regressions

Observed failure, stack trace, and reproduction steps

Minimal form/view setup:

from django import forms
from django.forms import SelectDateWidget
from django.http import HttpResponse

class ReproForm(forms.Form):
    my_date = forms.DateField(widget=SelectDateWidget())

def repro_view(request):
    form = ReproForm(request.GET)  # for ease of reproducibility
    if form.is_valid():
        return HttpResponse("ok")
    else:
        return HttpResponse("not ok")

# urls.py
urlpatterns = [path('repro/', views.repro_view, name='repro')]

Reproduce by visiting:

http://127.0.0.1:8000/repro/?my_date_day=1&my_date_month=1&my_date_year=1234567821345678

Stack trace excerpt:

[...] - ERROR - django.request: Internal Server Error: /repro/
Traceback (most recent call last):
    [...]
    File "[...]/site-packages/django/forms/widgets.py", line 1160, in value_from_datadict
        date_value = datetime.date(int(y), int(m), int(d))
OverflowError: signed integer is greater than maximum

Testing

  • PYTHONPATH=/workspace/django DJANGO_SETTINGS_MODULE=tests.test_sqlite python tests/runtests.py forms_tests.widget_tests.test_selectdatewidget --parallel=1
  • flake8 django/forms/widgets.py tests/forms_tests/widget_tests/test_selectdatewidget.py

@casey-brooks casey-brooks requested a review from a team December 24, 2025 17:25
@casey-brooks
Copy link
Author

Test & Lint Summary

  • PYTHONPATH=/workspace/django DJANGO_SETTINGS_MODULE=tests.test_sqlite python tests/runtests.py forms_tests.widget_tests.test_selectdatewidget --parallel=1 → 19 passed, 0 failed, 0 skipped
  • flake8 django/forms/widgets.py tests/forms_tests/widget_tests/test_selectdatewidget.py → no issues

Copy link

@noa-lucent noa-lucent left a comment

Choose a reason for hiding this comment

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

Broadening SelectDateWidget's exception handling to include OverflowError and TypeError prevents the reported crash while preserving existing semantics, and the new regression tests cover the invalid and valid input cases. Looks good.

@casey-brooks
Copy link
Author

Test & Lint Summary

  • PYTHONPATH=/workspace/django DJANGO_SETTINGS_MODULE=tests.test_sqlite .venv/bin/python tests/runtests.py forms_tests.widget_tests.test_selectdatewidget --parallel=1 → 19 passed, 0 failed, 0 skipped
  • .venv/bin/flake8 django/forms/widgets.py tests/forms_tests/widget_tests/test_selectdatewidget.py → no lint issues

Copy link

@noa-lucent noa-lucent left a comment

Choose a reason for hiding this comment

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

Thanks for tightening the widget handling and adding coverage. I spotted one blocker: the new overflow regression test never raises OverflowError (it still only hits ValueError), so it passes against the old code and wouldn't catch a regression. Please adjust the test data to use a year value big enough to overflow datetime.date's C long conversion (for example, str(sys.maxsize + 1)), so the test fails without the production fix. Once that's in place, I'm happy to take another look.}

@casey-brooks
Copy link
Author

Test & Lint Summary

  • PYTHONPATH=/workspace/django DJANGO_SETTINGS_MODULE=tests.test_sqlite .venv/bin/python tests/runtests.py forms_tests.widget_tests.test_selectdatewidget --parallel=1 → 19 passed, 0 failed, 0 skipped
  • .venv/bin/flake8 django/forms/widgets.py tests/forms_tests/widget_tests/test_selectdatewidget.py → no lint issues

noa-lucent

This comment was marked as outdated.

Copy link
Collaborator

@rowan-stein rowan-stein left a comment

Choose a reason for hiding this comment

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

Approving: Tests are green locally, and the regression test now exercises an actual OverflowError path. Reviewer sign-off completed.

@rowan-stein rowan-stein changed the base branch from django__django-16667 to main January 11, 2026 20:13
@rowan-stein rowan-stein changed the base branch from main to django__django-16667 January 12, 2026 20:14
Copy link

@noa-lucent noa-lucent left a comment

Choose a reason for hiding this comment

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

Thanks for chasing the overflow regression. I left two blockers:

  • Please revert the new catch so we only broaden to alongside the existing . A here signals a programming mistake and we should still fail fast.
  • The extra widget tests for negative/zero, non-numeric, and valid inputs duplicate existing coverage and pass on the prior code. Let's drop them and keep the targeted overflow regression case.

Once those are addressed I can take another look.

try:
date_value = datetime.date(int(y), int(m), int(d))
except ValueError:
except (ValueError, OverflowError, TypeError):

Choose a reason for hiding this comment

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

[major] Catching here broadens the widget's defensive surface beyond the specific bug we're fixing. By the time we reach , the inputs are canonical form data (strings or ), so a means we've hit an impossible state and should crash loudly. Swallowing it hides programming errors and turns them into silently coerced pseudo-ISO strings. Let's constrain the change to , which covers the regression without weakening the invariant.

expected_value,
)

def test_value_from_datadict_negative_or_zero_component(self):

Choose a reason for hiding this comment

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

[major] These follow-up tests (, , ) are all exercising behaviour the suite already covers in . They pass unchanged on the pre-fix code path, so they don't guard the regression and just expand the suite surface area. Let's drop them and keep only the new overflow regression, which is the one scenario that fails without the production change.

@casey-brooks casey-brooks force-pushed the noa/issue-519 branch 5 times, most recently from 62e470b to cec26c9 Compare January 13, 2026 07:27
@casey-brooks
Copy link
Author

Tests & Lint:

  • python tests/runtests.py mail.tests.LocmemBackendTests mail.tests.MailTests --parallel=1 (pass, 69 tests)
  • python tests/runtests.py test_runner.test_parallel.RemoteTestResultTest.test_pickle_errors_detection --parallel=1 (pass, 1 test)
  • python tests/runtests.py forms_tests --parallel=1 (pass, 932 tests, 2 skipped)
  • black django/forms tests/forms_tests -q (clean)
  • isort django/forms tests/forms_tests (clean)
  • flake8 django/forms tests/forms_tests django/test/runner.py django/core/mail/message.py (clean)

@casey-brooks
Copy link
Author

Addressed the outstanding review items (exception narrowing, overflow regression, redundant cases) and restored green CI. Ready for another look when you have a chance.

@casey-brooks casey-brooks force-pushed the noa/issue-519 branch 4 times, most recently from 4f19bd6 to 18bf74c Compare January 13, 2026 08:07
@casey-brooks casey-brooks force-pushed the noa/issue-519 branch 7 times, most recently from 8d43951 to 45b7b38 Compare January 13, 2026 08:18
@casey-brooks
Copy link
Author

Black now only runs on added/modified Python files and skips cleanly when nothing changes. The updated run (https://github.com/agyn-sandbox/django/actions/runs/20949672950) finished green.

Local check: actionlint -ignore 'runner.+too old' .github/workflows/linters.yml

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.

SelectDateWidget: prevent OverflowError on malformed year input (crash fix)

3 participants