-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Fix non-resumable binary uploads on Python 3 #147
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
Fix non-resumable binary uploads on Python 3 #147
Conversation
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project, in which case you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
|
I signed it! |
|
CLAs look good, thanks! |
|
What hope is there for test coverage for this change? And what's up with the test failures seen for the current draft of your change? |
|
The broken test is now fixed. It is also stricter now and should serve as a regression test for this bug. |
|
This looks correct to me. @tmatsuo would you mind being a second pair of eyes on this? The try/except import and monkeypatching are giving me the heebie-jeebies. |
googleapiclient/discovery.py
Outdated
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Fixed. - g.flatten(msgRoot, unixfrom=False)
- if write_lines:
- BytesGenerator._write_lines = write_lines
+ try:
+ g.flatten(msgRoot, unixfrom=False)
+ finally:
+ if write_lines:
+ BytesGenerator._write_lines = write_lines |
|
I'm still worrying when the code is used in multi threaded code. I think some threads might pick the patched version as |
|
Let me ask an alarmingly naïve question that reveals how I see the world with precious, innocent, childlike wonder: how has Python bug 18886 stayed open so long if it is so easy to work around? |
Found a better way to do this that sidesteps the issue :)
There could be a subtlety: some applications may have a preference for The same bug has also been reported as #19003, which includes a patch. |
googleapiclient/discovery.py
Outdated
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Done. |
1. Generator and StringIO are replaced by BytesGenerator and BytesIO.
If BytesGenerator doesn't exist (as is the case in Python 2), fall
back to Generator.
2. BytesGenerator is buggy [1] [2] and corrupts '\r' into '\n'. To
work around this, we implement a patched version of BytesGenerator
that replaces ._write_lines with just .write.
The test_multipart_media_good_upload has been updated to reflect the
change. It is also stricter now, as it matches the entire request body
against the expected form.
Note: BytesGenerator was introduced in Python 3.2. This is OK since the
library already demands 3.3+.
Fixes #145.
[1]: https://bugs.python.org/issue18886
[2]: https://bugs.python.org/issue19003
|
Thanks, LGTM |
|
Thank you for this conversation and for your contribution to the library! |
Fix non-resumable binary uploads on Python 3.
|
Is the available master the one that installs via pip ? Cause I am having exactly the original issue that lead to this patch ! |
|
@chromafunk: unfortunately no, we're overdue for a release. Perhaps in the next week? Fingers crossed? |
|
@nathanielmanistaatgoogle I have modified discovery.py with the patch by @Rufflewind myself but the problem persist when using resumable = False, do you want me to help on this ? I can dump output if you want it. |
|
A new release would be terrific! |
GeneratorandStringIOare replaced byBytesGeneratorandBytesIO. IfBytesGeneratordoesn't exist (as is the case in Python 2), fall back to Generator.BytesGeneratoris buggy (see #18886 and #19003) and corrupts\rinto\n. To work around this, we implement a patched version ofBytesGeneratorthat replaces._write_lineswith just.write.Note:
BytesGeneratorwas introduced in Python 3.2. This is OK since the library already demands 3.3+.The
test_multipart_media_good_uploadhas been updated to reflect the change. It is also stricter now, as it matches the entire request body against the expected form.Fixes #145.
This ensures that
bodyis of typebytesrather thanstr.I did some tests to make sure the new code is still sensible: the flattened MIME of a simple upload of a random 1MiB file on Python 3.5.0 after the fix is identical to that on Python 2.7.10 before and after the fix (modulo
dictrearrangements and MIME boundaries).