MagicStack / MagicStack/asyncpg

TypeError in asyncpg.connect() for specific parameters when values are not str enough

Ouverte
#1,340 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
Python
Étoiles
8.1k
Forks
468
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

When calling `asyncpg.connect()` with values that are simple `str`, things work as I expect them to work. Not all of the arguments are treated the same, though. When values that go through the `WriteBuffer` onto the wire are `str`, but maybe not only a `str`, `WriteBuffer.write_str` raises a `TypeError`. My concrete use case where I ran into this is connection parameters that were read from a TOML file using `tomlkit`, which produces `tomlkit.items.String` values, that *are* instances of `str`, but are not accepted.

The following example script demonstrates the issue using `enum.StrEnum`, which causes the same unexpected error:

```python
import asyncio
import enum

import asyncpg

class Connect(enum.StrEnum):
HOST = 'localhost'
USER = 'postgresql'

async def connect_host():
return await asyncpg.connect(host=Connect.HOST)

async def connect_host_user():
return await asyncpg.connect(host=Connect.HOST, user=Connect.USER)

if __name__ == '__main__':
print('HOST is str:', isinstance(Connect.HOST, str))
print('USER is str:', isinstance(Connect.USER, str))

try:
asyncio.run(connect_host())
except asyncpg.PostgresError as e:
print('not connected:', repr(e))

try:
asyncio.run(connect_host_user())
except asyncpg.PostgresError as e:
# this except block is never hit, connection setup encounters a TypeError
print('not connected:', repr(e))
```

The output of this script is as follows (Python 3.14.6 on Linux amd64, asyncpg 0.31.0):

```traceback
HOST is str: True
USER is str: True
not connected: InvalidAuthorizationSpecificationError('role "user" does not exist')
Traceback (most recent call last):
File "asyncpg/protocol/protocol.pyx", line 978, in asyncpg.protocol.protocol.BaseProtocol.connection_made
File "asyncpg/protocol/coreproto.pyx", line 947, in asyncpg.protocol.protocol.CoreProtocol._connect
TypeError: Expected str, got Connect

During handling of the above exception, another exception occurred:

[...]

File "asyncpg/protocol/protocol.pyx", line 983, in asyncpg.protocol.protocol.BaseProtocol.connection_made
AttributeError: 'Protocol' object has no attribute '_on_error'
```

Using a enum here is a bit odd of course, the point is that the values being passed to `asyncpg.connect()` are `str` and treated differently depending on where that argument ends up in the connection setup.

My expectation is that values that are instances of `str` are used as such and work as intended. The full array connection parameters in my code are read through `tomlkit`, which produces values that very much quack and walk like a `str` 🦆.

Are these values being rejected for good reason, or should these just be accepted?

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter le reproducteur de l’issue pour enum.StrEnum, puis inspectez coreproto.pyx au niveau de CoreProtocol._connect ainsi que le chemin WriteBuffer.write_str indiqué dans la trace d’erreur. Suivez la raison pour laquelle les paramètres de connexion sont traités différemment et ajoutez une couverture de régression montrant que les valeurs compatibles avec str signalées sont traitées de manière cohérente sans TypeError.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
postgresql, python
Domaine
databases
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
56/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.