Skip to content

Commit 4079d93

Browse files
rtibblesbotclaude
andcommitted
Vendor EnvironmentVarGuard for Python 3.14 compatibility
- Replace try/except import chain with a vendored EnvironmentVarGuard class using unittest.mock.patch.dict(os.environ) - Add tests for the vendored EnvironmentVarGuard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d465459 commit 4079d93

2 files changed

Lines changed: 58 additions & 11 deletions

File tree

tests/testapp/tests/compat.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
try:
2-
# In the Python EOL GH workflows, we have to install backported version
3-
# as the Docker container images we use does not have the test module installed.
4-
from backports.test.support import EnvironmentVarGuard # noqa F401
5-
except ImportError:
6-
try:
7-
# For python >3.8 and <3.10
8-
from test.support import EnvironmentVarGuard # noqa F401
9-
except ImportError:
10-
# In Python 3.10, this has been moved to test.support.os_helper
11-
from test.support.os_helper import EnvironmentVarGuard # noqa F401
1+
import os
2+
from unittest.mock import patch as _patch
3+
4+
5+
class EnvironmentVarGuard:
6+
"""
7+
Vendored replacement for the removed test.support EnvironmentVarGuard.
8+
Uses unittest.mock.patch.dict(os.environ) under the hood.
9+
Supports the context-manager-with-dict-assignment pattern:
10+
with EnvironmentVarGuard() as env: env[k] = v
11+
"""
12+
13+
def __init__(self):
14+
self._patcher = _patch.dict(os.environ)
15+
16+
def __enter__(self):
17+
self._patcher.start()
18+
return os.environ
19+
20+
def __exit__(self, *args):
21+
self._patcher.stop()

tests/testapp/tests/test_compat.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import os
2+
import uuid
3+
4+
from django.test import SimpleTestCase
5+
6+
from .compat import EnvironmentVarGuard
7+
8+
9+
class EnvironmentVarGuardTestCase(SimpleTestCase):
10+
"""Tests for the vendored EnvironmentVarGuard."""
11+
12+
def test_sets_env_var_inside_context(self):
13+
key = "MORANGO_TEST_" + uuid.uuid4().hex[:8]
14+
with EnvironmentVarGuard() as env:
15+
env[key] = "test_value"
16+
self.assertEqual(os.environ[key], "test_value")
17+
18+
def test_reverts_env_var_on_exit(self):
19+
key = "MORANGO_TEST_" + uuid.uuid4().hex[:8]
20+
with EnvironmentVarGuard() as env:
21+
env[key] = "test_value"
22+
self.assertNotIn(key, os.environ)
23+
24+
def test_reverts_modified_env_var_on_exit(self):
25+
key = "MORANGO_TEST_" + uuid.uuid4().hex[:8]
26+
os.environ[key] = "original"
27+
try:
28+
with EnvironmentVarGuard() as env:
29+
env[key] = "modified"
30+
self.assertEqual(os.environ[key], "modified")
31+
self.assertEqual(os.environ[key], "original")
32+
finally:
33+
os.environ.pop(key, None)
34+
35+
def test_returns_os_environ(self):
36+
with EnvironmentVarGuard() as env:
37+
self.assertIs(env, os.environ)

0 commit comments

Comments
 (0)