From 55cb3c8ac186f7664b38d66fb4c7e678fe524741 Mon Sep 17 00:00:00 2001
From: Konstantin Alekseev <mail@kalekseev.com>
Date: Mon, 26 Apr 2021 15:19:13 +0300
Subject: [PATCH] =?UTF-8?q?[3.2.x]=20Fixed=20#32687=20--=20Restored=20pass?=
 =?UTF-8?q?ing=20process=E2=80=99=20environment=20to=20underlying=20tool?=
 =?UTF-8?q?=20in=20dbshell=20on=20PostgreSQL.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Regression in bbe6fbb8768e8fb1aecb96d51c049d7ceaf802d3.

Backport of 6e742dabc95b00ba896434293556adeb4dbaee8a from main.
---
 django/db/backends/base/client.py       |  3 +--
 django/db/backends/postgresql/client.py |  2 +-
 docs/releases/3.2.1.txt                 |  3 +++
 tests/backends/base/test_client.py      | 14 ++++++++++++++
 tests/dbshell/test_postgresql.py        |  4 ++--
 5 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/django/db/backends/base/client.py b/django/db/backends/base/client.py
index 339f1e863c..8aca821fd2 100644
--- a/django/db/backends/base/client.py
+++ b/django/db/backends/base/client.py
@@ -21,6 +21,5 @@ class BaseDatabaseClient:
 
     def runshell(self, parameters):
         args, env = self.settings_to_cmd_args_env(self.connection.settings_dict, parameters)
-        if env:
-            env = {**os.environ, **env}
+        env = {**os.environ, **env} if env else None
         subprocess.run(args, env=env, check=True)
diff --git a/django/db/backends/postgresql/client.py b/django/db/backends/postgresql/client.py
index 7965401163..44f30f7939 100644
--- a/django/db/backends/postgresql/client.py
+++ b/django/db/backends/postgresql/client.py
@@ -41,7 +41,7 @@ class DatabaseClient(BaseDatabaseClient):
             env['PGSSLCERT'] = str(sslcert)
         if sslkey:
             env['PGSSLKEY'] = str(sslkey)
-        return args, env
+        return args, (env or None)
 
     def runshell(self, parameters):
         sigint_handler = signal.getsignal(signal.SIGINT)
diff --git a/docs/releases/3.2.1.txt b/docs/releases/3.2.1.txt
index 83d317bc7e..1c8776a0bf 100644
--- a/docs/releases/3.2.1.txt
+++ b/docs/releases/3.2.1.txt
@@ -65,3 +65,6 @@ Bugfixes
   admin changelist now uses ``Exists()`` instead ``QuerySet.distinct()``
   because calling ``delete()`` after ``distinct()`` is not allowed in Django
   3.2 to address a data loss possibility.
+
+* Fixed a regression in Django 3.2 where the calling process environment would
+  not be passed to the ``dbshell`` command on PostgreSQL (:ticket:`32687`).
diff --git a/tests/backends/base/test_client.py b/tests/backends/base/test_client.py
index 4573bbe97b..d9e5cc8883 100644
--- a/tests/backends/base/test_client.py
+++ b/tests/backends/base/test_client.py
@@ -1,3 +1,5 @@
+from unittest import mock
+
 from django.db import connection
 from django.db.backends.base.client import BaseDatabaseClient
 from django.test import SimpleTestCase
@@ -14,3 +16,15 @@ class SimpleDatabaseClientTests(SimpleTestCase):
         )
         with self.assertRaisesMessage(NotImplementedError, msg):
             self.client.settings_to_cmd_args_env(None, None)
+
+    def test_runshell_use_environ(self):
+        for env in [None, {}]:
+            with self.subTest(env=env):
+                with mock.patch('subprocess.run') as run:
+                    with mock.patch.object(
+                        BaseDatabaseClient,
+                        'settings_to_cmd_args_env',
+                        return_value=([], env),
+                    ):
+                        self.client.runshell(None)
+                    run.assert_called_once_with([], env=None, check=True)
diff --git a/tests/dbshell/test_postgresql.py b/tests/dbshell/test_postgresql.py
index ccf49d7e50..34f08dee16 100644
--- a/tests/dbshell/test_postgresql.py
+++ b/tests/dbshell/test_postgresql.py
@@ -39,7 +39,7 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase):
                 'PORT': '444',
             }), (
                 ['psql', '-U', 'someuser', '-h', 'somehost', '-p', '444', 'dbname'],
-                {},
+                None,
             )
         )
 
@@ -100,7 +100,7 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase):
     def test_parameters(self):
         self.assertEqual(
             self.settings_to_cmd_args_env({'NAME': 'dbname'}, ['--help']),
-            (['psql', 'dbname', '--help'], {}),
+            (['psql', 'dbname', '--help'], None),
         )
 
     @skipUnless(connection.vendor == 'postgresql', 'Requires a PostgreSQL connection')