Package: python-oauth2client
Followup-For: Bug #1058392
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu noble ubuntu-patch
Control: tags -1 patch

Dear Maintainer,

Python 3.12 dropped support in unittest.TestCase for assertRaisesRegexp and
assertEquals. These two functions were provided as a compability layer
since their deprecation in Python 3.2.

In Ubuntu, the attached patch was applied to achieve the following:

  * Replace obsolete assert* calls (dropped from Python 3.12) with their
    correct alternative to fix FTBFS.
     - debian/patches/python312-support.patch

Thanks for considering the patch.


-- System Information:
Debian Release: trixie/sid
  APT prefers mantic-updates
  APT policy: (500, 'mantic-updates'), (500, 'mantic-security'), (500, 
'mantic'), (100, 'mantic-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.1.0-16-generic (SMP w/8 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff -Nru python-oauth2client-4.1.3/debian/patches/python312-support.patch 
python-oauth2client-4.1.3/debian/patches/python312-support.patch
--- python-oauth2client-4.1.3/debian/patches/python312-support.patch    
1970-01-01 01:00:00.000000000 +0100
+++ python-oauth2client-4.1.3/debian/patches/python312-support.patch    
2024-02-16 10:51:37.000000000 +0100
@@ -0,0 +1,252 @@
+Description: Fix use of obsolete assert statements dropped in Python 3.12
+ Since Python 3.2, assertEquals and assertRaisesRegexp (+ others) have been
+ deprecated in favor of assertEqual and assertRaisesRegex.
+ In Python 3.12, the deprecated names got dropped, causing oauth2client to
+ FTBFS.
+ .
+ The patch is not meant for upstream inclusion since the project upstream is
+ deprecated (in favor of python-google-auth) and the repository is read only.
+Author: Olivier Gayot <olivier.ga...@canonical.com>
+Bug-Debian: https://bugs.debian.org/1058392
+Forwarded: not-needed
+Last-Update: 2024-02-16
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/tests/contrib/appengine/test_appengine.py
++++ b/tests/contrib/appengine/test_appengine.py
+@@ -906,7 +906,7 @@
+         self.decorator = decorator
+         self.test_required()
+         http = self.decorator.http()
+-        self.assertEquals('foo_access_token',
++        self.assertEqual('foo_access_token',
+                           http.request.credentials.access_token)
+ 
+         # revoke_uri is not required
+--- a/tests/contrib/test_devshell.py
++++ b/tests/contrib/test_devshell.py
+@@ -205,7 +205,7 @@
+     def test_no_refresh_token(self):
+         with _AuthReferenceServer():
+             creds = devshell.DevshellCredentials()
+-            self.assertEquals(None, creds.refresh_token)
++            self.assertIsNone(creds.refresh_token)
+ 
+     @mock.patch('oauth2client.client._UTCNOW')
+     def test_reads_credentials(self, utcnow):
+--- a/tests/contrib/test_keyring_storage.py
++++ b/tests/contrib/test_keyring_storage.py
+@@ -104,7 +104,7 @@
+                                autospec=True) as get_password:
+             store = keyring_storage.Storage('my_unit_test', 'me')
+             credentials = store.get()
+-            self.assertEquals(None, credentials)
++            self.assertIsNone(credentials)
+             get_password.assert_called_once_with('my_unit_test', 'me')
+ 
+     def test_get_with_malformed_json_credentials_stored(self):
+@@ -113,7 +113,7 @@
+                                autospec=True) as get_password:
+             store = keyring_storage.Storage('my_unit_test', 'me')
+             credentials = store.get()
+-            self.assertEquals(None, credentials)
++            self.assertIsNone(credentials)
+             get_password.assert_called_once_with('my_unit_test', 'me')
+ 
+     def test_get_and_set_with_json_credentials_stored(self):
+@@ -139,7 +139,7 @@
+                                    return_value=None,
+                                    autospec=True) as set_password:
+                 store = keyring_storage.Storage('my_unit_test', 'me')
+-                self.assertEquals(None, store.get())
++                self.assertIsNone(store.get())
+ 
+                 store.put(credentials)
+ 
+--- a/tests/test_client.py
++++ b/tests/test_client.py
+@@ -436,7 +436,7 @@
+             'File {0} \(pointed by {1} environment variable\) does not '
+             'exist!'.format(
+                 nonexistent_file, client.GOOGLE_APPLICATION_CREDENTIALS))
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             client._get_environment_variable_file()
+ 
+@@ -541,7 +541,7 @@
+             "'{1}' values\)".format(client.AUTHORIZED_USER,
+                                     client.SERVICE_ACCOUNT))
+ 
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             client._get_application_default_credential_from_file(
+                 credentials_file)
+@@ -552,7 +552,7 @@
+                          'application_default_credentials_malformed_2.json'))
+         expected_err_msg = (
+             'The following field\(s\) must be defined: private_key_id')
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             client._get_application_default_credential_from_file(
+                 credentials_file)
+@@ -569,7 +569,7 @@
+         missing_fields = ['first', 'second', 'third']
+         expected_err_msg = ('The following field\(s\) must be defined: ' +
+                             ', '.join(missing_fields))
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             client._raise_exception_for_missing_fields(missing_fields)
+ 
+@@ -580,7 +580,7 @@
+         expected_err_msg = ('An error was encountered while reading '
+                             'json file: ' + credential_file +
+                             extra_help + ': ' + str(error))
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             client._raise_exception_for_reading_json(
+                 credential_file, extra_help, error)
+@@ -721,7 +721,7 @@
+         credentials_filename = None
+         expected_err_msg = (r'The parameter passed to the from_stream\(\) '
+                             r'method should point to a file.')
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             self.get_a_google_credentials_object().from_stream(
+                 credentials_filename)
+@@ -737,7 +737,7 @@
+             "'type' field should be defined \(and have one of the '" +
+             client.AUTHORIZED_USER + "' or '" + client.SERVICE_ACCOUNT +
+             "' values\)")
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             self.get_a_google_credentials_object().from_stream(
+                 credentials_file)
+@@ -752,7 +752,7 @@
+             ' \(provided as parameter to the from_stream\(\) method\): '
+             'The following field\(s\) must be defined: '
+             'private_key_id')
+-        with 
self.assertRaisesRegexp(client.ApplicationDefaultCredentialsError,
++        with self.assertRaisesRegex(client.ApplicationDefaultCredentialsError,
+                                      expected_err_msg):
+             self.get_a_google_credentials_object().from_stream(
+                 credentials_file)
+@@ -1872,7 +1872,7 @@
+             data=b'error=invalid_request',
+         )
+ 
+-        with self.assertRaisesRegexp(client.FlowExchangeError,
++        with self.assertRaisesRegex(client.FlowExchangeError,
+                                      'invalid_request'):
+             self.flow.step2_exchange(code='some random code', http=http)
+ 
+@@ -2055,7 +2055,7 @@
+         http = http_mock.HttpMock(data=payload)
+ 
+         code = {'error': 'thou shall not pass'}
+-        with self.assertRaisesRegexp(
++        with self.assertRaisesRegex(
+                 client.FlowExchangeError, 'shall not pass'):
+             self.flow.step2_exchange(code=code, http=http)
+ 
+@@ -2188,7 +2188,7 @@
+ 
+         err_msg = ('This OAuth 2.0 flow is unsupported: '
+                    '{0!r}'.format(client_type))
+-        with self.assertRaisesRegexp(client.UnknownClientSecretsFlowError,
++        with self.assertRaisesRegex(client.UnknownClientSecretsFlowError,
+                                      err_msg):
+             client.flow_from_clientsecrets(filename, None, cache=cache)
+ 
+--- a/tests/test_clientsecrets.py
++++ b/tests/test_clientsecrets.py
+@@ -215,8 +215,8 @@
+                 clientsecrets.InvalidClientSecretsError) as exc_manager:
+             clientsecrets._loadfile(NONEXISTENT_FILE)
+ 
+-        self.assertEquals(exc_manager.exception.args[1], NONEXISTENT_FILE)
+-        self.assertEquals(exc_manager.exception.args[3], errno.ENOENT)
++        self.assertEqual(exc_manager.exception.args[1], NONEXISTENT_FILE)
++        self.assertEqual(exc_manager.exception.args[3], errno.ENOENT)
+ 
+ 
+ class CachedClientsecretsTests(unittest.TestCase):
+--- a/tests/test_file.py
++++ b/tests/test_file.py
+@@ -122,9 +122,9 @@
+         with open(FILENAME) as credentials_file:
+             data = json.load(credentials_file)
+ 
+-        self.assertEquals(data['access_token'], 'foo')
+-        self.assertEquals(data['_class'], 'OAuth2Credentials')
+-        self.assertEquals(data['_module'], 
client.OAuth2Credentials.__module__)
++        self.assertEqual(data['access_token'], 'foo')
++        self.assertEqual(data['_class'], 'OAuth2Credentials')
++        self.assertEqual(data['_module'], client.OAuth2Credentials.__module__)
+ 
+     def test_token_refresh_store_expired(self):
+         expiration = (datetime.datetime.utcnow() -
+@@ -144,7 +144,7 @@
+         http = http_mock.HttpMock(data=response_content)
+ 
+         credentials._refresh(http)
+-        self.assertEquals(credentials.access_token, access_token)
++        self.assertEqual(credentials.access_token, access_token)
+ 
+         # Verify mocks.
+         self.assertEqual(http.requests, 1)
+@@ -207,7 +207,7 @@
+         storage.put(new_cred)
+ 
+         credentials._refresh(None)
+-        self.assertEquals(credentials.access_token, 'bar')
++        self.assertEqual(credentials.access_token, 'bar')
+ 
+     def test_token_refresh_stream_body(self):
+         expiration = (datetime.datetime.utcnow() +
+@@ -263,10 +263,10 @@
+         credentials = storage.get()
+ 
+         self.assertIsNotNone(credentials)
+-        self.assertEquals('foo', credentials.access_token)
++        self.assertEqual('foo', credentials.access_token)
+ 
+         self.assertTrue(os.path.exists(FILENAME))
+ 
+         if os.name == 'posix':  # pragma: NO COVER
+             mode = os.stat(FILENAME).st_mode
+-            self.assertEquals('0o600', oct(stat.S_IMODE(mode)))
++            self.assertEqual('0o600', oct(stat.S_IMODE(mode)))
+--- a/tests/test_service_account.py
++++ b/tests/test_service_account.py
+@@ -571,7 +571,7 @@
+         utcnow.return_value = T3_DATE
+         transport.request(http, self.url)
+         token_2 = self.jwt.access_token
+-        self.assertEquals(self.jwt.token_expiry, T3_EXPIRY_DATE)
++        self.assertEqual(self.jwt.token_expiry, T3_EXPIRY_DATE)
+         self.assertNotEqual(token_1, token_2)
+ 
+         # Verify mocks.
+@@ -615,7 +615,7 @@
+ 
+         utcnow.return_value = T2_DATE
+         response, _ = transport.request(http, self.url)
+-        self.assertEquals(response.status, http_client.OK)
++        self.assertEqual(response.status, http_client.OK)
+         token_2 = self.jwt.access_token
+         # Check the 401 forced a new token
+         self.assertNotEqual(token_1, token_2)
+@@ -654,5 +654,5 @@
+         utcnow.return_value = T2_DATE
+         self.jwt.refresh(None)
+         token_2 = self.jwt.access_token
+-        self.assertEquals(self.jwt.token_expiry, T2_EXPIRY_DATE)
++        self.assertEqual(self.jwt.token_expiry, T2_EXPIRY_DATE)
+         self.assertNotEqual(token_1, token_2)
diff -Nru python-oauth2client-4.1.3/debian/patches/series 
python-oauth2client-4.1.3/debian/patches/series
--- python-oauth2client-4.1.3/debian/patches/series     2023-08-17 
18:22:35.000000000 +0200
+++ python-oauth2client-4.1.3/debian/patches/series     2024-02-16 
10:51:37.000000000 +0100
@@ -1,3 +1,5 @@
+python312-support.patch
 skip-network-doing-unit-test.patch
 remove-broken-tests.patch
 fix-hmac.new-call-in-py3.8.patch

Reply via email to