apache / apache/iotdb

[Bug] Python Client IoTDBContainer and Example is not well behaved and IoTDBContainer will fail on Windows

未关闭
#9,734 9 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Java
星标
6.4k
派生
1.2k
平均合并
1 天 23 小时
30 天内合并 PR
115

描述

### Search before asking

- [X] I searched in the [issues](https://github.com/apache/iotdb/issues) and found nothing similar.

### Version

Windows 11 22H2
IoTDB 1.1.0

### Describe the bug and provide the minimal reproduce step

In class `IoTDBContainer`:
```python
@wait_container_is_ready()
def _connect(self):
session = Session(
self.get_container_host_ip(), self.get_exposed_port(6667), "root", "root"
)
session.open(False)
session.close()
```
`get_exposed_port` return a `str`.

[Exampe](https://iotdb.apache.org/UserGuide/Master/API/Programming-Python-Native-API.html#how-to-use-example) use `str` port as well.

However, `TSocket` in `thrift` actually expect an `int` for `port`:
```python
class TSocket(TSocketBase):
"""Socket implementation of TTransport base."""

def __init__(self, host='localhost', port=9090, unix_socket=None,
socket_family=socket.AF_UNSPEC,
socket_keepalive=False):
"""Initialize a TSocket

@param host(str) The host to connect to.
@param port(int) The (TCP) port to connect to.
@param unix_socket(str) The filename of a unix socket to connect to.
(host and port will be ignored.)
@param socket_family(int) The socket family to use with this socket.
@param socket_keepalive(bool) enable TCP keepalive, default off.
"""
```
```python
@property
def _address(self):
return self._unix_socket if self._unix_socket else '%s:%d' % (self.host, self.port)
def open(self):
if self.handle:
raise TTransportException(type=TTransportException.ALREADY_OPEN, message="already open")
try:
addrs = self._resolveAddr()
except socket.gaierror as gai:
msg = 'failed to resolve sockaddr for ' + str(self._address)
...
```
Note the `%d` here. if the `self.port` is a `str`, when resolve address fail, an unrelated error will be raised:
```
socket.gaierror: [Errno 11001] getaddrinfo failed

During handling of the above exception, another exception occurred:
... LONG stack trace
TypeError: %d format: a real number is required, not str
```
I omit stack trace here, but in fact the terminal filled with stack trace and the plausible TypeError distracted me from discover the real bug: `self.get_container_host_ip()` return `'localnpipe'`.

How to reproduce:
(on Windows)
```python
from iotdb.IoTDBContainer import IoTDBContainer
IoTDBContainer()
```

### What did you expect to see?

1. no `TypeError: %d format: a real number is required, not str` raised.
2. host should be `localhost` instead of `localnpipe`
this seems an upstream bug.
there is a workaround: set environment variable `TC_HOST='localhost'`

### What did you see instead?

`TypeError: %d format: a real number is required, not str` is raised.
IoTDBContainer use `localnpipe` instead of `localhost`.

### Anything else?

_No response_

### Are you willing to submit a PR?

- [ ] I'm willing to submit a PR!

贡献指南

打开贡献指南

调研方向

从 IoTDBContainer._connect 和 Python 原生 API 示例开始,然后在 Windows 上运行提供的 IoTDBContainer() 复现。验证传递给 Session 的端口是数值型的,主机不是 localnpipe,并且无关的 TypeError 不再掩盖连接失败。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
databases
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。