Allow dicts for Session cookies

Right now you can provide a dictionary to the `cookies` param almost everywhere in Requests and it will be converted into a RequestsCookieJar (aka "just work"). The one place this isn't happening is with Session, which will accept a dictionary without complaint but then fail when you try to send a PreparedRequest. 

I discussed wanting to make this part of the API a bit more predictable with @Lukasa and this was a suggested fix for the problem. I did fair amount of testing outside of the included test and I don't believe this will adversely affect functionality. The one case I found is where someone is providing a CookieJar-like object that doesn't inherit from `cookielib.CookieJar`, and doesn't have an `__iter__` method. This seems like an unlikely case and wasn't _really_ supported before, so I wouldn't consider this breaking.


@sigmavirus24, if we're planning on enforcing cookies requiring domains with your work in #2714, then I'd agree this PR may not be needed. If we don't intend to deprecate the use of dict->cookies though, I do think this should work the same everywhere. The documentation is already a bit opaque on this, and my original suggestion to @Lukasa was to update it to reflect how updating cookies currently works with a Session. If we want to make a note of this change in the documentation, I think simply adding "As of 2.12" at the beginning should be sufficient.

I can make the changes for `self.cookies` to `self._cookies` if there's a consensus to move forward with this. I'm not sure I'm clear on the answer to that at present though. I'll wait for a go ahead from you and @Lukasa before I make any further changes.


very brilliant~~


@sigmavirus24 @Lukasa, if we don't want to address this issue by allowing dictionaries, perhaps we should at least raise an exception when someone tries to assign one? I'm not particularly keen on this approach, but the current point of failure doesn't generate a helpful error.


@nateprewitt I think @sigmavirus24 was tentatively in favour of this change, at least as a temporary stopping-off point before something better. He was just asking for a change in the descriptor protocol.


So here's my genuine perspective:

Dictionaries cannot adequately describe everything about a  particular cookie. In fact, I'd go so far as to say that setting cookies on a session (using dictionaries) is a security _risk_ if not full out _vulnerability_. When we specify cookies as a dictionary, there's no Host provided which means that with very few exceptions we will send those cookies to _every_ host that session talks to. Using a dictionary means you can't effectively say "Only send this cookie to https://example.com". In my opinion we should absolutely do something to warn folks, but raising an exception is backwards incompatible and this approach (while internally consistent) is a footgun more than anything.


@sigmavirus24 I agree with you about there being a risk of unintentionally sending cookies over the wire with session cookies, but I think that isn't entirely coupled to this issue. Instead of allowing people to pass a dictionary, we currently have them dump a dictionary into a RequestsCookieJar which has no domain info either. So this is an extra step for the sake of purity, that currently provides the user no extra safety or benefit.

I can see how this modification may reenforce bad behaviour that should probably be removed in 3.0.0, so in the meantime, I'll propose this. I think adding a section in the documentation detailing _how_ to do this correctly would go a long way. We should also at the very least add a warning when setting Session's cookies attribute with a dict, directing them to the documentation.

Something like this could go in the docs with an explanation of why using the domain property is important. An iterable-based version of `set` or `set_cookie` would probably be a useful helper for 3.0.0 too.

``` python

s = Session()
cookiejar = RequestsCookieJar()
domain = '.google.com'
for name, value in cookie_dict.items():
    cookiejar.set(name, value, domain=domain)
s.cookies = cookiejar
```


Like @nateprewitt said, there is benefits here we can not ignore.
When the user want to use `add_dict_to_cookiejar` this will add the dict to `''`domain. This is most likely not the desired scenario. 

For example:

```
s = requests.Session()
s.get('https://google.com')

# Generating cookie dict, based on the sessions cookies and other source 
new_cookie_dict = generate(s.cookies)
add_dict_to_cookiejar(s.cookies, new_cookie_dict)

# s.cookies might have duplicated cookies on different domains s.cookies['dup'] will error CookieConflictError 
```


Alright @Lukasa, @sigmavirus24,

I took a swing at my [last comment](https://github.com/kennethreitz/requests/pull/3595#issuecomment-254563756). It comes in two pieces. 

3e4e5b7: This adds documentation for adding dictionaries with domains. It's currently based off of the solution below, but if it's decided that isn't a good fit, we can change the code to my comment above. This at least provides direction for the user to do the right thing, rather than identical behaviour to a dictionary, with more code.

e2a4f9f & 4454849: I added in a `**kwargs` option to the `add_dict_to_cookiejar` and `cookiejar_from_dict` to allow cookie parameters. This will allow you to pass dictionary-wide cookie params to use the current proposed solution for session cookies "safely". This behaviour resembles what the browser does with set-cookie on a per request basis, allows for _fairly_ easy extensibility and it's a minimal code change. It definitely needs some updated doc strings but I wanted to get feed back before proceeding.

Lastly, I think that a warning, pointing users to the documentation, when setting the session cookie to a dict is low overhead and will prevent issues like #3624.

This is becoming a much longer running discussion than I anticipated after discussing opening this patch with Lukasa. It may be worth closing this PR and moving it into an issue, but I'll defer to your judgements on how you want this cataloged.


I can get behind moving this to an issue for discussion. It's clear @sigmavirus24 has a bigger goal for this API than I originally did, and so I'd like us to move to a forum where he can participate effectively despite his current high workload.


Alright, I'm going to close this for now then and open a likely broader cookie issue.