Skip to content

Commit 544a429

Browse files
committed
fix!: Ensure all open uses UTF-8 instead of default encoding.
Signed-off-by: Karthik Bekal Pattathana <[email protected]>
1 parent 509a868 commit 544a429

File tree

18 files changed

+96
-38
lines changed

18 files changed

+96
-38
lines changed

.github/scripts/get_latest_changelog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import re
3333

3434
h2 = r"^##\s.*$"
35-
with open("CHANGELOG.md") as f:
35+
with open("CHANGELOG.md", encoding="utf-8") as f:
3636
contents = f.read()
3737
matches = re.findall(h2, contents, re.MULTILINE)
3838
changelog = contents[: contents.find(matches[1]) - 1] if len(matches) > 1 else contents

src/openjd/adaptor_runtime/_background/backend_runner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ def run(self, *, on_connection_file_written: List[Callable[[], None]] | None = N
116116
raise
117117

118118
try:
119-
with secure_open(self._connection_file_path, open_mode="w") as conn_file:
119+
with secure_open(
120+
self._connection_file_path, open_mode="w", encoding="utf-8"
121+
) as conn_file:
120122
json.dump(
121123
ConnectionSettings(server_path),
122124
conn_file,

src/openjd/adaptor_runtime/_background/frontend_runner.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def init(
153153
bootstrap_output_path = os.path.join(
154154
bootstrap_log_dir, f"adaptor-runtime-background-bootstrap-output-{bootstrap_id}.log"
155155
)
156-
output_log_file = open(bootstrap_output_path, mode="w+")
156+
output_log_file = open(bootstrap_output_path, mode="w+", encoding="utf-8")
157157
try:
158158
process = subprocess.Popen(
159159
args,
@@ -194,7 +194,7 @@ def init(
194194
if process.stderr:
195195
process.stderr.close()
196196

197-
with open(bootstrap_output_path, mode="r") as f:
197+
with open(bootstrap_output_path, mode="r", encoding="utf-8") as f:
198198
bootstrap_output = f.readlines()
199199
_logger.info("========== BEGIN BOOTSTRAP OUTPUT CONTENTS ==========")
200200
for line in bootstrap_output:
@@ -203,7 +203,7 @@ def init(
203203

204204
_logger.info(f"Checking for bootstrap logs at '{bootstrap_log_path}'")
205205
try:
206-
with open(bootstrap_log_path, mode="r") as f:
206+
with open(bootstrap_log_path, mode="r", encoding="utf-8") as f:
207207
bootstrap_logs = f.readlines()
208208
except Exception as e:
209209
_logger.error(f"Failed to get bootstrap logs at '{bootstrap_log_path}': {e}")
@@ -442,7 +442,8 @@ def _wait_for_connection_file(
442442

443443
def file_is_openable() -> bool:
444444
try:
445-
open(filepath, mode="r").close()
445+
with open(filepath, mode="r", encoding="utf-8"):
446+
pass
446447
except IOError:
447448
# File is not available yet
448449
return False

src/openjd/adaptor_runtime/_background/loaders.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ConnectionSettingsFileLoader(ConnectionSettingsLoader):
3535

3636
def load(self) -> ConnectionSettings:
3737
try:
38-
with open(self.file_path) as conn_file:
38+
with open(self.file_path, encoding="utf-8") as conn_file:
3939
loaded_settings = json.load(conn_file)
4040
except OSError as e:
4141
errmsg = f"Failed to open connection file '{self.file_path}': {e}"

src/openjd/adaptor_runtime/_background/log_buffers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def __init__(self, filepath: str, *, formatter: logging.Formatter | None = None)
132132
def buffer(self, record: logging.LogRecord) -> None:
133133
with (
134134
self._file_lock,
135-
secure_open(self._filepath, open_mode="a") as f,
135+
secure_open(self._filepath, open_mode="a", encoding="utf-8") as f,
136136
):
137137
f.write(self._format(record))
138138

@@ -142,7 +142,7 @@ def chunk(self) -> BufferedOutput:
142142
with (
143143
self._chunk_lock,
144144
self._file_lock,
145-
open(self._filepath, mode="r") as f,
145+
open(self._filepath, mode="r", encoding="utf-8") as f,
146146
):
147147
self._chunk.id = id
148148
f.seek(self._chunk.start)

src/openjd/adaptor_runtime/_entrypoint.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ def _init_loggers(self, *, bootstrap_log_path: str | None = None) -> _LogConfig:
179179
formatter = ConditionalFormatter(
180180
"%(levelname)s: %(message)s", ignore_patterns=[_OPENJD_LOG_REGEX]
181181
)
182+
183+
# Ensure stdout uses UTF-8 encoding to avoid issues with
184+
# encoding Non-ASCII characters.
185+
sys.stdout.reconfigure(encoding="utf-8") # type: ignore
182186
stream_handler = logging.StreamHandler(sys.stdout)
183187
stream_handler.setFormatter(formatter)
184188

@@ -590,14 +594,14 @@ def _load_data(data: str) -> dict:
590594

591595
def _load_yaml_json(data: str) -> Any:
592596
"""
593-
Loads a YAML/JSON file/string.
597+
Loads a YAML/JSON file/string using the UTF-8 encoding.
594598
595599
Note that yaml.safe_load() is capable of loading JSON documents.
596600
"""
597601
loaded_yaml = None
598602
if data.startswith("file://"):
599603
filepath = data[len("file://") :]
600-
with open(filepath) as yaml_file:
604+
with open(filepath, encoding="utf-8") as yaml_file:
601605
loaded_yaml = yaml.safe_load(yaml_file)
602606
else:
603607
loaded_yaml = yaml.safe_load(data)

src/openjd/adaptor_runtime/adaptors/_validator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def from_schema_file(schema_path: str) -> AdaptorDataValidator:
7474
schema_path (str): The path to the JSON schema file to use.
7575
"""
7676
try:
77-
with open(schema_path) as schema_file:
77+
with open(schema_path, encoding="utf-8") as schema_file:
7878
schema = json.load(schema_file)
7979
except json.JSONDecodeError as e:
8080
_logger.error(f"Failed to decode JSON schema file: {e}")
@@ -148,7 +148,7 @@ def _load_yaml_json(data: str) -> Any:
148148
loaded_yaml = None
149149
if data.startswith("file://"):
150150
filepath = data[len("file://") :]
151-
with open(filepath) as yaml_file:
151+
with open(filepath, encoding="utf-8") as yaml_file:
152152
loaded_yaml = yaml.safe_load(yaml_file)
153153
else:
154154
loaded_yaml = yaml.safe_load(data)

src/openjd/adaptor_runtime/adaptors/configuration/_configuration.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ def from_file(
8282
"""
8383

8484
try:
85-
config = json.load(open(config_path))
85+
with open(config_path, encoding="utf-8") as config_file:
86+
config = json.load(config_file)
8687
except OSError as e:
8788
_logger.error(f"Failed to open configuration at {config_path}: {e}")
8889
raise
@@ -102,7 +103,8 @@ def from_file(
102103
schema_paths = schema_path if isinstance(schema_path, list) else [schema_path]
103104
for path in schema_paths:
104105
try:
105-
schema = json.load(open(path))
106+
with open(path, encoding="utf-8") as schema_file:
107+
schema = json.load(schema_file)
106108
except OSError as e:
107109
_logger.error(f"Failed to open configuration schema at {path}: {e}")
108110
raise

src/openjd/adaptor_runtime/adaptors/configuration/_configuration_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def _ensure_config_file(filepath: str, *, create: bool = False) -> bool:
9595
_logger.info(f"Creating empty configuration at {filepath}")
9696
try:
9797
os.makedirs(os.path.dirname(filepath), mode=stat.S_IRWXU, exist_ok=True)
98-
with secure_open(filepath, open_mode="w") as f:
98+
with secure_open(filepath, open_mode="w", encoding="utf-8") as f:
9999
json.dump({}, f)
100100
except OSError as e:
101101
_logger.warning(f"Could not write empty configuration to {filepath}: {e}")

test/openjd/adaptor_runtime/integ/_utils/test_secure_open.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def create_file():
2424
f"secure_open_test_{''.join(random.choice(string.ascii_letters) for _ in range(10))}.txt"
2525
)
2626
test_file_path = os.path.join(tempfile.gettempdir(), test_file_name)
27-
with secure_open(test_file_path, open_mode="w") as test_file:
27+
with secure_open(test_file_path, open_mode="w", encoding="utf-8") as test_file:
2828
test_file.write(file_content)
2929
yield test_file_path, file_content
3030
os.remove(test_file_path)
@@ -36,7 +36,7 @@ def test_secure_open_write_and_read(self, create_file):
3636
Test if the file owner can write and read the file
3737
"""
3838
test_file_path, file_content = create_file
39-
with secure_open(test_file_path, open_mode="r") as test_file:
39+
with secure_open(test_file_path, open_mode="r", encoding="utf-8") as test_file:
4040
result = test_file.read()
4141
assert result == file_content
4242

@@ -61,7 +61,7 @@ def test_secure_open_file_windows_permission(self, create_file, win_test_user):
6161

6262
try:
6363
with pytest.raises(PermissionError):
64-
with open(test_file_path, "r") as f:
64+
with open(test_file_path, "r", encoding="utf-8") as f:
6565
f.read()
6666
finally:
6767
# Revert the impersonation

0 commit comments

Comments
 (0)