Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ jobs:
strategy:
max-parallel: 5
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10']
# 3.7 is gone from the ubuntu-latest runner images (setup-python:
# "Version 3.7 with arch x64 not found").
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10']
fail-fast: false

steps:
Expand Down
3 changes: 3 additions & 0 deletions experiments/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
class ExperimentsConfig(AppConfig):
name = 'experiments'
label = 'experiments'
# Django >= 6 defaults new projects to BigAutoField; pin the historical
# AutoField so existing installations are not asked for an id migration.
default_auto_field = 'django.db.models.AutoField'

def ready(self):
from django.contrib.auth.signals import user_logged_in, user_logged_out
Expand Down
12 changes: 9 additions & 3 deletions experiments/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def clear_participant_cache(request):
def _get_participant(request, session, user):
if request and hasattr(request, 'user') and not user:
user = request.user
if request and hasattr(request, 'session') and not session:
if request and hasattr(request, 'session') and session is None:
session = request.session

if request and conf.BOT_REGEX.search(request.META.get("HTTP_USER_AGENT", "")):
Expand All @@ -64,7 +64,10 @@ def _get_participant(request, session, user):
return WebUser(user=user, request=request)
else:
return DummyUser()
elif session:
elif session is not None:
# Truthiness is not identity here: since Django 6.1 an *empty* session
# is falsy, and a fresh visitor's empty session must still get a
# WebUser, not a DummyUser.
return WebUser(session=session, request=request)
else:
return DummyUser()
Expand Down Expand Up @@ -409,7 +412,10 @@ def _is_verified_human(self):

@property
def _session_key(self):
if not self.session:
# `is None`, not truthiness: since Django 6.1 an *empty* session is
# falsy, and returning None for every fresh visitor would key all of
# their enrollments and counters to the same identifier.
if self.session is None:
return None
if 'experiments_session_key' not in self.session:
if not self.session.session_key:
Expand Down
8 changes: 8 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ envlist =
{py,pypy}{38,39,310,311}-django{4.1}
{py,pypy}{38,39,310,311,312}-django{4.2}
{py,pypy}{310,311,312}-django{5.0}
{py,pypy}{310,311,312,313}-django{5.1,5.2}
py{312,313}-django{6.0,6.1}

[gh-actions]
python =
Expand All @@ -27,6 +29,8 @@ python =
3.9: py39
3.10: py310
3.11: py311
3.12: py312
3.13: py313
pypy-3.8: pypy38
pypy-3.9: pypy39
pypy-3.10: pypy310
Expand All @@ -51,3 +55,7 @@ deps =
django4.1: Django==4.1.*
django4.2: Django==4.2.*
django5.0: Django==5.0.*
django5.1: Django==5.1.*
django5.2: Django==5.2.*
django6.0: Django==6.0.*
django6.1: Django==6.1.*
Loading