Closed virusdefender closed 10 years ago
Hi, @virusdefender
请测试下最新 master 的代码,https://github.com/upyun/python-sdk/commit/057266dbff6f1ce91389cd97139b5b78ea1c958b 这个 commit 已经修复该问题。
最新的commit测试可以使用。但是我修改的结果是
if hasattr(value, 'fileno'):
length = value.size
就改了这一个地方。你们的测试用例在我的电脑上编码错误,环境ubuntu 14.04,就没有测试。但是可以使用。
@virusdefender 你提到的编码错误,有更具体的错误信息提供吗?
我们的测试用例在 Mac 和 ubuntu/14.04 上都测试过的,系统编码都是 en_US.UTF-8,均未出现错误。
PS. 既然最新的代码已经修复了这个问题,这个 issues 暂时就先关闭了,后续有问题请再反馈 :-)
Hi, @virusdefender
我又稍微完善了下对于这类 File Like Object 的支持 https://github.com/upyun/python-sdk/commit/358d48742ae5dc82a509535f7233806e10bddc9b ,兼容了自定义的 UploadObject。
有空请麻烦再测试下最新的修改,若没问题的话,稍后我就 Release 一个新的版本出来:v2.2.4。
另外,你前面提到:
length = value.size
类似这样的语句也能获取到 Django File Object 的大小是因为 Django 封装的文件对象提供了 size
属性,具体可参见 Django UploadObject
类的实现:
https://github.com/django/django/blob/master/django/core/files/uploadedfile.py#L30
而我们的修复方式更加通用点,在 Django InMemoryUploadedFile
的情况下,其虽然拥有 fileno
属性,但若尝试去获取大小的话就会抛 IOError
异常,因为此时传递给 InMemoryUploadedFile
的是一个 BytesIO
对象:
https://github.com/django/django/blob/master/django/core/files/utils.py#L12
https://github.com/django/django/blob/master/django/core/files/uploadhandler.py#L175
因此当 fileno
获取 size 失败的时候,我们就尝试用 getvalue()
方法去获取 BytesIO
对象的 size。这样就既能兼容 Django 中 InMemoryUploadedFile
和 TemporaryUploadedFile
两种情况的 UploadObject
,也能兼容原始的 BytesIO
或 StringIO
类构造的 File Like Object 了。
另外,特别地,Django File Object 实际上已经提供了一个 __len__
的内置类属性:
https://github.com/django/django/blob/master/django/core/files/base.py#L36
因此,这里我们其实简单地将 hasattr(value, '__len__')
的判断提前也能解决这个问题 :-)
@virusdefender
v2.2.4 已经发布:# pip install -U upyun
十分感谢,今天白天有点事情。测试的问题,我刚才又跑了一遍,认真的看了一下,虽然最后面是经典的编码错误的提示,但是向前看是缺少了依赖的openssl的库的问题,有空再测试。再次表示感谢,国庆快乐~
最近在使用django + 又拍云,但是直接网页上传文件的时候出现这个问题。先读取本地文件再上传就没问题。 代码大致是这样的,request.FILES["file"]是网页form上传来的。
Upload就是自己写的一个类,简单的集成了sdk中的上传文件的功能。但是sdk中有一句fileno的语句会导致错误,和我上面注释掉的那句基本一样。
截图在这里 http://photo.weibo.com/3560808645/albums/detail/album_id/3616760132684350#!/mode/1/page/1