Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'str' does not support the buffer interface #216

Closed
jonfen opened this issue Nov 14, 2018 · 10 comments
Closed

'str' does not support the buffer interface #216

jonfen opened this issue Nov 14, 2018 · 10 comments
Assignees
Labels

Comments

@jonfen
Copy link

@jonfen jonfen commented Nov 14, 2018

The uploads portion of the following example code fails with the error above for both create() and save(), removing the uploads assignment makes the call successful, but not valuable:

https://python-redmine.com/resources/issue.html?highlight=stringio

from io import StringIO
issue = redmine.issue.create(
     project_id='vacation',
     subject='Vacation',
     tracker_id=8,
     description='foo',
     status_id=3,
     priority_id=7,
     assigned_to_id=123,
     watcher_user_ids=[123],
     parent_issue_id=345,
     start_date=datetime.date(2014, 1, 1),
     due_date=datetime.date(2014, 2, 1),
     estimated_hours=4,
     done_ratio=40,
     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
     uploads=[{'path': '/absolute/path/to/file'}, {'path': StringIO('I am content of file 2')}]
)

produces error: 'str' does not support the buffer interface

Redmine Server: 3.2.0
Python: 3.3
OS: Windows 10 Pro

@maxtepkeev maxtepkeev self-assigned this Nov 24, 2018
@maxtepkeev maxtepkeev added the bug label Nov 24, 2018
@jonfen
Copy link
Author

@jonfen jonfen commented Jan 2, 2019

file_contents = 'I am content of file 2'
uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(file_contents.encode('utf-8'))}]

After upgrading to Python 3.7 StringIO supports ByteIO, but it did not in 3.3. The code above would be more accurate.

@jonfen jonfen closed this Jan 2, 2019
maxtepkeev added a commit that referenced this issue Jan 2, 2019
@maxtepkeev
Copy link
Owner

@maxtepkeev maxtepkeev commented Jan 2, 2019

@jonfen You're absolutely right that one should use BytesIO under Python 3. I was also investigating this issue for the last two days, since I finally found some time to do this and here are my findings:

  • This error comes from the standard library httplib (which is mocked in tests, that's why we didn't find it earlier) when it tries to send the data over the socket as it expects to send bytes, but receives a unicode object, httplib is used internally by urllib3, which is used internally by requests which is what python-redmine uses to do all the network calls
  • Using StringIO or any other file-like object under Python 2 works most of the time unless you specifically say that you want to put a unicode string inside (using a u'' prefix, unicode function or whatever)
  • Under Python 3 things get more complicated since all strings are unicode by default
  • Starting from Python 3.6 things will start working magically (exactly what you've experienced after upgrading to 3.7), because they're trying to do the conversion under the hood, but it works only if you have only ascii chars in your strings, add something else, say a char from Russian language and everything will fail again

So basically what we need to do is to convert our unicode strings to bytes before feeding a file-like object to Python-Redmine which is exactly what I'm doing now in c8b49bd. Since it's a clients application failure and it requires Python-Redmine to do some unnecessary things, I'm emitting a PerformanceWarning which explains the issue and asks a client application to fix it, I've also changed the docs to use BytesIO instead of StringIO.

Thank you very much for rasing this issue as it helped to find this nasty bug.

@1508zb
Copy link

@1508zb 1508zb commented Sep 6, 2019

issue = redmine.issue.create(
project_id='vacation',
subject='Vacation',
tracker_id=8,
description='foo',
status_id=3,
priority_id=7,
assigned_to_id=123,
watcher_user_ids=[123],
parent_issue_id=345,
start_date=datetime.date(2014, 1, 1),
due_date=datetime.date(2014, 2, 1),
estimated_hours=4,
done_ratio=40,
custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
uploads=[{'path': r 'C:\1.png'}]
)

Redmine Server: 4.0.4
Python: 3.7
OS: Windows 7

error: Cannot upload this type of attachment
Redmine Server support to upload 'png', but the code doesn't work. However,when the version of Redmine Server is 1.x, code running successfully。Any help would be appreciated!

@maxtepkeev
Copy link
Owner

@maxtepkeev maxtepkeev commented Sep 7, 2019

@1508zb Your code works perfectly fine for me using Python 3.7 and Redmine 4.0.4.

@1508zb
Copy link

@1508zb 1508zb commented Sep 9, 2019

@maxtepkeev Thank you for help! What's your version of python-redmine, please? And what do you think are the possible causes of this situation? My Redmine does not limit this type of attachment, such as png and so on.

@1508zb
Copy link

@1508zb 1508zb commented Sep 9, 2019

@maxtepkeev This is my error screenshot。Chinese error message is not allowed to upload this type of attachment
error

@maxtepkeev
Copy link
Owner

@maxtepkeev maxtepkeev commented Sep 9, 2019

@1508zb I used the latest version (2.2.1). This error comes from Redmine and has nothing to do with Python-Redmine. There might be some plugin blocking uploads. You can check your code against a public Redmine demo http://demo.redmineup.com (admin:admin) and see if it works there (it should). If it works that means it's your Redmine server that is not allowing you to upload these files and you should consult with Redmine people about this.

@1508zb
Copy link

@1508zb 1508zb commented Sep 11, 2019

@maxtepkeev Thank you for your answer!My code works fine against a public Redmine demo http://demo.redmineup.com. For our Redmine, if it sets the type of attachments that are allowed to be uploaded, my code failed although the attachment type I am uploading is allowed. But if it doesn't restrict any attachment types to upload, my code works successfully. Do you know why, please? And dose the public Redmine that you gave limit the types of attachments we can upload?

@maxtepkeev
Copy link
Owner

@maxtepkeev maxtepkeev commented Sep 11, 2019

@1508zb I found the cause of this problem and I can fix it on Python-Redmine side. Fix will be available ASAP.

@1508zb
Copy link

@1508zb 1508zb commented Sep 12, 2019

@maxtepkeev Thank you so much for help! What is the cause of this problem? Is it a bug of Redmine? Looking forward to your new version of Python-Redmine!

avgas3 pushed a commit to avgas3/python-redmine that referenced this issue Mar 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants