merge_setting always returns a dict, even if dict_class is set to something else

I've been using [responses](https://github.com/dropbox/responses) to test an application using matched URL parameters, which was encountering issues as the `merge_setting` function always returns an unordered `dict` (even though the `dict_class` argument defaults to `OrderedDict`). This means that I can't guarantee which order the URL parameters will be constructed in, so writing a test which responds to a particular URL is difficult.

I'm not sure that the `dict_class` argument was meant to be the class of object that is returned, but making it work that way would seem to make sense. As a workaround, I've set the session object's parameters to `None`, which causes `merge_setting` to return the request's parameters unmodified (which, in my case, are an `OrderedDict`).


I see no reason why this is a use case we should support. You're essentially testing something that should never matter (the ordering of the parameters) - in other words your tests are wrong. 

The best way to write a test for your URL is to parse it after it has been constructed. That sounds like more work but if you are in fact intent on testing the URL you could build this into responses as an attribute (like `parsed_url`). 

It is also important to note that we don't support `responses`, so any problems you have with it should be raised there.


In which case, what is the `dict_class` parameter supposed to be for? My feeling was not that something fundamental should be changed in `requests` to make this work, it was that the parameter was there already -- it just wasn't being used properly. If that's not right, then maybe it should be removed entirely.

I know my scenario above is somewhat contrived, but I can imagine other cases where something like this would be genuinely useful, and allowing it to work isn't too much of a hassle. I realise that `responses` is a separate project and unsupported, but being able to predict what order the URL parameters are generated in is useful in general, even if it's not the default behaviour and needs to be enabled.


The purpose of `dict_class` is stated in the docstring:

> If a setting is a dictionary, they will be merged together using `dict_class`.

This means that `dict_class` is intended to control the merging logic. An example here is that of `MultiDict`, which will treat merging settings fundamentally very differently to the way a `dict` or `OrderedDict` would.

_With that said_, I have no particular objection to having `merge_setting` return the `dict_class`. Clearly @sigmavirus24 doesn't agree, but I'll try to have a chat with him and see why we're on different pages. I suspect he's seeing something I'm not. =)


> but I can imagine other cases where something like this would be genuinely useful

I'm interested in hearing what they are.

---

That aside, I don't understand why this isn't a feature request in responses. It makes more sense to want a parsed URL attribute on a call than it does to introduce arbitrary and easily breakable behaviour in requests that will only result in more bug reports like this one.


Here's a concrete example in jQuery UI: http://api.jqueryui.com/sortable/#method-serialize

The order of the URL parameters is important, because it's used to communicate to the server how a collection of objects should be sorted. If this were passed to an application running `requests`, which then made an API call to a backend application, preserving that order should be possible. This change makes that the default behaviour, which won't matter for users who don't care about the ordering, but will have a positive effect for those who do.

The behaviour at the moment is also inconsistent, because setting `parameters = None` on the `Session` object causes `request_parameters` to be handed back unmodified, which means the order is preserved if an `OrderedDict` or list of tuples is passed in.


> The behaviour at the moment is also inconsistent

I disagree (as you might have guessed). If there's nothing to merge, why should we bother modifying anything, especially if it has an API that we're expecting. Basically any mapping can be passed to requests like this and we'll return it so long as it behaves like we expect it to (i.e., has all the methods we need in order to operate correctly). This is very much a feature.

> Here's a concrete example in jQuery UI:

The problem with your example is that requests doesn't work that way. The equivalent way to do that in requests is this:

``` pycon
>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'setname': [1, 5, 3]})
>>> r.json()['args']
{u'setname': [u'1', u'5', u'3']}
```

The parameter string will look different (`setname=1&setname=5&setname=3`) but that's the only way to send it with requests otherwise.

Are there other use cases?


The inconsistency arises from the difference between `session_params` being set to `{}` or `None`. The former causes `merge_setting` to return a plain `dict` (even though no merging happens), whereas the latter will cause it to return `request_params` untouched. Regardless of which is correct, the same thing should probably be returned in both cases.

The jQuery UI example obviously doesn't hold up in this case because there's a proper way to do that in `requests`, but the reasoning still stands; if someone were writing a library to communicate with a legacy HTTP server which needed to receive URL parameters in a particular order, that should be possible.


Closing, for the same reason #2058 was closed.