【问题标题】:Why do I get a TypeError when passing a bytes string to magic.from_buffer()?为什么在将字节字符串传递给 magic.from_buffer() 时会出现 TypeError?
【发布时间】:2019-05-01 12:17:27
【问题描述】:

我正在尝试使用 python-magic 的 from_buffer 从 url 获取图像的文件类型,它在实践中运行良好,但在我尝试运行单元测试时失败。

这是我的功能:

def get_uri_from_url(url):
    if url != '':
        response = requests.get(url)
        data_type = magic.from_buffer(response.content, mime=True)
        image_bytes = str(base64.b64encode(response.content).decode('utf-8'))
        return f'data:{data_type};base64,{image_bytes}'
    return url

这是目前为止的测试:

    def test_get_uri_from_url(self):
        test_bytes = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&' \
                     b'\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd' \
                     b'\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82'

        class Requests:
            content = test_bytes

            def get(self, url):
                return self

        with patch('path_to_my_function.requests', return_value=Requests):
            self.assertEqual(
                get_uri_from_url('any_url'),
                f'data:image/png;base64,{test_bytes}'
            )

此测试需要很长时间才能运行,最后出现以下回溯错误:

Traceback (most recent call last):
  File "/<path>/test_file.py", line 90, in test_get_uri_from_url
    get_uri_from_url('any_url'),
  File "/<path>/file.py", line 165, in get_uri_from_url
    data_type = magic.from_buffer(response.content, mime=True)
  File "/<path_to_python>/python3.6/site-packages/magic.py", line 148, in from_buffer
    return m.from_buffer(buffer)
  File "/<path_to_python>/python3.6/site-packages/magic.py", line 80, in from_buffer
    return maybe_decode(magic_buffer(self.cookie, buf))
  File "/<path_to_python>/python3.6/site-packages/magic.py", line 255, in magic_buffer
    return _magic_buffer(cookie, buf, len(buf))
ctypes.ArgumentError: argument 2: <class 'TypeError'>: wrong type

我看不出我做错了什么,当我在终端中运行它时它工作正常,我一定错过了一些东西。

In [17]: response = requests.get('https://upload.wikimedia.org/wikipedia/commons/3/31/Red-dot-5px.png')                                                                           

In [18]: response.content                                                                                                                                                         
Out[18]: b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82'

In [19]: magic.from_buffer(response.content, mime=True)                                                                                                                           
Out[19]: 'image/png'

【问题讨论】:

  • 你能包括完整的回溯而不是最后一部分吗?
  • 更新了完整的回溯

标签: python-3.x python-requests python-magic


【解决方案1】:

我已经设法通过使用以下方法使其工作:

    def test_get_uri_from_url(self):

        class Response:
            content = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&' \
                      b'\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X' \
                      b'\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82'

        with patch('touchsurgery.apps.apiv3.helpers.requests.get', return_value=Response):
            self.assertEqual(
                get_uri_from_url('any_url'),
                'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHx'
                'gljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
            )

我相信问题出在我的嘲笑和修补中。由于我修补了 'requests' 的返回值,但 requests 本身从未显式调用 (),因此传递给 magic.from_buffer 的对象只是一个 magicmock 对象,所以它失败了。

这个函数现在可以工作了,因为 get() 在函数中被显式调用了。如果其他人可以对此有所了解或提供更详细的解释,将不胜感激。

【讨论】:

  • 来自from_buffer documentation接受二进制字符串并返回检测到的文件类型。 [...]。这就是您在此答案中用作参数的内容。这是一个较晚的响应,但可能会对其他人有所帮助。
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 2019-04-11
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
相关资源
最近更新 更多