fix issue when an object overrode __getattr__

when a class overrode `__getattr__` method and always return something even `None`, this check would fail.
adding `callable` check to ensure there is an existing method `read`.

below is fail case which is used widely to use dot access for a dict:
```
class DotDict(dict):
    """dot.notation access to dictionary attributes"""
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__
    __getattr__ = dict.get

```


Hi @truebit, thanks for contributing to Requests. While we want Requests to be general enough to span a wide range of use cases, I'm not sure this is necessary. The [official Python docs](https://docs.python.org/3/reference/datamodel.html#object.__getattr__) state pretty clearly that: 
>  [\_\_getattr\_\_] should either return the (computed) attribute value or raise an AttributeError exception.

Overloading a dunder method and breaking the expected contract is going to cause issues, and we can't support every possible scenario. Given that \_\_getattr\_\_ is used in a number of areas throughout the codebase, this would have to be added everywhere for what I'd consider undefined behaviour. I don't think we're likely to accept this PR at this time. Thanks for the proposal though!

Sorry, Maybe I did not make it clear. Besides the mentioned case, for the condition check statement itself, its intention is to check if a `read` **method** in the object:
``` 
if isinstance(data, (str, bytes)):
    return data
elif hasattr(data, 'read'):
    return data
elif hasattr(data, '__iter__'):
    result = []
……
```

In that case, current check is only a necessary but not sufficient condition; with a `callable` check , the two checks together would be necessary and sufficient one.

On the other hand, if it's not check for `read` method, there is another problem: the `hasattr` in Python2 would not find a property if this check is only check for a `read` attrbibute instead of `read` method.  More details could be found [here](https://hynek.me/articles/hasattr/).

In a word, I think this PR has no problem

I added one [more commit](https://github.com/truebit/requests/commit/ed01d428ab9d8ffade81d3c3e716d163d3ab330a) to cover all hasattr problems in requests.

BTW, It seems closed PR do not update new commits...

@truebit, the problem mentioned above is how quickly the handling scope explodes once you start down this path. We have a well documented set of inputs we take for each parameter in the API. Once users start handing in objects with unknown or redefined behavior, it becomes extremely difficult to predict all outcomes. Trying to handle everything causes the code base to become needlessly cluttered.

A quick example is if someone has chosen to overload `read`. If they decide that read is still callable but it performs a non-io action, we’re in the same spot. The definition of `read` has clear semantics in the [Python docs](https://docs.python.org/3/glossary.html#term-file-object), deviating from that enters unsupported territory.

As for `hasattr` vs `getattr`, we’re aware of the issues with Python2. We’ve discussed moving these over previously (#3426) but it was determined to be out of scope by Kenneth.

I understand your standpoint. 
As a professional QA, I do not think this bug is too occasional to be fixed. 
IMHO right is always above wrong:
"In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it." from zen of Python

>  "In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it." from zen of Python

And as a professional Python software developer your "widely used" accessing of a dictionary via attributes is not widely used. I've seen a great deal of proprietary and open source Python codebases that don't do that because there is one obvious way to access the members of a dictionary and using attributes is **not** that method.

Nevertheless, `callable` is a correct way to check if it's an attribute or a method after `hasattr` returned `True`...