From 952f5d80d3ffcf4c42fe65b66c85f29ae8816da1 Mon Sep 17 00:00:00 2001 From: Mohammed Alkindi Date: Thu, 10 Sep 2026 17:46:00 +0400 Subject: [PATCH] fix: read static discovery documents as UTF-8 The packaged discovery documents are UTF-8, but get_static_doc opened them with no encoding, so they were decoded with the host's locale encoding instead. On a default Windows install (cp1252) this makes build("run", "v1beta1") raise UnicodeDecodeError, and jobs.v2.json decodes to mojibake with no error at all. --- googleapiclient/discovery_cache/__init__.py | 4 +++- tests/test_discovery_cache.py | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/googleapiclient/discovery_cache/__init__.py b/googleapiclient/discovery_cache/__init__.py index 6051191e737..5dc3112e658 100644 --- a/googleapiclient/discovery_cache/__init__.py +++ b/googleapiclient/discovery_cache/__init__.py @@ -69,7 +69,9 @@ def get_static_doc(serviceName, version): doc_name = "{}.{}.json".format(serviceName, version) try: - with open(os.path.join(DISCOVERY_DOC_DIR, doc_name), "r") as f: + with open( + os.path.join(DISCOVERY_DOC_DIR, doc_name), "r", encoding="utf-8" + ) as f: content = f.read() except FileNotFoundError: # File does not exist. Nothing to do here. diff --git a/tests/test_discovery_cache.py b/tests/test_discovery_cache.py index 678350505d6..7fd751b45ba 100644 --- a/tests/test_discovery_cache.py +++ b/tests/test_discovery_cache.py @@ -18,10 +18,12 @@ """Discovery document cache tests.""" import datetime +import os +import tempfile import unittest from unittest import mock -from googleapiclient.discovery_cache import DISCOVERY_DOC_MAX_AGE +from googleapiclient.discovery_cache import DISCOVERY_DOC_MAX_AGE, get_static_doc try: from googleapiclient.discovery_cache.file_cache import Cache as FileCache @@ -59,3 +61,19 @@ def future_now(): # Make sure the content is expired self.assertEqual(None, cache.get(first_url)) + + +class GetStaticDocTest(unittest.TestCase): + def test_reads_discovery_document_as_utf8(self): + # The packaged discovery documents are UTF-8 and must be decoded as + # such regardless of the host's locale encoding. + content = '{"description": "\u201cquoted\u201d"}' + with tempfile.TemporaryDirectory() as doc_dir: + with open( + os.path.join(doc_dir, "fake.v1.json"), "w", encoding="utf-8" + ) as f: + f.write(content) + with mock.patch( + "googleapiclient.discovery_cache.DISCOVERY_DOC_DIR", new=doc_dir + ): + self.assertEqual(content, get_static_doc("fake", "v1"))