]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Drop connection.set_client_encoding
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 14 May 2021 21:11:50 +0000 (23:11 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 26 Sep 2021 22:08:43 +0000 (00:08 +0200)
The property might have been super useful in pre-unicode times, but now
it is really an implementation detail.

The connection encoding can be still changed setting the GUC or with a
PGOPTION or option in the connection params.

12 files changed:
docs/api/connections.rst
psycopg/psycopg/connection.py
psycopg/psycopg/connection_async.py
tests/test_connection.py
tests/test_connection_async.py
tests/test_copy.py
tests/test_copy_async.py
tests/test_cursor.py
tests/test_cursor_async.py
tests/test_errors.py
tests/test_sql.py
tests/types/test_string.py

index 8fff068d549e36c7e162227541140026fffceb21..19d3ae2c5d66e6ae80565c6211b92b695040cc83 100644 (file)
@@ -227,10 +227,6 @@ The `!Connection` class
 
     .. autoattribute:: client_encoding
 
-        The property is writable for sync connections, read-only for async
-        ones: you should call ``await`` `~AsyncConnection.set_client_encoding`\
-        :samp:`({value})` instead.
-
         The value returned is always normalized to the Python codec
         `~codecs.CodecInfo.name`::
 
@@ -356,7 +352,6 @@ The `!AsyncConnection` class
                     ...
 
     .. automethod:: notifies
-    .. automethod:: set_client_encoding
     .. automethod:: set_autocommit
     .. automethod:: set_isolation_level
     .. automethod:: set_read_only
index 419f0193999ef06ef646892d38bc318b66aca03f..8b4900a014b179f8e441a30dfc3a919e02b6a601 100644 (file)
@@ -265,22 +265,6 @@ class BaseConnection(Generic[Row]):
         pgenc = self.pgconn.parameter_status(b"client_encoding") or b"UTF8"
         return encodings.pg2py(pgenc)
 
-    @client_encoding.setter
-    def client_encoding(self, name: str) -> None:
-        self._set_client_encoding(name)
-
-    def _set_client_encoding(self, name: str) -> None:
-        raise NotImplementedError
-
-    def _set_client_encoding_gen(self, name: str) -> PQGen[None]:
-        self.pgconn.send_query_params(
-            b"SELECT set_config('client_encoding', $1, false)",
-            [encodings.py2pg(name)],
-        )
-        (result,) = yield from execute(self.pgconn)
-        if result.status != ExecStatus.TUPLES_OK:
-            raise e.error_from_result(result, encoding=self.client_encoding)
-
     @property
     def info(self) -> ConnectionInfo:
         """A `ConnectionInfo` attribute to inspect connection properties."""
@@ -806,7 +790,3 @@ class Connection(BaseConnection[Row]):
     def _set_deferrable(self, value: Optional[bool]) -> None:
         with self.lock:
             super()._set_deferrable(value)
-
-    def _set_client_encoding(self, name: str) -> None:
-        with self.lock:
-            self.wait(self._set_client_encoding_gen(name))
index 44bd6d040d69a5eea0c4a25f98b190b2da19fc72..7f6b3a3af3a15eb2fc4772b113a4bed7c6a0515e 100644 (file)
@@ -318,14 +318,6 @@ class AsyncConnection(BaseConnection[Row]):
         async with self.lock:
             super()._set_deferrable(value)
 
-    def _set_client_encoding(self, name: str) -> None:
-        self._no_set_async("client_encoding")
-
-    async def set_client_encoding(self, name: str) -> None:
-        """Async version of the `~Connection.client_encoding` setter."""
-        async with self.lock:
-            await self.wait(self._set_client_encoding_gen(name))
-
     def _no_set_async(self, attribute: str) -> None:
         raise AttributeError(
             f"'the {attribute!r} property is read-only on async connections:"
index 97b094cda40d51150427210442ab58319a88e095..07044cb05c88ea18447dfacb512f431a8e6ddc52 100644 (file)
@@ -304,15 +304,6 @@ def test_get_encoding(conn):
     assert conn.client_encoding == encodings.pg2py(enc)
 
 
-def test_set_encoding(conn):
-    newenc = "iso8859-1" if conn.client_encoding != "iso8859-1" else "utf-8"
-    assert conn.client_encoding != newenc
-    conn.client_encoding = newenc
-    assert conn.client_encoding == newenc
-    (enc,) = conn.cursor().execute("show client_encoding").fetchone()
-    assert encodings.pg2py(enc) == newenc
-
-
 @pytest.mark.parametrize(
     "enc, out, codec",
     [
@@ -325,7 +316,7 @@ def test_set_encoding(conn):
     ],
 )
 def test_normalize_encoding(conn, enc, out, codec):
-    conn.client_encoding = enc
+    conn.execute("select set_config('client_encoding', %s, false)", [enc])
     assert conn.pgconn.parameter_status(b"client_encoding").decode() == out
     assert conn.client_encoding == codec
 
@@ -354,11 +345,6 @@ def test_set_encoding_unsupported(conn):
         cur.execute("select 'x'")
 
 
-def test_set_encoding_bad(conn):
-    with pytest.raises(LookupError):
-        conn.client_encoding = "WAT"
-
-
 @pytest.mark.parametrize(
     "args, kwargs, want",
     [
index 7423c1466b4807edc66174102fa85e050bd9df89..06c08de394ba180eca1f2f18cbc4f5da00cc4910 100644 (file)
@@ -317,20 +317,6 @@ async def test_get_encoding(aconn):
     assert aconn.client_encoding == encodings.pg2py(enc)
 
 
-async def test_set_encoding(aconn):
-    newenc = "iso8859-1" if aconn.client_encoding != "iso8859-1" else "utf-8"
-    assert aconn.client_encoding != newenc
-    with pytest.raises(AttributeError):
-        aconn.client_encoding = newenc
-    assert aconn.client_encoding != newenc
-    await aconn.set_client_encoding(newenc)
-    assert aconn.client_encoding == newenc
-    cur = aconn.cursor()
-    await cur.execute("show client_encoding")
-    (enc,) = await cur.fetchone()
-    assert encodings.pg2py(enc) == newenc
-
-
 @pytest.mark.parametrize(
     "enc, out, codec",
     [
@@ -343,7 +329,9 @@ async def test_set_encoding(aconn):
     ],
 )
 async def test_normalize_encoding(aconn, enc, out, codec):
-    await aconn.set_client_encoding(enc)
+    await aconn.execute(
+        "select set_config('client_encoding', %s, false)", [enc]
+    )
     assert aconn.pgconn.parameter_status(b"client_encoding").decode() == out
     assert aconn.client_encoding == codec
 
@@ -372,11 +360,6 @@ async def test_set_encoding_unsupported(aconn):
         await cur.execute("select 'x'")
 
 
-async def test_set_encoding_bad(aconn):
-    with pytest.raises(LookupError):
-        await aconn.set_client_encoding("WAT")
-
-
 @pytest.mark.parametrize(
     "args, kwargs, want",
     [
index 043eb860f32d0c8220adc347c1f82070f0c3983d..3050822066a5626c4c63d9f3ffcfe3f4f1e91b21 100644 (file)
@@ -140,7 +140,7 @@ def test_set_custom_type(conn, hstore):
 def test_copy_out_allchars(conn, format):
     cur = conn.cursor()
     chars = list(map(chr, range(1, 256))) + [eur]
-    conn.client_encoding = "utf8"
+    conn.execute("set client_encoding to utf8")
     rows = []
     query = sql.SQL(
         "copy (select unnest({}::text[])) to stdout (format {})"
@@ -392,7 +392,7 @@ def test_copy_in_allchars(conn):
     cur = conn.cursor()
     ensure_table(cur, sample_tabledef)
 
-    conn.client_encoding = "utf8"
+    conn.execute("set client_encoding to utf8")
     with cur.copy("copy copy_in from stdin (format text)") as copy:
         for i in range(1, 256):
             copy.write_row((i, None, chr(i)))
index 37ab5e1f8f5bc423cbb0aff65908b83efef8fb02..5242f043752392289fe58290e31a913031be2759 100644 (file)
@@ -117,7 +117,7 @@ async def test_set_custom_type(aconn, hstore):
 async def test_copy_out_allchars(aconn, format):
     cur = aconn.cursor()
     chars = list(map(chr, range(1, 256))) + [eur]
-    await aconn.set_client_encoding("utf8")
+    await aconn.execute("set client_encoding to utf8")
     rows = []
     query = sql.SQL(
         "copy (select unnest({}::text[])) to stdout (format {})"
@@ -381,7 +381,7 @@ async def test_copy_in_allchars(aconn):
     cur = aconn.cursor()
     await ensure_table(cur, sample_tabledef)
 
-    await aconn.set_client_encoding("utf8")
+    await aconn.execute("set client_encoding to utf8")
     async with cur.copy("copy copy_in from stdin (format text)") as copy:
         for i in range(1, 256):
             await copy.write_row((i, None, chr(i)))
index 07827732007668ceb477f7029a6c5bb8ef7ac95d..b6abecc463bd992b7d2fba7e96a7e94cff4615bb 100644 (file)
@@ -140,14 +140,14 @@ def test_binary_cursor_text_override(conn):
 
 @pytest.mark.parametrize("encoding", ["utf8", "latin9"])
 def test_query_encode(conn, encoding):
-    conn.client_encoding = encoding
+    conn.execute(f"set client_encoding to {encoding}")
     cur = conn.cursor()
     (res,) = cur.execute("select '\u20ac'").fetchone()
     assert res == "\u20ac"
 
 
 def test_query_badenc(conn):
-    conn.client_encoding = "latin1"
+    conn.execute("set client_encoding to latin1")
     cur = conn.cursor()
     with pytest.raises(UnicodeEncodeError):
         cur.execute("select '\u20ac'")
index 54c2a99c7fa832c784fe8b10455a6e169f02aee3..6e1fa5d865b3e9931ac9dba9a0f103b8b60b2155 100644 (file)
@@ -143,7 +143,7 @@ async def test_binary_cursor_text_override(aconn):
 
 @pytest.mark.parametrize("encoding", ["utf8", "latin9"])
 async def test_query_encode(aconn, encoding):
-    await aconn.set_client_encoding(encoding)
+    await aconn.execute(f"set client_encoding to {encoding}")
     cur = aconn.cursor()
     await cur.execute("select '\u20ac'")
     (res,) = await cur.fetchone()
@@ -151,7 +151,7 @@ async def test_query_encode(aconn, encoding):
 
 
 async def test_query_badenc(aconn):
-    await aconn.set_client_encoding("latin1")
+    await aconn.execute("set client_encoding to latin1")
     cur = aconn.cursor()
     with pytest.raises(UnicodeEncodeError):
         await cur.execute("select '\u20ac'")
index 15e429ec9792b65eddad933e71cdd3c86bb98312..cd92f4d940c4bef6f1b368349652eb878f963d1b 100644 (file)
@@ -74,7 +74,7 @@ def test_diag_encoding(conn, enc):
     msgs = []
     conn.pgconn.exec_(b"set client_min_messages to notice")
     conn.add_notice_handler(lambda diag: msgs.append(diag.message_primary))
-    conn.client_encoding = enc
+    conn.execute(f"set client_encoding to {enc}")
     cur = conn.cursor()
     cur.execute(
         "do $$begin raise notice 'hello %', chr(8364); end$$ language plpgsql"
@@ -84,7 +84,8 @@ def test_diag_encoding(conn, enc):
 
 @pytest.mark.parametrize("enc", ["utf8", "latin9"])
 def test_error_encoding(conn, enc):
-    conn.client_encoding = enc
+    with conn.transaction():
+        conn.execute(f"set client_encoding to {enc}")
     cur = conn.cursor()
     with pytest.raises(e.DatabaseError) as excinfo:
         cur.execute(
index b2c6264c8793f0cd8d74df699c1e9be846dde770..44f0f03901bab0f41d52c5b8bc2b244473ec79dc 100644 (file)
@@ -9,6 +9,7 @@ import pytest
 
 from psycopg import pq, sql, ProgrammingError
 from psycopg.adapt import PyFormat
+from psycopg._encodings import py2pgenc
 
 eur = "\u20ac"
 
@@ -290,7 +291,7 @@ class TestIdentifier:
     )
     def test_as_bytes(self, conn, args, want, enc):
         want = want.encode(enc)
-        conn.client_encoding = enc
+        conn.execute(f"set client_encoding to {py2pgenc(enc).decode()}")
         assert sql.Identifier(*args).as_bytes(conn) == want
 
     def test_join(self):
@@ -328,9 +329,9 @@ class TestLiteral:
             sql.Literal(dt.date(2017, 1, 1)).as_bytes(conn) == b"'2017-01-01'"
         )
 
-        conn.client_encoding = "utf8"
+        conn.execute("set client_encoding to utf8")
         assert sql.Literal(eur).as_bytes(conn) == f"'{eur}'".encode()
-        conn.client_encoding = "latin9"
+        conn.execute("set client_encoding to latin9")
         assert sql.Literal(eur).as_bytes(conn) == f"'{eur}'".encode("latin9")
 
     def test_eq(self):
@@ -410,10 +411,10 @@ class TestSQL:
     def test_as_bytes(self, conn):
         assert sql.SQL("foo").as_bytes(conn) == b"foo"
 
-        conn.client_encoding = "utf8"
+        conn.execute("set client_encoding to utf8")
         assert sql.SQL(eur).as_bytes(conn) == eur.encode()
 
-        conn.client_encoding = "latin9"
+        conn.execute("set client_encoding to latin9")
         assert sql.SQL(eur).as_bytes(conn) == eur.encode("latin9")
 
 
@@ -484,10 +485,10 @@ class TestComposed:
 
         obj = sql.Composed([sql.SQL("foo"), sql.SQL(eur)])
 
-        conn.client_encoding = "utf8"
+        conn.execute("set client_encoding to utf8")
         assert obj.as_bytes(conn) == ("foo" + eur).encode()
 
-        conn.client_encoding = "latin9"
+        conn.execute("set client_encoding to latin9")
         assert obj.as_bytes(conn) == ("foo" + eur).encode("latin9")
 
 
index 21e66d696b500e78576c7715c76c8fff9c146fac..6070ed42c287461b5d81e2ea8a387019d4d5c568 100644 (file)
@@ -91,11 +91,11 @@ def test_load_1char(conn, typename, fmt_out):
 
 
 @pytest.mark.parametrize("fmt_in", PyFormat)
-@pytest.mark.parametrize("encoding", ["utf8", "latin9", "ascii"])
+@pytest.mark.parametrize("encoding", ["utf8", "latin9", "sql_ascii"])
 def test_dump_enc(conn, fmt_in, encoding):
     cur = conn.cursor()
 
-    conn.client_encoding = encoding
+    conn.execute(f"set client_encoding to {encoding}")
     (res,) = cur.execute(f"select ascii(%{fmt_in})", (eur,)).fetchone()
     assert res == ord(eur)
 
@@ -104,7 +104,7 @@ def test_dump_enc(conn, fmt_in, encoding):
 def test_dump_badenc(conn, fmt_in):
     cur = conn.cursor()
 
-    conn.client_encoding = "latin1"
+    conn.execute("set client_encoding to latin1")
     with pytest.raises(UnicodeEncodeError):
         cur.execute(f"select %{fmt_in}::bytea", (eur,))
 
@@ -113,7 +113,7 @@ def test_dump_badenc(conn, fmt_in):
 def test_dump_utf8_badenc(conn, fmt_in):
     cur = conn.cursor()
 
-    conn.client_encoding = "utf-8"
+    conn.execute("set client_encoding to utf8")
     with pytest.raises(UnicodeEncodeError):
         cur.execute(f"select %{fmt_in}", ("\uddf8",))
 
@@ -151,8 +151,8 @@ def test_dump_text_oid(conn, fmt_in):
 def test_load_enc(conn, typename, encoding, fmt_out):
     cur = conn.cursor(binary=fmt_out)
 
-    conn.client_encoding = encoding
-    (res,) = cur.execute(f"select chr(%s)::{typename}", (ord(eur),)).fetchone()
+    conn.execute(f"set client_encoding to {encoding}")
+    (res,) = cur.execute(f"select chr(%s)::{typename}", [ord(eur)]).fetchone()
     assert res == eur
 
     stmt = sql.SQL("copy (select chr({})) to stdout (format {})").format(
@@ -171,9 +171,9 @@ def test_load_badenc(conn, typename, fmt_out):
     conn.autocommit = True
     cur = conn.cursor(binary=fmt_out)
 
-    conn.client_encoding = "latin1"
+    conn.execute("set client_encoding to latin1")
     with pytest.raises(psycopg.DataError):
-        cur.execute(f"select chr(%s)::{typename}", (ord(eur),))
+        cur.execute(f"select chr(%s)::{typename}", [ord(eur)])
 
     stmt = sql.SQL("copy (select chr({})) to stdout (format {})").format(
         ord(eur), sql.SQL(fmt_out.name)
@@ -189,8 +189,8 @@ def test_load_badenc(conn, typename, fmt_out):
 def test_load_ascii(conn, typename, fmt_out):
     cur = conn.cursor(binary=fmt_out)
 
-    conn.client_encoding = "ascii"
-    cur.execute(f"select chr(%s)::{typename}", (ord(eur),))
+    conn.execute("set client_encoding to sql_ascii")
+    cur.execute(f"select chr(%s)::{typename}", [ord(eur)])
     assert cur.fetchone()[0] == eur.encode()
 
     stmt = sql.SQL("copy (select chr({})) to stdout (format {})").format(
@@ -217,7 +217,7 @@ def test_text_array(conn, typename, fmt_in, fmt_out):
 @pytest.mark.parametrize("fmt_in", PyFormat)
 @pytest.mark.parametrize("fmt_out", pq.Format)
 def test_text_array_ascii(conn, fmt_in, fmt_out):
-    conn.client_encoding = "ascii"
+    conn.execute("set client_encoding to sql_ascii")
     cur = conn.cursor(binary=fmt_out)
     a = list(map(chr, range(1, 256))) + [eur]
     exp = [s.encode() for s in a]