Upgrading asyncpg 0.29 to 0.30
Breaking0.29.0 → 0.30.0Security1Platform2New7Changed4Fixed6
BreakingUpgrade verdict
2 platform requirement changes and a security fix.
In plain terms
- 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.
Must act 3 items need code or config changes
What you must change
Security1
Replaces obsolete, unsafe Py_TRASHCAN_SAFE_BEGIN/END.
Py_TRASHCAN_SAFE_BEGINPy_TRASHCAN_SAFE_ENDPlatform2
Adds support for Python 3.13 and PostgreSQL 17.
Requires async_timeout for Python versions below 3.11.
async_timeoutAPI changes
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