MagicStack / MagicStack/asyncpg

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

Đang mở
#1,340 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
Python
Star
8.1k
Fork
468
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

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?

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách chạy trình tái hiện enum.StrEnum của issue, sau đó kiểm tra coreproto.pyx tại CoreProtocol._connect và đường dẫn WriteBuffer.write_str được hiển thị trong traceback. Truy tìm lý do các tham số kết nối được xử lý khác nhau, đồng thời bổ sung phạm vi kiểm thử hồi quy cho thấy các giá trị tương thích với str được báo cáo được xử lý nhất quán mà không xảy ra TypeError.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
postgresql, python
Lĩnh vực
databases
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
56/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.