From: Varun Chawla Date: Tue, 10 Feb 2026 08:11:28 +0000 (-0800) Subject: fix: correct typo in tstrings error message and fix sql.rst docs X-Git-Tag: 3.3.3~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0db9d8bb76c48e70dffd48776406fd3ffdc89b5a;p=thirdparty%2Fpsycopg.git fix: correct typo in tstrings error message and fix sql.rst docs - Fix error message in _tstrings.py: reference nonexistent "sql.Composite" corrected to "sql.Composable" (the actual base class) - Fix docs/api/sql.rst: remove incorrect escape_identifier() example that passed a str where bytes is required (closes #421) - Fix typo "re-exoprts" -> "re-exports" in conninfo.py Co-Authored-By: Claude Opus 4.6 Note: this MR is AI slop which has been pushed by the author without even considering if it was correct. Corrected by a human being in the next commit on this branch. --- diff --git a/docs/api/sql.rst b/docs/api/sql.rst index e8ca6246d..4b6268fce 100644 --- a/docs/api/sql.rst +++ b/docs/api/sql.rst @@ -26,24 +26,14 @@ instance:: This sort of works, but it is an accident waiting to happen: the table name may be an invalid SQL literal and need quoting; even more serious is the -security problem in case the table name comes from an untrusted source. The -name should be escaped using `~psycopg.pq.Escaping.escape_identifier()`:: +security problem in case the table name comes from an untrusted source. - from psycopg.pq import Escaping +.. note:: - # This works, but it is not optimal - table_name = 'my_table' - cur.execute( - "INSERT INTO %s VALUES (%%s, %%s)" % Escaping.escape_identifier(table_name), - [10, 20]) - -This is now safe, but it somewhat ad-hoc. In case, for some reason, it is -necessary to include a value in the query string (as opposite as in a value) -the merging rule is still different. It is also still relatively dangerous: if -`!escape_identifier()` is forgotten somewhere, the program will usually work, -but will eventually crash in the presence of a table or field name with -containing characters to escape, or will present a potentially exploitable -weakness. + The low-level `~psycopg.pq.Escaping.escape_identifier()` function can be + used to escape a single identifier, but it operates on :sql:`bytes` and + is cumbersome to use in practice. The `!psycopg.sql` module, described + below, is the recommended approach for building dynamic queries safely. The objects exposed by the `!psycopg.sql` module allow generating SQL statements on the fly, separating clearly the variable parts of the statement diff --git a/psycopg/psycopg/_tstrings.py b/psycopg/psycopg/_tstrings.py index 90b1b3e22..e721b7aa9 100644 --- a/psycopg/psycopg/_tstrings.py +++ b/psycopg/psycopg/_tstrings.py @@ -83,7 +83,7 @@ class TemplateProcessor: elif fmt == FMT_SQL: # It must have been processed already raise e.ProgrammingError( - "sql values must be sql.Composite, sql.SQL, or Template;" + "sql values must be sql.Composable, sql.SQL, or Template;" f" got {type(item.value).__qualname__}" f" in {{{item.expression}:{fmt}}}" ) diff --git a/psycopg/psycopg/conninfo.py b/psycopg/psycopg/conninfo.py index f72ec34e0..056810d62 100644 --- a/psycopg/psycopg/conninfo.py +++ b/psycopg/psycopg/conninfo.py @@ -13,7 +13,7 @@ from . import errors as e from . import pq from .abc import ConnDict, ConnParam -# re-exoprts +# re-exports conninfo_attempts = _conninfo_attempts.conninfo_attempts conninfo_attempts_async = _conninfo_attempts_async.conninfo_attempts_async