Add a `add_params` method to the `Session` class.

Otherwise, it's tricky for clients to write code that adds params without them poking inside the innards of `Session`, which can be problematic when the implementation changes.

This was motivated by the fact that I just ran some code of mine that depends on requests and it failed, because my virtualenv had a newer version of requests (0.13.9) and the code was written against 0.13.1 and had code that looked like this:

``` python
self.session.params['access_token'] = response_obj['access_token']
```

I do this to add an `access_token` parameter after the user logs in and obtains an access token, because this parameter is needed on subsequent requests after the login.

This worked in 0.13.1, because in 0.13.1, `session.params` was a dict, but it is now a list of tuples. The problem arises because there was no public interface for setting params and because this is Python, one can manipulate the attributes of the class whenever they desire. When the implementation changes, this breaks code that relies on that implementation.

So I propose to add a `add_params` method to `Session`, which is the official interface for clients to use to add parameters and it can change in the future if the implementation changes and clients code will still work.

I guess this is all a really long way of saying...abstraction :-)


This pull request [passes](http://travis-ci.org/kennethreitz/requests/builds/2255072) (merged aef7b65e into b9ecf456).


Thanks for the contribution, but I don't really see how modifying the very simple dictionary is difficult at all.


My changes towards #179 store parameters as a list of key-value tuples 

It seems besides missing the merge function, I also misunderstood partially what was desired. I'm going to put some effort into this tomorrow or Friday, I already have some ideas started in my fork.

For my sanity, you want to accept the key value lists but you want to store them as dictionaries?

If so, I'd like to propose keeping at least the data parameter as a key value list since that can heavily rely on ordering. Or maybe just use OrderedDicts everywhere? 


@kennethreitz 

> Thanks for the contribution, but I don't really see how modifying the very simple dictionary is difficult at all.

Hmmm, maybe I'm missing some easy way to do this? Or maybe you're not familiar with or recalling the recent changes in how `params` is handled? (see @sigmavirus24's comment also)

`params` **used to** be a dict until very recently. Now it is a list of tuples. It's not rocket science of course to append to a list of tuples -- the issue is that it's tricky for folks to write code that reliably handles `params` when they don't know which version of requests is installed. Not impossible, but harder than it needs to be. Here's what I have in my client code now:

``` python
if isinstance(self.session.params, dict):
    self.session.params['access_token'] = response_obj['access_token']
elif isinstance(self.session.params, list):
    # At some point, `requests` changed session.params from a dict to a list of tuples (maybe in version 0.13.7?)
    self.session.params.append(('access_token', response_obj['access_token']))
```

If I had the `add_params` method then this simply becomes:

``` python
self.session.add_params({'access_token': response_obj['access_token']})
```


Oh, I didn't realize it was a list of tuples now. It should definitely be a dictionary. Let's fix that.


Maybe use OrderedDicts everywhere? I think Kenneth should weigh in on how it should work of course.


@msabramo that was my initial thought as well, yes.


Optional idea:
Related urllib3 bug for headers: https://github.com/shazow/urllib3/issues/3
If we make headers use a MultiDict or similar, then I'd be happy to make filepost encoding use the same. This way there would be less translation happening between requests and urllib3.


@shazow :cake:


OrderedDicts everywhere would be fantastic. Also, I'll fix that up tomorrow gladly. I already have a function to transition to a dictionary from a key, val list. I'll modify it to use ordereddicts though. Sorry about the confusion. This is entirely my fault.


@sigmavirus24 no fault needs to be had, just improvements to a great pull request :)


Hm. So the only problem I have encountered thus far is sending data/files with the same name. OrderedDicts will eat those values by default. I'll push what I have but this one test fails. Apparently this is related to #746. Since these worked as pure lists of key-value tuples, I'm wondering if storing them like this permanently is the solution. These cannot be set when initializing a `Session` object so the use case that spurred this issue shouldn't be encountered. Thoughts?


#817 should take care of this and #804