From: Daniele Varrazzo Date: Thu, 9 May 2024 01:27:29 +0000 (+0200) Subject: feat: add Column.type_display X-Git-Tag: 3.2.0~29^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1226430f7dbb10ab1961dd22e7221f6eec660dd1;p=thirdparty%2Fpsycopg.git feat: add Column.type_display --- diff --git a/docs/api/objects.rst b/docs/api/objects.rst index 3b285daf7..33b080835 100644 --- a/docs/api/objects.rst +++ b/docs/api/objects.rst @@ -176,6 +176,10 @@ The description `Column` object .. autoattribute:: name .. autoattribute:: type_code + .. autoattribute:: type_display + + .. versionadded:: 3.2 + .. autoattribute:: display_size .. autoattribute:: internal_size .. autoattribute:: precision diff --git a/psycopg/psycopg/_column.py b/psycopg/psycopg/_column.py index 8be4e44c3..7c879a60f 100644 --- a/psycopg/psycopg/_column.py +++ b/psycopg/psycopg/_column.py @@ -40,26 +40,24 @@ class Column(Sequence[Any]): def __repr__(self) -> str: return ( f"" + f" type: {self.type_display} (oid: {self.type_code})>" ) def __len__(self) -> int: return 7 - def _type_display(self) -> str: + @property + def type_display(self) -> str: + """A pretty representation of the column type. + + It is composed by the type name, followed by eventual modifiers and + brackets to signify arrays, e.g. :sql:`text`, :sql:`varchar(42)`, + :sql:`date[]`. + """ if not self._type: return str(self.type_code) - parts = [] - parts.append(self._type.name) - mod = self._type.get_modifier(self._fmod) - if mod: - parts.append(f"({','.join(map(str, mod))})") - - if self.type_code == self._type.array_oid: - parts.append("[]") - - return "".join(parts) + return self._type.get_type_display(oid=self.type_code, fmod=self._fmod) def __getitem__(self, index: Any) -> Any: if isinstance(index, slice): @@ -79,7 +77,7 @@ class Column(Sequence[Any]): @property def display_size(self) -> Optional[int]: - """The field size, for :sql:`varchar(n)`, None otherwise.""" + """The field size, for string types such as :sql:`varchar(n)`.""" return self._type.get_display_size(self._fmod) if self._type else None @property diff --git a/psycopg/psycopg/_typeinfo.py b/psycopg/psycopg/_typeinfo.py index f380cb035..27a41a733 100644 --- a/psycopg/psycopg/_typeinfo.py +++ b/psycopg/psycopg/_typeinfo.py @@ -194,8 +194,17 @@ ORDER BY t.oid """Method called by the `!registry` when the object is added there.""" pass - def get_modifier(self, fmod: int) -> tuple[int, ...] | None: - return self.typemod.get_modifier(fmod) + def get_type_display(self, oid: int | None = None, fmod: int | None = None) -> str: + parts = [] + parts.append(self.name) + mod = self.typemod.get_modifier(fmod) if fmod is not None else () + if mod: + parts.append(f"({','.join(map(str, mod))})") + + if oid == self.array_oid: + parts.append("[]") + + return "".join(parts) def get_display_size(self, fmod: int) -> int | None: return self.typemod.get_display_size(fmod) diff --git a/tests/test_column.py b/tests/test_column.py index 0440d9756..d5ae58fea 100644 --- a/tests/test_column.py +++ b/tests/test_column.py @@ -66,21 +66,23 @@ def test_description_slice(conn): "type, precision, scale, dsize, isize", [ ("text", None, None, None, None), + ("text[]", None, None, None, None), ("varchar", None, None, None, None), ("varchar(1)", None, None, 1, None), + ("varchar(1)[]", None, None, 1, None), ("varchar(42)", None, None, 42, None), ("bpchar(42)", None, None, 42, None), ("varchar(10485760)", None, None, 10485760, None), ("int4", None, None, None, 4), ("numeric", None, None, None, None), ("numeric(10,0)", 10, 0, None, None), - ("numeric(10,3)", 10, 3, None, None), + ("numeric(10,3)[]", 10, 3, None, None), ("numeric(10,-1)", 10, -1, None, None), ("numeric(1,-1000)", 1, -1000, None, None), ("numeric(1,1000)", 1, 1000, None, None), ("numeric(1000,1000)", 1000, 1000, None, None), ("time", None, None, None, 8), - ("time", None, None, None, 8), + ("time[]", None, None, None, None), ("timetz", None, None, None, 12), ("timestamp", None, None, None, 8), ("timestamptz", None, None, None, 8), @@ -98,7 +100,8 @@ def test_details(conn, type, precision, scale, dsize, isize): cur = conn.cursor() cur.execute(f"select null::{type}") col = cur.description[0] - assert type in (repr(col)) + assert type == col.type_display + assert f" {type} " in (repr(col)) assert col.precision == precision assert col.scale == scale assert col.display_size == dsize