From 881caeea8c16d9c27f2764a1e47f6f658bfb4f95 Mon Sep 17 00:00:00 2001 From: Scott Nemes Date: Sat, 31 Jan 2026 12:27:48 -0800 Subject: [PATCH 1/2] Convert importlib read_text and open_text uses to newer files() syntax --- changelog.md | 1 + mycli/config.py | 5 +++-- mycli/main.py | 9 ++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 3644bcf2..95e384ef 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ Internal -------- * Remove `align_decimals` preprocessor, which had no effect. * Fix TLS deprecation warning in test suite. +* Convert importlib read_text and open_text uses to newer files() syntax 1.48.0 (2026/01/27) diff --git a/mycli/config.py b/mycli/config.py index b965acd4..964693ae 100644 --- a/mycli/config.py +++ b/mycli/config.py @@ -101,14 +101,15 @@ def read_config_files(files: list[str | TextIOWrapper], list_values: bool = True def create_default_config(list_values: bool = True) -> ConfigObj: import mycli - default_config_file = resources.open_text(mycli, "myclirc") + default_config_file = resources.files(mycli).joinpath("myclirc").open('r') return read_config_file(default_config_file, list_values=list_values) def write_default_config(destination: str, overwrite: bool = False) -> None: import mycli - default_config = resources.read_text(mycli, "myclirc") + with resources.files(mycli).joinpath("myclirc").open('r') as f: + default_config = f.read() destination = os.path.expanduser(destination) if not overwrite and exists(destination): return diff --git a/mycli/main.py b/mycli/main.py index 0e3e37d3..fd1358a1 100755 --- a/mycli/main.py +++ b/mycli/main.py @@ -2005,7 +2005,14 @@ def is_select(status: str | None) -> bool: def thanks_picker() -> str: import mycli - lines = (resources.read_text(mycli, "AUTHORS") + resources.read_text(mycli, "SPONSORS")).split("\n") + lines: str = "" + with resources.files(mycli).joinpath("AUTHORS").open('r') as f: + lines += f.read() + + with resources.files(mycli).joinpath("SPONSORS").open('r') as f: + lines += f.read() + + lines = lines.split("\n") contents = [] for line in lines: From e998179d4ce059a4270486649c4d9bff64daf118 Mon Sep 17 00:00:00 2001 From: Scott Nemes Date: Sat, 31 Jan 2026 12:46:30 -0800 Subject: [PATCH 2/2] Reworked typing --- mycli/config.py | 10 +++++----- mycli/main.py | 12 +++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/mycli/config.py b/mycli/config.py index 964693ae..66555b89 100644 --- a/mycli/config.py +++ b/mycli/config.py @@ -6,7 +6,7 @@ from os.path import exists import struct import sys -from typing import IO, BinaryIO, Literal, TextIO +from typing import IO, BinaryIO, Literal from configobj import ConfigObj, ConfigObjError from Cryptodome.Cipher import AES @@ -23,7 +23,7 @@ def log(logger: logging.Logger, level: int, message: str) -> None: logger.log(level, message) -def read_config_file(f: str | TextIO | TextIOWrapper, list_values: bool = True) -> ConfigObj | None: +def read_config_file(f: str | IO[str], list_values: bool = True) -> ConfigObj | None: """Read a config file. *list_values* set to `True` is the default behavior of ConfigObj. @@ -50,7 +50,7 @@ def read_config_file(f: str | TextIO | TextIOWrapper, list_values: bool = True) return config -def get_included_configs(config_file: str | TextIOWrapper) -> list[str | TextIOWrapper]: +def get_included_configs(config_file: str | IO[str]) -> list[str | IO[str]]: """Get a list of configuration files that are included into config_path with !includedir directive. @@ -62,7 +62,7 @@ def get_included_configs(config_file: str | TextIOWrapper) -> list[str | TextIOW """ if not isinstance(config_file, str) or not os.path.isfile(config_file): return [] - included_configs: list[str | TextIOWrapper] = [] + included_configs: list[str | IO[str]] = [] try: with open(config_file) as f: @@ -78,7 +78,7 @@ def get_included_configs(config_file: str | TextIOWrapper) -> list[str | TextIOW return included_configs -def read_config_files(files: list[str | TextIOWrapper], list_values: bool = True) -> ConfigObj: +def read_config_files(files: list[str | IO[str]], list_values: bool = True) -> ConfigObj: """Read and merge a list of config files.""" config = create_default_config(list_values=list_values) diff --git a/mycli/main.py b/mycli/main.py index fd1358a1..98ced43f 100755 --- a/mycli/main.py +++ b/mycli/main.py @@ -10,7 +10,7 @@ import sys import threading import traceback -from typing import Any, Generator, Iterable, Literal +from typing import IO, Any, Generator, Iterable, Literal try: from pwd import getpwuid @@ -90,7 +90,7 @@ class MyCli: defaults_suffix = None # In order of being loaded. Files lower in list override earlier ones. - cnf_files: list[str | TextIOWrapper] = [ + cnf_files: list[str | IO[str]] = [ "/etc/my.cnf", "/etc/mysql/my.cnf", "/usr/local/etc/my.cnf", @@ -99,7 +99,7 @@ class MyCli: # check XDG_CONFIG_HOME exists and not an empty string xdg_config_home = os.environ.get("XDG_CONFIG_HOME", "~/.config") - system_config_files: list[str | TextIOWrapper] = [ + system_config_files: list[str | IO[str]] = [ "/etc/myclirc", os.path.join(os.path.expanduser(xdg_config_home), "mycli", "myclirc"), ] @@ -134,7 +134,7 @@ def __init__( self.cnf_files = [defaults_file] # Load config. - config_files: list[str | TextIOWrapper] = self.system_config_files + [myclirc] + [self.pwd_config_file] + config_files: list[str | IO[str]] = self.system_config_files + [myclirc] + [self.pwd_config_file] c = self.config = read_config_files(config_files) self.multi_line = c["main"].as_bool("multi_line") self.key_bindings = c["main"]["key_bindings"] @@ -2011,11 +2011,9 @@ def thanks_picker() -> str: with resources.files(mycli).joinpath("SPONSORS").open('r') as f: lines += f.read() - - lines = lines.split("\n") contents = [] - for line in lines: + for line in lines.split("\n"): if m := re.match(r"^ *\* (.*)", line): contents.append(m.group(1)) return choice(contents) if contents else 'our sponsors'