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

AttributeError: 'unicode' object has no attribute 'items' #68

Closed
alanhamlett opened this issue Mar 19, 2016 · 6 comments
Closed

AttributeError: 'unicode' object has no attribute 'items' #68

alanhamlett opened this issue Mar 19, 2016 · 6 comments

Comments

@alanhamlett
Copy link

This line misses Python2 unicode strings, eventually causing an AttributeError exception.

Traceback (most recent call last):
  File "/opt/wakatime/current/venv/local/lib/python2.7/site-packages/braintree/subscription.py", line 150, in update
    return Configuration.gateway().subscription.update(subscription_id, params)
  File "/opt/wakatime/current/venv/local/lib/python2.7/site-packages/braintree/subscription_gateway.py", line 59, in update
    Resource.verify_keys(params, Subscription.update_signature())
  File "/opt/wakatime/current/venv/local/lib/python2.7/site-packages/braintree/resource.py", line 9, in verify_keys
    params_keys = Resource.__flattened_params_keys(params)
  File "/opt/wakatime/current/venv/local/lib/python2.7/site-packages/braintree/resource.py", line 27, in __flattened_params_keys
    keys += Resource.__flattened_params_keys(val, full_key)
  File "/opt/wakatime/current/venv/local/lib/python2.7/site-packages/braintree/resource.py", line 30, in __flattened_params_keys
    keys += Resource.__flattened_params_keys(item, full_key)
  File "/opt/wakatime/current/venv/local/lib/python2.7/site-packages/braintree/resource.py", line 24, in __flattened_params_keys
    for key, val in params.items():
AttributeError: 'unicode' object has no attribute 'items'

Should be basestring instead of str, or even better use six.string_types for Python 3 compatibility.

@jdlc
Copy link

jdlc commented Mar 21, 2016

@alanhamlett,
Thanks for opening this issue. Could you share more details about your use case and integration with Braintree so we can better evaluate this change? Currently the Braintree Python client library as a whole favors str over basestring.

@alanhamlett
Copy link
Author

Sometimes I pass strings from SQLAlchemy, which prefers unicode over str, and from WTForms, which also prefers unicode over str. I'm not sure which attribute caused the error, but it was when changing the quantity in the addons array when updating a subscription.

@jdlc
Copy link

jdlc commented Mar 23, 2016

Thanks for clarifying your use case. We'll discuss this change and let you know if we have any further questions.

@jdlc
Copy link

jdlc commented Apr 11, 2016

Hi @alanhamlett,
We've discussed this internally and we will be retaining str as we want encoded strings instead of unicode. I'm closing this issue, but thanks for reaching out.

@jdlc jdlc closed this as completed Apr 11, 2016
@alanhamlett
Copy link
Author

Ok, just want to say that str should only be used when writing to disk, network, or other things external to Python. unicode is the preferred way to handle any string in Python.

When you’re dealing with text manipulations (finding the number of characters in a string or cutting a string on word boundaries) you should be dealing with unicode strings as they abstract characters in a manner that’s appropriate for thinking of them as a sequence of letters that you will see on a page. When dealing with I/O, reading to and from the disk, printing to a terminal, sending something over a network link, etc, you should be dealing with byte str as those devices are going to need to deal with concrete implementations of what bytes represent your abstract characters.

For example as soon as you get a string from the user or from the network, convert it to unicode:
https://pythonhosted.org/kitchen/unicode-frustrations.html#convert-text-at-the-border
I've noticed usage of both unicode and str in this library. You should standardize the usage of unicode vs str throughout the library.

You're going to run into a lot of cases where unicode is needed (emails can contain unicode characters) so it's best to standardize on unicode instead of str. Having to somehow guess which string type this library is expecting is a recipe for exceptions.

@alanhamlett
Copy link
Author

Also, the 2 most popular Python web frameworks[1] both default to unicode and both convert user input to unicode. For example a payment processor token from braintree.js is automatically treated as unicode and it goes against conventions to have to convert back to str when passing strings to braintree_python.

  1. Django and Flask are in my experience the 2 most popular Python web frameworks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants