Work around missing object_pairs_hook in Python 2.6

This commit is contained in:
Jakub Roztocil 2015-01-23 22:04:42 +01:00
parent 22c993bab8
commit 25b1be7c8a
4 changed files with 32 additions and 14 deletions

View File

@ -3,28 +3,28 @@ Python 2.6, 2.7, and 3.x compatibility.
""" """
# Borrow these from requests: # Borrow these from requests:
#noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from requests.compat import is_windows, bytes, str, is_py3, is_py26 from requests.compat import is_windows, bytes, str, is_py3, is_py26
try: try:
#noinspection PyUnresolvedReferences,PyCompatibility # noinspection PyUnresolvedReferences,PyCompatibility
from urllib.parse import urlsplit from urllib.parse import urlsplit
except ImportError: except ImportError:
#noinspection PyUnresolvedReferences,PyCompatibility # noinspection PyUnresolvedReferences,PyCompatibility
from urlparse import urlsplit from urlparse import urlsplit
try: try:
#noinspection PyCompatibility # noinspection PyCompatibility
from urllib.request import urlopen from urllib.request import urlopen
except ImportError: except ImportError:
#noinspection PyCompatibility # noinspection PyCompatibility
from urllib2 import urlopen from urllib2 import urlopen
try: try:
from collections import OrderedDict from collections import OrderedDict
except ImportError: except ImportError:
### Python 2.6 OrderedDict class, needed for headers, parameters, etc .### # Python 2.6 OrderedDict class, needed for headers, parameters, etc .###
### <https://pypi.python.org/pypi/ordereddict/1.1> # <https://pypi.python.org/pypi/ordereddict/1.1>
# noinspection PyCompatibility # noinspection PyCompatibility
from UserDict import DictMixin from UserDict import DictMixin

View File

@ -4,13 +4,12 @@
import os import os
import sys import sys
import re import re
import json
import errno import errno
import mimetypes import mimetypes
import getpass import getpass
from io import BytesIO from io import BytesIO
from collections import namedtuple from collections import namedtuple
#noinspection PyCompatibility # noinspection PyCompatibility
from argparse import ArgumentParser, ArgumentTypeError, ArgumentError from argparse import ArgumentParser, ArgumentTypeError, ArgumentError
# TODO: Use MultiDict for headers once added to `requests`. # TODO: Use MultiDict for headers once added to `requests`.
@ -19,6 +18,7 @@ from requests.structures import CaseInsensitiveDict
from httpie.compat import OrderedDict, urlsplit, str from httpie.compat import OrderedDict, urlsplit, str
from httpie.sessions import VALID_SESSION_NAME_PATTERN from httpie.sessions import VALID_SESSION_NAME_PATTERN
from httpie.utils import load_json_preserve_order
HTTP_POST = 'POST' HTTP_POST = 'POST'
@ -111,7 +111,7 @@ class Parser(ArgumentParser):
kwargs['add_help'] = False kwargs['add_help'] = False
super(Parser, self).__init__(*args, **kwargs) super(Parser, self).__init__(*args, **kwargs)
#noinspection PyMethodOverriding # noinspection PyMethodOverriding
def parse_args(self, env, args=None, namespace=None): def parse_args(self, env, args=None, namespace=None):
self.env = env self.env = env
@ -640,7 +640,7 @@ def parse_items(items,
if item.sep in SEP_GROUP_RAW_JSON_ITEMS: if item.sep in SEP_GROUP_RAW_JSON_ITEMS:
try: try:
value = json.loads(value, object_pairs_hook=OrderedDict) value = load_json_preserve_order(value)
except ValueError as e: except ValueError as e:
raise ParseError('"%s": %s' % (item.orig, e)) raise ParseError('"%s": %s' % (item.orig, e))
target = data target = data

View File

@ -1,4 +1,13 @@
from __future__ import division from __future__ import division
import json
from httpie.compat import is_py26, OrderedDict
def load_json_preserve_order(s):
if is_py26:
return json.loads(s)
return json.loads(s, object_pairs_hook=OrderedDict)
def humanize_bytes(n, precision=2): def humanize_bytes(n, precision=2):

View File

@ -1,7 +1,10 @@
"""High-level tests.""" """High-level tests."""
import pytest
from utils import TestEnvironment, http, HTTP_OK from utils import TestEnvironment, http, HTTP_OK
from fixtures import FILE_PATH, FILE_CONTENT from fixtures import FILE_PATH, FILE_CONTENT
import httpie import httpie
from httpie.compat import is_py26
class TestHTTPie: class TestHTTPie:
@ -64,7 +67,13 @@ class TestHTTPie:
assert '"User-Agent": "HTTPie' in r, r assert '"User-Agent": "HTTPie' in r, r
assert '"Foo": "bar"' in r assert '"Foo": "bar"' in r
def test_json_order(self, httpbin): @pytest.mark.skipif(
r = http('PATCH', httpbin.url + '/patch', 'order:={"map":{"1":"first","2":"second"}}') is_py26,
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'
)
def test_json_input_preserve_order(self, httpbin):
r = http('PATCH', httpbin.url + '/patch',
'order:={"map":{"1":"first","2":"second"}}')
assert HTTP_OK in r assert HTTP_OK in r
assert r.json['data'] == '{"order": {"map": {"1": "first", "2": "second"}}}' assert r.json['data'] == \
'{"order": {"map": {"1": "first", "2": "second"}}}'