Skip to content

chore(deps): upgrade Python to 3.12 DEV-1863#6793

Merged
noliveleger merged 9 commits intodjango-5.2from
python-3.12
Mar 23, 2026
Merged

chore(deps): upgrade Python to 3.12 DEV-1863#6793
noliveleger merged 9 commits intodjango-5.2from
python-3.12

Conversation

@jnm
Copy link
Copy Markdown
Member

@jnm jnm commented Mar 5, 2026

📣 Summary

Upgrades the backend runtime to Python 3.12 .

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Python 3.12 in the test suite.
  • Tests

    • Updated test assertions to use current standard methods.
  • Chores

    • Removed deprecated dependency by migrating to internal utility functions.

@jnm jnm added the Back end label Mar 5, 2026
p2edwards and others added 4 commits March 5, 2026 13:53
 # Conflicts:
 #	.github/workflows/pytest.yml
 #	kobo/apps/languages/models/language.py
 #	kpi/utils/strings.py
 # Conflicts:
 #	kpi/admin.py
@noliveleger noliveleger changed the base branch from main to django-5.2 March 23, 2026 19:33
@noliveleger noliveleger changed the title [wip] Python 3.12 chore(deps): upgrade Python to 3.12 and Django to 5.2 DEV-1863 Mar 23, 2026
@noliveleger noliveleger changed the title chore(deps): upgrade Python to 3.12 and Django to 5.2 DEV-1863 chore(deps): upgrade Python to 3.12 DEV-1863 Mar 23, 2026
@noliveleger noliveleger self-assigned this Mar 23, 2026
@noliveleger noliveleger marked this pull request as ready for review March 23, 2026 19:53
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 23, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7f2edbba-5c8d-45d4-97ba-9b22e4e5927b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch python-3.12

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

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

Upgrades backend compatibility toward Python 3.12 by removing distutils usage (removed in 3.12) and expanding CI to exercise Python 3.12.

Changes:

  • Added a local strtobool helper to replace distutils.util.strtobool().
  • Updated call sites to use the new helper instead of distutils.
  • Expanded GitHub Actions pytest workflow to run on Python 3.10 and 3.12.

Reviewed changes

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

Show a summary per file
File Description
kpi/utils/strings.py Adds a local strtobool implementation to avoid distutils dependency.
kpi/utils/query_parser/query_parser.py Switches boolean parsing to the new strtobool helper.
kobo/apps/languages/models/language.py Removes distutils usage during CSV import and uses the new helper.
kobo/apps/accounts/tests/test_forms.py Updates deprecated assertEquals to assertEqual.
.github/workflows/pytest.yml Adds Python 3.12 to the pytest matrix.
Comments suppressed due to low confidence (1)

.github/workflows/pytest.yml:71

  • With a Python-version matrix, the Coveralls upload step will run once per Python version. That typically results in duplicate/competing uploads (or requires Coveralls parallel-build configuration). Consider running Coveralls only for a single matrix entry (e.g., the primary runtime) or configuring per-version flag-name + parallel/parallel-finished so coverage reporting stays accurate.
    strategy:
      matrix:
        python-version: ['3.10', '3.12']
        extra-pytest-options:
          - --ds kobo.settings.testing
          - --ds kobo.settings.testing_no_stripe --ignore kobo/apps/stripe
    services:
      postgres:
        image: postgis/postgis:14-3.4
        env:
          POSTGRES_USER: kobo
          POSTGRES_PASSWORD: kobo
          POSTGRES_DB: kpi_test
        ports:
          - 5432:5432
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
      redis_cache:
        image: redis:6.2
        ports:
          - 6379:6379
    steps:
    - uses: actions/checkout@v6
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install uv
      uses: astral-sh/setup-uv@v7
      with: { cache-suffix: 'dev_requirements' }
    - name: Update Debian package lists
      run: sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
    - name: Install Debian dependencies
      # All about YAML line breaks: https://stackoverflow.com/a/21699210
      run: >-
        sudo DEBIAN_FRONTEND=noninteractive apt-get -y install
        gdal-bin gettext libproj-dev postgresql-client ffmpeg
        gcc libc-dev build-essential
    - name: Install Python dependencies
      run: uv pip sync --system dependencies/pip/dev_requirements.txt
    - name: Update translations
      run: git submodule init && git submodule update --remote && python manage.py compilemessages
    - name: Test back-end code
      # Explicitly name the directories where coverage should be measured;
      # specifying just `--cov=.` includes `src`, which contains third-party packages
      run: pytest ${{ matrix.extra-pytest-options }} --cov=hub --cov=kobo --cov=kpi -ra
    - name: Run coveralls for back-end code
      uses: AndreMiras/coveralls-python-action@develop
      # Coveralls action will intermittently give 422 errors - until that issue is resolved this step allowed to error.
      continue-on-error: true

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread kpi/utils/strings.py Outdated
Comment on lines +19 to +34
def strtobool(val):
"""Convert a string representation of truth to true (1) or false (0).

True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.

This is copied and pasted from `distutils.util.strtobool()` in Python 3.10
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError('invalid truth value {!r}'.format(val))
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

strtobool() is new code introduced to replace distutils.util.strtobool() for Python 3.12 compatibility, but it currently has no direct unit test coverage. Since kpi/tests/test_utils.py already covers other helpers in kpi.utils.strings (e.g., split_lines_to_list), adding a small test for the accepted true/false strings and the ValueError case would help prevent regressions during the runtime upgrade.

Copilot uses AI. Check for mistakes.
code = row[1].strip()
try:
featured = util.strtobool(row[2])
featured = strtobool(row[2])
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

strtobool() returns 0/1 ints, but Language.featured is a BooleanField. Right now the try branch assigns an int while the except assigns a bool, which mixes types and can leak 0/1 into downstream code. Consider converting to a boolean (e.g., wrap the result in bool(...)) so featured is consistently a bool before constructing the Language object.

Suggested change
featured = strtobool(row[2])
featured = bool(strtobool(row[2]))

Copilot uses AI. Check for mistakes.
- Dockerfile: switch base image from python3.10 to python3.12
- settings: fix regex escaping in PASSWORD_CUSTOM_CHARACTER_RULES
- strtobool: return bool directly instead of int
- migration 0074: fix dependency to 0073_merge_conflicting_0072
@noliveleger noliveleger merged commit 265169a into django-5.2 Mar 23, 2026
21 of 30 checks passed
@noliveleger noliveleger deleted the python-3.12 branch March 23, 2026 20:38
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.

4 participants