annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/site-packages/requests/cookies.py @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
rev   line source
jpayne@68 1 """
jpayne@68 2 requests.cookies
jpayne@68 3 ~~~~~~~~~~~~~~~~
jpayne@68 4
jpayne@68 5 Compatibility code to be able to use `http.cookiejar.CookieJar` with requests.
jpayne@68 6
jpayne@68 7 requests.utils imports from here, so be careful with imports.
jpayne@68 8 """
jpayne@68 9
jpayne@68 10 import calendar
jpayne@68 11 import copy
jpayne@68 12 import time
jpayne@68 13
jpayne@68 14 from ._internal_utils import to_native_string
jpayne@68 15 from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse
jpayne@68 16
jpayne@68 17 try:
jpayne@68 18 import threading
jpayne@68 19 except ImportError:
jpayne@68 20 import dummy_threading as threading
jpayne@68 21
jpayne@68 22
jpayne@68 23 class MockRequest:
jpayne@68 24 """Wraps a `requests.Request` to mimic a `urllib2.Request`.
jpayne@68 25
jpayne@68 26 The code in `http.cookiejar.CookieJar` expects this interface in order to correctly
jpayne@68 27 manage cookie policies, i.e., determine whether a cookie can be set, given the
jpayne@68 28 domains of the request and the cookie.
jpayne@68 29
jpayne@68 30 The original request object is read-only. The client is responsible for collecting
jpayne@68 31 the new headers via `get_new_headers()` and interpreting them appropriately. You
jpayne@68 32 probably want `get_cookie_header`, defined below.
jpayne@68 33 """
jpayne@68 34
jpayne@68 35 def __init__(self, request):
jpayne@68 36 self._r = request
jpayne@68 37 self._new_headers = {}
jpayne@68 38 self.type = urlparse(self._r.url).scheme
jpayne@68 39
jpayne@68 40 def get_type(self):
jpayne@68 41 return self.type
jpayne@68 42
jpayne@68 43 def get_host(self):
jpayne@68 44 return urlparse(self._r.url).netloc
jpayne@68 45
jpayne@68 46 def get_origin_req_host(self):
jpayne@68 47 return self.get_host()
jpayne@68 48
jpayne@68 49 def get_full_url(self):
jpayne@68 50 # Only return the response's URL if the user hadn't set the Host
jpayne@68 51 # header
jpayne@68 52 if not self._r.headers.get("Host"):
jpayne@68 53 return self._r.url
jpayne@68 54 # If they did set it, retrieve it and reconstruct the expected domain
jpayne@68 55 host = to_native_string(self._r.headers["Host"], encoding="utf-8")
jpayne@68 56 parsed = urlparse(self._r.url)
jpayne@68 57 # Reconstruct the URL as we expect it
jpayne@68 58 return urlunparse(
jpayne@68 59 [
jpayne@68 60 parsed.scheme,
jpayne@68 61 host,
jpayne@68 62 parsed.path,
jpayne@68 63 parsed.params,
jpayne@68 64 parsed.query,
jpayne@68 65 parsed.fragment,
jpayne@68 66 ]
jpayne@68 67 )
jpayne@68 68
jpayne@68 69 def is_unverifiable(self):
jpayne@68 70 return True
jpayne@68 71
jpayne@68 72 def has_header(self, name):
jpayne@68 73 return name in self._r.headers or name in self._new_headers
jpayne@68 74
jpayne@68 75 def get_header(self, name, default=None):
jpayne@68 76 return self._r.headers.get(name, self._new_headers.get(name, default))
jpayne@68 77
jpayne@68 78 def add_header(self, key, val):
jpayne@68 79 """cookiejar has no legitimate use for this method; add it back if you find one."""
jpayne@68 80 raise NotImplementedError(
jpayne@68 81 "Cookie headers should be added with add_unredirected_header()"
jpayne@68 82 )
jpayne@68 83
jpayne@68 84 def add_unredirected_header(self, name, value):
jpayne@68 85 self._new_headers[name] = value
jpayne@68 86
jpayne@68 87 def get_new_headers(self):
jpayne@68 88 return self._new_headers
jpayne@68 89
jpayne@68 90 @property
jpayne@68 91 def unverifiable(self):
jpayne@68 92 return self.is_unverifiable()
jpayne@68 93
jpayne@68 94 @property
jpayne@68 95 def origin_req_host(self):
jpayne@68 96 return self.get_origin_req_host()
jpayne@68 97
jpayne@68 98 @property
jpayne@68 99 def host(self):
jpayne@68 100 return self.get_host()
jpayne@68 101
jpayne@68 102
jpayne@68 103 class MockResponse:
jpayne@68 104 """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
jpayne@68 105
jpayne@68 106 ...what? Basically, expose the parsed HTTP headers from the server response
jpayne@68 107 the way `http.cookiejar` expects to see them.
jpayne@68 108 """
jpayne@68 109
jpayne@68 110 def __init__(self, headers):
jpayne@68 111 """Make a MockResponse for `cookiejar` to read.
jpayne@68 112
jpayne@68 113 :param headers: a httplib.HTTPMessage or analogous carrying the headers
jpayne@68 114 """
jpayne@68 115 self._headers = headers
jpayne@68 116
jpayne@68 117 def info(self):
jpayne@68 118 return self._headers
jpayne@68 119
jpayne@68 120 def getheaders(self, name):
jpayne@68 121 self._headers.getheaders(name)
jpayne@68 122
jpayne@68 123
jpayne@68 124 def extract_cookies_to_jar(jar, request, response):
jpayne@68 125 """Extract the cookies from the response into a CookieJar.
jpayne@68 126
jpayne@68 127 :param jar: http.cookiejar.CookieJar (not necessarily a RequestsCookieJar)
jpayne@68 128 :param request: our own requests.Request object
jpayne@68 129 :param response: urllib3.HTTPResponse object
jpayne@68 130 """
jpayne@68 131 if not (hasattr(response, "_original_response") and response._original_response):
jpayne@68 132 return
jpayne@68 133 # the _original_response field is the wrapped httplib.HTTPResponse object,
jpayne@68 134 req = MockRequest(request)
jpayne@68 135 # pull out the HTTPMessage with the headers and put it in the mock:
jpayne@68 136 res = MockResponse(response._original_response.msg)
jpayne@68 137 jar.extract_cookies(res, req)
jpayne@68 138
jpayne@68 139
jpayne@68 140 def get_cookie_header(jar, request):
jpayne@68 141 """
jpayne@68 142 Produce an appropriate Cookie header string to be sent with `request`, or None.
jpayne@68 143
jpayne@68 144 :rtype: str
jpayne@68 145 """
jpayne@68 146 r = MockRequest(request)
jpayne@68 147 jar.add_cookie_header(r)
jpayne@68 148 return r.get_new_headers().get("Cookie")
jpayne@68 149
jpayne@68 150
jpayne@68 151 def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
jpayne@68 152 """Unsets a cookie by name, by default over all domains and paths.
jpayne@68 153
jpayne@68 154 Wraps CookieJar.clear(), is O(n).
jpayne@68 155 """
jpayne@68 156 clearables = []
jpayne@68 157 for cookie in cookiejar:
jpayne@68 158 if cookie.name != name:
jpayne@68 159 continue
jpayne@68 160 if domain is not None and domain != cookie.domain:
jpayne@68 161 continue
jpayne@68 162 if path is not None and path != cookie.path:
jpayne@68 163 continue
jpayne@68 164 clearables.append((cookie.domain, cookie.path, cookie.name))
jpayne@68 165
jpayne@68 166 for domain, path, name in clearables:
jpayne@68 167 cookiejar.clear(domain, path, name)
jpayne@68 168
jpayne@68 169
jpayne@68 170 class CookieConflictError(RuntimeError):
jpayne@68 171 """There are two cookies that meet the criteria specified in the cookie jar.
jpayne@68 172 Use .get and .set and include domain and path args in order to be more specific.
jpayne@68 173 """
jpayne@68 174
jpayne@68 175
jpayne@68 176 class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
jpayne@68 177 """Compatibility class; is a http.cookiejar.CookieJar, but exposes a dict
jpayne@68 178 interface.
jpayne@68 179
jpayne@68 180 This is the CookieJar we create by default for requests and sessions that
jpayne@68 181 don't specify one, since some clients may expect response.cookies and
jpayne@68 182 session.cookies to support dict operations.
jpayne@68 183
jpayne@68 184 Requests does not use the dict interface internally; it's just for
jpayne@68 185 compatibility with external client code. All requests code should work
jpayne@68 186 out of the box with externally provided instances of ``CookieJar``, e.g.
jpayne@68 187 ``LWPCookieJar`` and ``FileCookieJar``.
jpayne@68 188
jpayne@68 189 Unlike a regular CookieJar, this class is pickleable.
jpayne@68 190
jpayne@68 191 .. warning:: dictionary operations that are normally O(1) may be O(n).
jpayne@68 192 """
jpayne@68 193
jpayne@68 194 def get(self, name, default=None, domain=None, path=None):
jpayne@68 195 """Dict-like get() that also supports optional domain and path args in
jpayne@68 196 order to resolve naming collisions from using one cookie jar over
jpayne@68 197 multiple domains.
jpayne@68 198
jpayne@68 199 .. warning:: operation is O(n), not O(1).
jpayne@68 200 """
jpayne@68 201 try:
jpayne@68 202 return self._find_no_duplicates(name, domain, path)
jpayne@68 203 except KeyError:
jpayne@68 204 return default
jpayne@68 205
jpayne@68 206 def set(self, name, value, **kwargs):
jpayne@68 207 """Dict-like set() that also supports optional domain and path args in
jpayne@68 208 order to resolve naming collisions from using one cookie jar over
jpayne@68 209 multiple domains.
jpayne@68 210 """
jpayne@68 211 # support client code that unsets cookies by assignment of a None value:
jpayne@68 212 if value is None:
jpayne@68 213 remove_cookie_by_name(
jpayne@68 214 self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
jpayne@68 215 )
jpayne@68 216 return
jpayne@68 217
jpayne@68 218 if isinstance(value, Morsel):
jpayne@68 219 c = morsel_to_cookie(value)
jpayne@68 220 else:
jpayne@68 221 c = create_cookie(name, value, **kwargs)
jpayne@68 222 self.set_cookie(c)
jpayne@68 223 return c
jpayne@68 224
jpayne@68 225 def iterkeys(self):
jpayne@68 226 """Dict-like iterkeys() that returns an iterator of names of cookies
jpayne@68 227 from the jar.
jpayne@68 228
jpayne@68 229 .. seealso:: itervalues() and iteritems().
jpayne@68 230 """
jpayne@68 231 for cookie in iter(self):
jpayne@68 232 yield cookie.name
jpayne@68 233
jpayne@68 234 def keys(self):
jpayne@68 235 """Dict-like keys() that returns a list of names of cookies from the
jpayne@68 236 jar.
jpayne@68 237
jpayne@68 238 .. seealso:: values() and items().
jpayne@68 239 """
jpayne@68 240 return list(self.iterkeys())
jpayne@68 241
jpayne@68 242 def itervalues(self):
jpayne@68 243 """Dict-like itervalues() that returns an iterator of values of cookies
jpayne@68 244 from the jar.
jpayne@68 245
jpayne@68 246 .. seealso:: iterkeys() and iteritems().
jpayne@68 247 """
jpayne@68 248 for cookie in iter(self):
jpayne@68 249 yield cookie.value
jpayne@68 250
jpayne@68 251 def values(self):
jpayne@68 252 """Dict-like values() that returns a list of values of cookies from the
jpayne@68 253 jar.
jpayne@68 254
jpayne@68 255 .. seealso:: keys() and items().
jpayne@68 256 """
jpayne@68 257 return list(self.itervalues())
jpayne@68 258
jpayne@68 259 def iteritems(self):
jpayne@68 260 """Dict-like iteritems() that returns an iterator of name-value tuples
jpayne@68 261 from the jar.
jpayne@68 262
jpayne@68 263 .. seealso:: iterkeys() and itervalues().
jpayne@68 264 """
jpayne@68 265 for cookie in iter(self):
jpayne@68 266 yield cookie.name, cookie.value
jpayne@68 267
jpayne@68 268 def items(self):
jpayne@68 269 """Dict-like items() that returns a list of name-value tuples from the
jpayne@68 270 jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
jpayne@68 271 vanilla python dict of key value pairs.
jpayne@68 272
jpayne@68 273 .. seealso:: keys() and values().
jpayne@68 274 """
jpayne@68 275 return list(self.iteritems())
jpayne@68 276
jpayne@68 277 def list_domains(self):
jpayne@68 278 """Utility method to list all the domains in the jar."""
jpayne@68 279 domains = []
jpayne@68 280 for cookie in iter(self):
jpayne@68 281 if cookie.domain not in domains:
jpayne@68 282 domains.append(cookie.domain)
jpayne@68 283 return domains
jpayne@68 284
jpayne@68 285 def list_paths(self):
jpayne@68 286 """Utility method to list all the paths in the jar."""
jpayne@68 287 paths = []
jpayne@68 288 for cookie in iter(self):
jpayne@68 289 if cookie.path not in paths:
jpayne@68 290 paths.append(cookie.path)
jpayne@68 291 return paths
jpayne@68 292
jpayne@68 293 def multiple_domains(self):
jpayne@68 294 """Returns True if there are multiple domains in the jar.
jpayne@68 295 Returns False otherwise.
jpayne@68 296
jpayne@68 297 :rtype: bool
jpayne@68 298 """
jpayne@68 299 domains = []
jpayne@68 300 for cookie in iter(self):
jpayne@68 301 if cookie.domain is not None and cookie.domain in domains:
jpayne@68 302 return True
jpayne@68 303 domains.append(cookie.domain)
jpayne@68 304 return False # there is only one domain in jar
jpayne@68 305
jpayne@68 306 def get_dict(self, domain=None, path=None):
jpayne@68 307 """Takes as an argument an optional domain and path and returns a plain
jpayne@68 308 old Python dict of name-value pairs of cookies that meet the
jpayne@68 309 requirements.
jpayne@68 310
jpayne@68 311 :rtype: dict
jpayne@68 312 """
jpayne@68 313 dictionary = {}
jpayne@68 314 for cookie in iter(self):
jpayne@68 315 if (domain is None or cookie.domain == domain) and (
jpayne@68 316 path is None or cookie.path == path
jpayne@68 317 ):
jpayne@68 318 dictionary[cookie.name] = cookie.value
jpayne@68 319 return dictionary
jpayne@68 320
jpayne@68 321 def __contains__(self, name):
jpayne@68 322 try:
jpayne@68 323 return super().__contains__(name)
jpayne@68 324 except CookieConflictError:
jpayne@68 325 return True
jpayne@68 326
jpayne@68 327 def __getitem__(self, name):
jpayne@68 328 """Dict-like __getitem__() for compatibility with client code. Throws
jpayne@68 329 exception if there are more than one cookie with name. In that case,
jpayne@68 330 use the more explicit get() method instead.
jpayne@68 331
jpayne@68 332 .. warning:: operation is O(n), not O(1).
jpayne@68 333 """
jpayne@68 334 return self._find_no_duplicates(name)
jpayne@68 335
jpayne@68 336 def __setitem__(self, name, value):
jpayne@68 337 """Dict-like __setitem__ for compatibility with client code. Throws
jpayne@68 338 exception if there is already a cookie of that name in the jar. In that
jpayne@68 339 case, use the more explicit set() method instead.
jpayne@68 340 """
jpayne@68 341 self.set(name, value)
jpayne@68 342
jpayne@68 343 def __delitem__(self, name):
jpayne@68 344 """Deletes a cookie given a name. Wraps ``http.cookiejar.CookieJar``'s
jpayne@68 345 ``remove_cookie_by_name()``.
jpayne@68 346 """
jpayne@68 347 remove_cookie_by_name(self, name)
jpayne@68 348
jpayne@68 349 def set_cookie(self, cookie, *args, **kwargs):
jpayne@68 350 if (
jpayne@68 351 hasattr(cookie.value, "startswith")
jpayne@68 352 and cookie.value.startswith('"')
jpayne@68 353 and cookie.value.endswith('"')
jpayne@68 354 ):
jpayne@68 355 cookie.value = cookie.value.replace('\\"', "")
jpayne@68 356 return super().set_cookie(cookie, *args, **kwargs)
jpayne@68 357
jpayne@68 358 def update(self, other):
jpayne@68 359 """Updates this jar with cookies from another CookieJar or dict-like"""
jpayne@68 360 if isinstance(other, cookielib.CookieJar):
jpayne@68 361 for cookie in other:
jpayne@68 362 self.set_cookie(copy.copy(cookie))
jpayne@68 363 else:
jpayne@68 364 super().update(other)
jpayne@68 365
jpayne@68 366 def _find(self, name, domain=None, path=None):
jpayne@68 367 """Requests uses this method internally to get cookie values.
jpayne@68 368
jpayne@68 369 If there are conflicting cookies, _find arbitrarily chooses one.
jpayne@68 370 See _find_no_duplicates if you want an exception thrown if there are
jpayne@68 371 conflicting cookies.
jpayne@68 372
jpayne@68 373 :param name: a string containing name of cookie
jpayne@68 374 :param domain: (optional) string containing domain of cookie
jpayne@68 375 :param path: (optional) string containing path of cookie
jpayne@68 376 :return: cookie.value
jpayne@68 377 """
jpayne@68 378 for cookie in iter(self):
jpayne@68 379 if cookie.name == name:
jpayne@68 380 if domain is None or cookie.domain == domain:
jpayne@68 381 if path is None or cookie.path == path:
jpayne@68 382 return cookie.value
jpayne@68 383
jpayne@68 384 raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
jpayne@68 385
jpayne@68 386 def _find_no_duplicates(self, name, domain=None, path=None):
jpayne@68 387 """Both ``__get_item__`` and ``get`` call this function: it's never
jpayne@68 388 used elsewhere in Requests.
jpayne@68 389
jpayne@68 390 :param name: a string containing name of cookie
jpayne@68 391 :param domain: (optional) string containing domain of cookie
jpayne@68 392 :param path: (optional) string containing path of cookie
jpayne@68 393 :raises KeyError: if cookie is not found
jpayne@68 394 :raises CookieConflictError: if there are multiple cookies
jpayne@68 395 that match name and optionally domain and path
jpayne@68 396 :return: cookie.value
jpayne@68 397 """
jpayne@68 398 toReturn = None
jpayne@68 399 for cookie in iter(self):
jpayne@68 400 if cookie.name == name:
jpayne@68 401 if domain is None or cookie.domain == domain:
jpayne@68 402 if path is None or cookie.path == path:
jpayne@68 403 if toReturn is not None:
jpayne@68 404 # if there are multiple cookies that meet passed in criteria
jpayne@68 405 raise CookieConflictError(
jpayne@68 406 f"There are multiple cookies with name, {name!r}"
jpayne@68 407 )
jpayne@68 408 # we will eventually return this as long as no cookie conflict
jpayne@68 409 toReturn = cookie.value
jpayne@68 410
jpayne@68 411 if toReturn:
jpayne@68 412 return toReturn
jpayne@68 413 raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
jpayne@68 414
jpayne@68 415 def __getstate__(self):
jpayne@68 416 """Unlike a normal CookieJar, this class is pickleable."""
jpayne@68 417 state = self.__dict__.copy()
jpayne@68 418 # remove the unpickleable RLock object
jpayne@68 419 state.pop("_cookies_lock")
jpayne@68 420 return state
jpayne@68 421
jpayne@68 422 def __setstate__(self, state):
jpayne@68 423 """Unlike a normal CookieJar, this class is pickleable."""
jpayne@68 424 self.__dict__.update(state)
jpayne@68 425 if "_cookies_lock" not in self.__dict__:
jpayne@68 426 self._cookies_lock = threading.RLock()
jpayne@68 427
jpayne@68 428 def copy(self):
jpayne@68 429 """Return a copy of this RequestsCookieJar."""
jpayne@68 430 new_cj = RequestsCookieJar()
jpayne@68 431 new_cj.set_policy(self.get_policy())
jpayne@68 432 new_cj.update(self)
jpayne@68 433 return new_cj
jpayne@68 434
jpayne@68 435 def get_policy(self):
jpayne@68 436 """Return the CookiePolicy instance used."""
jpayne@68 437 return self._policy
jpayne@68 438
jpayne@68 439
jpayne@68 440 def _copy_cookie_jar(jar):
jpayne@68 441 if jar is None:
jpayne@68 442 return None
jpayne@68 443
jpayne@68 444 if hasattr(jar, "copy"):
jpayne@68 445 # We're dealing with an instance of RequestsCookieJar
jpayne@68 446 return jar.copy()
jpayne@68 447 # We're dealing with a generic CookieJar instance
jpayne@68 448 new_jar = copy.copy(jar)
jpayne@68 449 new_jar.clear()
jpayne@68 450 for cookie in jar:
jpayne@68 451 new_jar.set_cookie(copy.copy(cookie))
jpayne@68 452 return new_jar
jpayne@68 453
jpayne@68 454
jpayne@68 455 def create_cookie(name, value, **kwargs):
jpayne@68 456 """Make a cookie from underspecified parameters.
jpayne@68 457
jpayne@68 458 By default, the pair of `name` and `value` will be set for the domain ''
jpayne@68 459 and sent on every request (this is sometimes called a "supercookie").
jpayne@68 460 """
jpayne@68 461 result = {
jpayne@68 462 "version": 0,
jpayne@68 463 "name": name,
jpayne@68 464 "value": value,
jpayne@68 465 "port": None,
jpayne@68 466 "domain": "",
jpayne@68 467 "path": "/",
jpayne@68 468 "secure": False,
jpayne@68 469 "expires": None,
jpayne@68 470 "discard": True,
jpayne@68 471 "comment": None,
jpayne@68 472 "comment_url": None,
jpayne@68 473 "rest": {"HttpOnly": None},
jpayne@68 474 "rfc2109": False,
jpayne@68 475 }
jpayne@68 476
jpayne@68 477 badargs = set(kwargs) - set(result)
jpayne@68 478 if badargs:
jpayne@68 479 raise TypeError(
jpayne@68 480 f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
jpayne@68 481 )
jpayne@68 482
jpayne@68 483 result.update(kwargs)
jpayne@68 484 result["port_specified"] = bool(result["port"])
jpayne@68 485 result["domain_specified"] = bool(result["domain"])
jpayne@68 486 result["domain_initial_dot"] = result["domain"].startswith(".")
jpayne@68 487 result["path_specified"] = bool(result["path"])
jpayne@68 488
jpayne@68 489 return cookielib.Cookie(**result)
jpayne@68 490
jpayne@68 491
jpayne@68 492 def morsel_to_cookie(morsel):
jpayne@68 493 """Convert a Morsel object into a Cookie containing the one k/v pair."""
jpayne@68 494
jpayne@68 495 expires = None
jpayne@68 496 if morsel["max-age"]:
jpayne@68 497 try:
jpayne@68 498 expires = int(time.time() + int(morsel["max-age"]))
jpayne@68 499 except ValueError:
jpayne@68 500 raise TypeError(f"max-age: {morsel['max-age']} must be integer")
jpayne@68 501 elif morsel["expires"]:
jpayne@68 502 time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
jpayne@68 503 expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
jpayne@68 504 return create_cookie(
jpayne@68 505 comment=morsel["comment"],
jpayne@68 506 comment_url=bool(morsel["comment"]),
jpayne@68 507 discard=False,
jpayne@68 508 domain=morsel["domain"],
jpayne@68 509 expires=expires,
jpayne@68 510 name=morsel.key,
jpayne@68 511 path=morsel["path"],
jpayne@68 512 port=None,
jpayne@68 513 rest={"HttpOnly": morsel["httponly"]},
jpayne@68 514 rfc2109=False,
jpayne@68 515 secure=bool(morsel["secure"]),
jpayne@68 516 value=morsel.value,
jpayne@68 517 version=morsel["version"] or 0,
jpayne@68 518 )
jpayne@68 519
jpayne@68 520
jpayne@68 521 def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):
jpayne@68 522 """Returns a CookieJar from a key/value dictionary.
jpayne@68 523
jpayne@68 524 :param cookie_dict: Dict of key/values to insert into CookieJar.
jpayne@68 525 :param cookiejar: (optional) A cookiejar to add the cookies to.
jpayne@68 526 :param overwrite: (optional) If False, will not replace cookies
jpayne@68 527 already in the jar with new ones.
jpayne@68 528 :rtype: CookieJar
jpayne@68 529 """
jpayne@68 530 if cookiejar is None:
jpayne@68 531 cookiejar = RequestsCookieJar()
jpayne@68 532
jpayne@68 533 if cookie_dict is not None:
jpayne@68 534 names_from_jar = [cookie.name for cookie in cookiejar]
jpayne@68 535 for name in cookie_dict:
jpayne@68 536 if overwrite or (name not in names_from_jar):
jpayne@68 537 cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
jpayne@68 538
jpayne@68 539 return cookiejar
jpayne@68 540
jpayne@68 541
jpayne@68 542 def merge_cookies(cookiejar, cookies):
jpayne@68 543 """Add cookies to cookiejar and returns a merged CookieJar.
jpayne@68 544
jpayne@68 545 :param cookiejar: CookieJar object to add the cookies to.
jpayne@68 546 :param cookies: Dictionary or CookieJar object to be added.
jpayne@68 547 :rtype: CookieJar
jpayne@68 548 """
jpayne@68 549 if not isinstance(cookiejar, cookielib.CookieJar):
jpayne@68 550 raise ValueError("You can only merge into CookieJar")
jpayne@68 551
jpayne@68 552 if isinstance(cookies, dict):
jpayne@68 553 cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
jpayne@68 554 elif isinstance(cookies, cookielib.CookieJar):
jpayne@68 555 try:
jpayne@68 556 cookiejar.update(cookies)
jpayne@68 557 except AttributeError:
jpayne@68 558 for cookie_in_jar in cookies:
jpayne@68 559 cookiejar.set_cookie(cookie_in_jar)
jpayne@68 560
jpayne@68 561 return cookiejar