Skip to content

Upgrading asyncpg 0.29 to 0.30

Breaking0.29.0 → 0.30.0Security1Platform2New7Changed4Fixed6

BreakingUpgrade verdict

2 platform requirement changes and a security fix.

  • The library now works with the newest Python and PostgreSQL versions.
  • On Python older than 3.11, the async_timeout package is now required.
  • Replaces unsafe C API macros with safer equivalents.
3 items need code or config changes
Security1
Replaces obsolete, unsafe Py_TRASHCAN_SAFE_BEGIN/END.
Py_TRASHCAN_SAFE_BEGINPy_TRASHCAN_SAFE_END
Platform2
Adds support for Python 3.13 and PostgreSQL 17.
Requires async_timeout for Python versions below 3.11.
async_timeout

Generated by DepDelta from published Python source. Not mixed with prose notes.

  • added: export exceptions
  • changed: async function wait_closed(stream) → async function wait_closed(stream: asyncio.StreamWriter) -> None
  • changed: function get_pg_home_directory() -> typing.Optional[pathlib.Path] → function get_pg_home_directory() -> pathlib.Path | None
  • changed: variable CSIDL_APPDATA → variable CSIDL_APPDATA: typing.Final
  • changed: variable SYSTEM → variable SYSTEM: typing.Final
  • added: class StrEnum(str, enum.Enum)
  • added: function markcoroutinefunction(c)
  • added: class SSLNegotiation(compat.StrEnum)
  • added: field SSLNegotiation.direct
  • added: field SSLNegotiation.postgres
  • changed: async function connect(dsn=…, *, host=…, port=…, user=…, password=…, passfile=…, database=…, loop=…, timeout=…, statement_cache_size=…, max_cached_statement_lifetime=…, max_cacheable_statement_size=…, command_timeout=…, ssl=…, direct_tls=…, connection_class=…, record_class=…, server_settings=…, target_session_attrs=…) → async function connect(dsn=…, *, host=…, port=…, user=…, password=…, passfile=…, database=…, loop=…, timeout=…, statement_cache_size=…, max_cached_statement_lifetime=…, max_cacheable_statement_size=…, command_timeout=…, ssl=…, direct_tls=…, connection_class=…, record_class=…, server_settings=…, target_session_attrs=…, krbsrvname=…, gsslib=…)
  • added: async method Connection.fetchmany(query, args, *, timeout: float=…, record_class=…)
  • added: method Connection.get_reset_query()
  • added: class FileNameTooLongError(PostgresSystemError)
  • added: class InvalidArgumentForXqueryError(_base.PostgresError)
  • added: class TransactionTimeoutError(InvalidTransactionStateError)
  • added: field FileNameTooLongError.sqlstate
  • added: field InvalidArgumentForXqueryError.sqlstate
  • added: field TransactionTimeoutError.sqlstate
  • changed: function is_composite_type(typeinfo) -> bool → function is_composite_type(typeinfo: protocol.Record) -> bool
  • changed: function is_domain_type(typeinfo) -> bool → function is_domain_type(typeinfo: protocol.Record) -> bool
  • changed: function is_scalar_type(typeinfo) -> bool → function is_scalar_type(typeinfo: protocol.Record) -> bool
  • changed: variable TYPE_BY_NAME → variable TYPE_BY_NAME: typing.Final
  • added: class BufferError(Exception)
  • added: class CodecContext
  • added: class ReadBuffer
  • added: class UUID(uuid.UUID)
  • added: class WriteBuffer
  • added: constructor UUID(inp: typing.AnyStr) -> None
  • added: method CodecContext.get_text_codec() -> codecs.CodecInfo
  • changed: constructor Pool(*connect_args, min_size, max_size, max_queries, max_inactive_connection_lifetime, setup, init, loop, connection_class, record_class, **connect_kwargs) → constructor Pool(*connect_args, min_size, max_size, max_queries, max_inactive_connection_lifetime, connect=…, setup=…, init=…, reset=…, loop, connection_class, record_class, **connect_kwargs)
  • changed: function create_pool(dsn=…, *, min_size=…, max_size=…, max_queries=…, max_inactive_connection_lifetime=…, setup=…, init=…, loop=…, connection_class=…, record_class=…, **connect_kwargs) → function create_pool(dsn=…, *, min_size=…, max_size=…, max_queries=…, max_inactive_connection_lifetime=…, connect=…, setup=…, init=…, reset=…, loop=…, connection_class=…, record_class=…, **connect_kwargs)
  • added: async method Pool.fetchmany(query, args, *, timeout=…, record_class=…)
  • added: async method PreparedStatement.fetchmany(args, *, timeout=…)
  • added: async method BaseProtocol.bind(state: PreparedStatementState[_OtherRecord], args: Sequence[object], portal_name: str, timeout: _TimeoutType) -> Any
  • added: async method BaseProtocol.bind_execute(state: PreparedStatementState[_OtherRecord], args: Sequence[object], portal_name: str, limit: int, return_extra: Literal[False], timeout: _TimeoutType) -> list[_OtherRecord] | (state: PreparedStatementState[_OtherRecord], args: Sequence[object], portal_name: str, limit: int, return_extra: Literal[True], timeout: _TimeoutType) -> tuple[list[_OtherRecord], byt…
  • added: async method BaseProtocol.bind_execute_many(state: PreparedStatementState[_OtherRecord], args: Iterable[Sequence[object]], portal_name: str, timeout: _TimeoutType) -> None
  • added: async method BaseProtocol.close(timeout: _TimeoutType) -> None
  • added: async method BaseProtocol.close_portal(portal_name: str, timeout: _TimeoutType) -> None
  • added: async method BaseProtocol.close_statement(state: PreparedStatementState[_OtherRecord], timeout: _TimeoutType) -> Any
  • added: async method BaseProtocol.copy_in(*args: object, **kwargs: object) -> str
  • added: async method BaseProtocol.copy_out(*args: object, **kwargs: object) -> str
  • added: async method BaseProtocol.execute(*args: object, **kwargs: object) -> Any
  • added: async method BaseProtocol.prepare(stmt_name: str, query: str, timeout: float | None=…, *, state: _PreparedStatementState, ignore_custom_codec: bool=…, record_class: None) -> _PreparedStatementState | (stmt_name: str, query: str, timeout: float | None=…, *, state: None=…, ignore_custom_codec: bool=…, record_class: type[_OtherRecord]) -> PreparedStatementState[_OtherRecord]
  • added: async method BaseProtocol.query(*args: object, **kwargs: object) -> str
  • added: class BaseProtocol(CoreProtocol, Generic[_Record])
  • added: class Codec
  • added: class ConnectionSettings(asyncpg.pgproto.pgproto.CodecContext)
  • added: class CoreProtocol
  • added: class DataCodecConfig
  • added: class PreparedStatementState(Generic[_Record])
  • added: class Protocol(BaseProtocol[_Record], asyncio.protocols.Protocol)
  • added: class Record
  • added: class SCRAMAuthentication
  • added: class Timer
  • added: constructor BaseProtocol(addr: object, connected_fut: object, con_params: _ConnectionParameters, record_class: type[_Record], loop: object) -> None
  • added: constructor ConnectionSettings(conn_key: object) -> None
  • added: constructor CoreProtocol(addr: object, con_params: _ConnectionParameters) -> None
  • added: constructor DataCodecConfig() -> None
  • added: constructor PreparedStatementState(name: str, query: str, protocol: BaseProtocol[Any], record_class: type[_Record], ignore_custom_codec: bool) -> None
  • added: constructor Timer(budget: float | None) -> None
  • added: field BaseProtocol.is_ssl: bool
  • added: field BaseProtocol.queries_count: Any
  • added: field CoreProtocol.backend_pid: Any
  • added: field CoreProtocol.backend_secret: Any
  • added: field PreparedStatementState.closed: bool
  • added: field PreparedStatementState.ignore_custom_codec: bool
  • added: field PreparedStatementState.name: str
  • added: field PreparedStatementState.prepared: bool
  • added: field PreparedStatementState.query: str
  • added: field PreparedStatementState.record_class: type[_Record]
  • added: field PreparedStatementState.refs: int
  • added: field SCRAMAuthentication.AUTHENTICATION_METHODS: ClassVar[list[str]]
  • added: field SCRAMAuthentication.DEFAULT_CLIENT_NONCE_BYTES: ClassVar[int]
  • added: field SCRAMAuthentication.DIGEST
  • added: field SCRAMAuthentication.REQUIREMENTS_CLIENT_FINAL_MESSAGE: ClassVar[list[str]]
  • added: field SCRAMAuthentication.REQUIREMENTS_CLIENT_PROOF: ClassVar[list[str]]
  • added: field SCRAMAuthentication.SASLPREP_PROHIBITED: ClassVar[tuple[Callable[[str], bool], ...]]
  • added: field SCRAMAuthentication.authentication_method: bytes
  • added: field SCRAMAuthentication.authorization_message: bytes | None
  • added: field SCRAMAuthentication.client_channel_binding: bytes
  • added: field SCRAMAuthentication.client_first_message_bare: bytes | None
  • added: field SCRAMAuthentication.client_nonce: bytes | None
  • added: field SCRAMAuthentication.client_proof: bytes | None
  • added: field SCRAMAuthentication.password_iterations: int
  • added: field SCRAMAuthentication.password_salt: bytes | None
  • added: field SCRAMAuthentication.server_first_message: bytes | None
  • added: field SCRAMAuthentication.server_key: hmac.HMAC | None
  • added: field SCRAMAuthentication.server_nonce: bytes | None
  • added: method BaseProtocol.abort() -> None
  • added: method BaseProtocol.connection_lost(exc: Exception | None) -> None
  • added: method BaseProtocol.connection_made(transport: object) -> None
  • added: method BaseProtocol.data_received(data: object) -> None
  • added: method BaseProtocol.get_record_class() -> type[_Record]
  • added: method BaseProtocol.get_server_pid(*args: object, **kwargs: object) -> int
  • added: method BaseProtocol.get_settings(*args: object, **kwargs: object) -> ConnectionSettings
  • added: method BaseProtocol.is_closed(*args: object, **kwargs: object) -> Any
  • added: method BaseProtocol.is_connected(*args: object, **kwargs: object) -> Any
  • added: method BaseProtocol.pause_writing(*args: object, **kwargs: object) -> Any
  • added: method BaseProtocol.resume_writing(*args: object, **kwargs: object) -> Any
  • added: method BaseProtocol.set_connection(connection: object) -> None
  • added: method ConnectionSettings.add_python_codec(typeoid: int, typename: str, typeschema: str, typeinfos: Iterable[object], typekind: str, encoder: Callable[[Any], Any], decoder: Callable[[Any], Any], format: object) -> Any
  • added: method ConnectionSettings.clear_type_cache() -> None
  • added: method ConnectionSettings.get_data_codec(oid: int, format: object=…, ignore_custom_codec: bool=…) -> Any
  • added: method ConnectionSettings.get_text_codec() -> CodecInfo
  • added: method ConnectionSettings.register_data_types(types: Iterable[object]) -> None
  • added: method ConnectionSettings.remove_python_codec(typeoid: int, typename: str, typeschema: str) -> None
  • added: method ConnectionSettings.set_builtin_type_codec(typeoid: int, typename: str, typeschema: str, typekind: str, alias_to: str, format: object=…) -> Any
  • added: method CoreProtocol.is_in_transaction() -> bool
  • added: method DataCodecConfig.add_python_codec(typeoid: int, typename: str, typeschema: str, typekind: str, typeinfos: Iterable[object], encoder: Callable[[ConnectionSettings, WriteBuffer, object], object], decoder: Callable[..., object], format: object, xformat: object) -> Any
  • added: method DataCodecConfig.add_types(types: Iterable[object]) -> Any
  • added: method DataCodecConfig.clear_type_cache() -> None
  • added: method DataCodecConfig.declare_fallback_codec(oid: int, name: str, schema: str) -> Codec
  • added: method DataCodecConfig.remove_python_codec(typeoid: int, typename: str, typeschema: str) -> Any
  • added: method DataCodecConfig.set_builtin_type_codec(typeoid: int, typename: str, typeschema: str, typekind: str, alias_to: str, format: object=…) -> Any
  • added: method PreparedStatementState.attach() -> None
  • added: method PreparedStatementState.detach() -> None
  • added: method PreparedStatementState.mark_closed() -> None
  • added: method PreparedStatementState.mark_unprepared() -> None
  • added: method Record.get(key: str) -> Any | None | (key: str, default: _T) -> Any | _T
  • added: method Record.items() -> Iterator[tuple[str, Any]]
  • added: method Record.keys() -> Iterator[str]
  • added: method Record.values() -> Iterator[Any]
  • added: method Timer.get_remaining_budget() -> float
  • added: method Timer.has_budget_greater_than(amount: float) -> bool
  • added: variable BUILTIN_TYPE_NAME_MAP: Final[dict[str, int]]
  • added: variable BUILTIN_TYPE_OID_MAP: Final[dict[int, str]]
  • added: variable NO_TIMEOUT: Final[_NoTimeoutType]
  • added: variable hashlib_md5
  • changed: function split_server_version_string(version_string) → function split_server_version_string(version_string: str) -> ServerVersion
  • changed: variable version_regex → variable version_regex: typing.Final
  • removed: property Range.isempty
  • removed: property Range.lower
  • removed: property Range.lower_inc
  • removed: property Range.lower_inf
  • removed: property Range.upper
  • removed: property Range.upper_inc
  • removed: property Range.upper_inf
  • removed: variable Attribute
  • removed: variable ServerVersion
  • removed: variable Type
  • changed: class Range → class Range(typing.Generic[_RV])
  • changed: constructor Range(lower=…, upper=…, *, lower_inc=…, upper_inc=…, empty=…) → constructor Range(lower: _RV | None=…, upper: _RV | None=…, *, lower_inc: bool=…, upper_inc: bool=…, empty: bool=…) -> None
  • changed: method Range.issubset(other) → method Range.issubset(other: Self) -> bool
  • changed: method Range.issuperset(other) → method Range.issuperset(other: Self) -> bool
  • added: class Attribute(typing.NamedTuple)
  • added: class ServerVersion(typing.NamedTuple)
  • added: class Type(typing.NamedTuple)
  • added: field Attribute.name: str
  • added: field Attribute.type: Type
  • added: field ServerVersion.major: int
  • added: field ServerVersion.micro: int
  • added: field ServerVersion.minor: int
  • added: field ServerVersion.releaselevel: str
  • added: field ServerVersion.serial: int
  • added: field Type.kind: str
  • added: field Type.name: str
  • added: field Type.oid: int
  • added: field Type.schema: str
  • added: property Range.isempty -> bool
  • added: property Range.lower -> _RV | None
  • added: property Range.lower_inc -> bool
  • added: property Range.lower_inf -> bool
  • added: property Range.upper -> _RV | None
  • added: property Range.upper_inc -> bool
  • added: property Range.upper_inf -> bool