# -*- coding: utf-8 -*-
from __future__ import absolute_import

"""
oauthlib.common
~~~~~~~~~~~~~~

This module provides data structures and utilities common
to all implementations of OAuth.
"""

from urlparse import parse_qsl, urlparse


def extract_params(raw):
    """Extract parameters and return them as a list of 2-tuples.

    Will successfully extract parameters from urlencoded query strings,
    dicts, or lists of 2-tuples. Empty strings/dicts/lists will return an
    empty list of parameters. Any other input will result in a return
    value of None.
    """
    if isinstance(raw, basestring):
        if len(raw) == 0:
            params = []  # short-circuit, strict parsing chokes on blank
        else:
            try:
                params = parse_qsl(raw, keep_blank_values=True, strict_parsing=True)
            except ValueError:
                params = None  # No parameters to see here, move along.
    elif hasattr(raw, '__iter__'):
        try:
            dict(raw)
        except ValueError:
            params = None
        except TypeError:
            params = None
        else:
            params = list(raw.items() if isinstance(raw, dict) else raw)
    else:
        params = None

    return params


class Request(object):
    """A malleable representation of a signable HTTP request.

    Body argument may contain any data, but parameters will only be decoded if
    they are one of:

    * urlencoded query string
    * dict
    * list of 2-tuples

    Anything else will be treated as raw body data to be passed through
    unmolested.
    """

    def __init__(self, uri, http_method=u'GET', body=None, headers=None):
        self.uri = uri
        self.http_method = http_method
        self.headers = headers or {}
        self.body = extract_params(body or [])
        if self.body == None:
            self.body = body
            self.body_has_params = False
        elif self.body == []:
            self.body_has_params = False
        else:
            self.body_has_params = True
        self.oauth_params = []

    @property
    def uri_query(self):
        return urlparse(self.uri).query

    @property
    def uri_query_params(self):
        return parse_qsl(self.uri_query, keep_blank_values=True,
                                  strict_parsing=True)

@@ -707,32 +707,174 @@
 k%0A        else:%0A
+            # FIXME how do we handle partly invalid param strings like %22c2&a3=2+q%22?%0A            # With strict_parsing it's all or nothing. :(%0A
             try:
@@ -881,32 +881,34 @@
 %0A               
+ #
  params = parse_
@@ -961,16 +961,80 @@
 g=True)%0A
+                params = parse_qsl(raw, keep_blank_values=True)%0A
         

Disable strict parsing when extracting parameters.