From cd6ff46d4081aec717e882a36d8c3aff05324ce4 Mon Sep 17 00:00:00 2001 From: Pattems Date: Tue, 13 Oct 2026 18:12:00 -0400 Subject: [PATCH 1/3] Replace pkgutil.get_loader for 3.14. pkgutil.get_loader was deprecated in Python 3.12 and removed in 3.14, so importing postgresql.python.command (and with it pg_python) fails with ImportError on 3.14. Resolve the loader with importlib.util.find_spec instead, which is available on every supported version. --- postgresql/python/command.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/postgresql/python/command.py b/postgresql/python/command.py index d88b154..e040659 100644 --- a/postgresql/python/command.py +++ b/postgresql/python/command.py @@ -57,7 +57,17 @@ from gettext import gettext as _ from traceback import print_exception -from pkgutil import get_loader as module_loader +from importlib.util import find_spec + +def module_loader(name): + """ + Return the loader of the named module, or None if it cannot be found. + (Replaces pkgutil.get_loader, which was removed in Python 3.14.) + """ + spec = find_spec(name) + if spec is None: + return None + return spec.loader class single_loader(object): """ From 4ae3746457284f296fa30c373b9e7362f2035846 Mon Sep 17 00:00:00 2001 From: Pattems Date: Thu, 15 Oct 2026 08:59:37 -0400 Subject: [PATCH 2/3] Always set __version__; fixes pg_dotconf import. project.py no longer defines author or date, so the combined import from .project raised ImportError after binding version and before __version__ was assigned. The error was swallowed, leaving the package without __version__ and breaking "from postgresql import *" (__all__ lists __author__ and __date__) and postgresql.bin.pg_dotconf, which does "from .. import __version__". Import only version_info and version, assign __version__ outside the try, and drop __author__ and __date__ from __all__. --- postgresql/__init__.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/postgresql/__init__.py b/postgresql/__init__.py index 60ce8e5..1af6316 100644 --- a/postgresql/__init__.py +++ b/postgresql/__init__.py @@ -10,8 +10,6 @@ for information about Python. """ __all__ = [ - '__author__', - '__date__', '__version__', '__docformat__', 'version', @@ -27,11 +25,10 @@ # Optional. try: - from .project import version_info, version, \ - author as __author__, date as __date__ - __version__ = version + from .project import version_info, version except ImportError: pass +__version__ = version # Avoid importing these until requested. _pg_iri = _pg_driver = _pg_param = None From b8c39af442edda2b8bad4806d23557024cb12e2e Mon Sep 17 00:00:00 2001 From: Pattems Date: Thu, 15 Oct 2026 08:59:57 -0400 Subject: [PATCH 3/3] Fix pg_dotconf -f/--file. The settings-file loop referenced the undefined names comment and unquote (NameError) instead of configfile.comment and configfile.unquote, and it tested the first character of the key rather than the text before it, so commented-out settings in the file would have been applied. Check line[:start], as alter_config() does. --- postgresql/bin/pg_dotconf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/postgresql/bin/pg_dotconf.py b/postgresql/bin/pg_dotconf.py index 31306e9..06599a6 100644 --- a/postgresql/bin/pg_dotconf.py +++ b/postgresql/bin/pg_dotconf.py @@ -39,8 +39,8 @@ def command(args): for line in sf: pl = configfile.parse_line(line) if pl is not None: - if comment not in line[pl[0].start]: - settings[line[pl[0]]] = unquote(line[pl[1]]) + if configfile.comment not in line[:pl[0].start]: + settings[line[pl[0]]] = configfile.unquote(line[pl[1]]) prev = None for p in ca[1:]: