1
0
mirror of https://github.com/httpie/cli.git synced 2025-01-10 00:28:12 +02:00

Removed Python 2.6 support

* Travis CI doesn't support it anymore.
* It had EOL more than 4 years ago
This commit is contained in:
Jakub Roztocil 2017-12-28 18:03:13 +01:00
parent 4d3b4fa0be
commit ec899d70b7
8 changed files with 13 additions and 159 deletions

View File

@ -8,9 +8,12 @@ This project adheres to `Semantic Versioning <http://semver.org/>`_.
`1.0.0-dev`_ (unreleased) `1.0.0-dev`_ (unreleased)
------------------------- -------------------------
* Removed Python 2.6 support.
* ``--verify`` now accepts ``true``/``false`` in addition to ``yes``/``no`` * ``--verify`` now accepts ``true``/``false`` in addition to ``yes``/``no``
and the boolean value is case-insensitive. and the boolean value is case-insensitive.
`0.9.8`_ (2016-12-08) `0.9.8`_ (2016-12-08)
--------------------- ---------------------

View File

@ -41,7 +41,7 @@ Main features
* Custom headers * Custom headers
* Persistent sessions * Persistent sessions
* Wget-like downloads * Wget-like downloads
* Python 2.6, 2.7 and 3.x support * Python 2.7 and 3.x support
* Linux, macOS and Windows support * Linux, macOS and Windows support
* Plugins * Plugins
* Documentation * Documentation
@ -119,10 +119,10 @@ and always provides the latest version) is to use `pip`_:
Python version Python version
-------------- --------------
Although Python 2.6 and 2.7 are supported as well, it is recommended to install Although Python 2.7 is supported as well, it is strongly recommended to
HTTPie against the latest Python 3.x whenever possible. That will ensure that install HTTPie against the latest Python 3.x whenever possible. That will
some of the newer HTTP features, such as `SNI (Server Name Indication)`_, ensure that some of the newer HTTP features, such as
work out of the box. `SNI (Server Name Indication)`_, work out of the box.
Python 3 is the default for Homebrew installations starting with version 0.9.4. Python 3 is the default for Homebrew installations starting with version 0.9.4.
To see which version HTTPie uses, run ``http --debug``. To see which version HTTPie uses, run ``http --debug``.

View File

@ -1,12 +1,11 @@
""" """
Python 2.6, 2.7, and 3.x compatibility. Python 2.7, and 3.x compatibility.
""" """
import sys import sys
is_py2 = sys.version_info[0] == 2 is_py2 = sys.version_info[0] == 2
is_py26 = sys.version_info[:2] == (2, 6)
is_py27 = sys.version_info[:2] == (2, 7) is_py27 = sys.version_info[:2] == (2, 7)
is_py3 = sys.version_info[0] == 3 is_py3 = sys.version_info[0] == 3
is_pypy = 'pypy' in sys.version.lower() is_pypy = 'pypy' in sys.version.lower()
@ -38,141 +37,3 @@ try: # pragma: no cover
except ImportError: # pragma: no cover except ImportError: # pragma: no cover
# noinspection PyCompatibility,PyUnresolvedReferences # noinspection PyCompatibility,PyUnresolvedReferences
from urllib2 import urlopen from urllib2 import urlopen
try: # pragma: no cover
from collections import OrderedDict
except ImportError: # pragma: no cover
# Python 2.6 OrderedDict class, needed for headers, parameters, etc .###
# <https://pypi.python.org/pypi/ordereddict/1.1>
# noinspection PyCompatibility,PyUnresolvedReferences
from UserDict import DictMixin
# noinspection PyShadowingBuiltins,PyCompatibility
class OrderedDict(dict, DictMixin):
# Copyright (c) 2009 Raymond Hettinger
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# noinspection PyMissingConstructor
def __init__(self, *args, **kwds):
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d'
% len(args))
try:
self.__end
except AttributeError:
self.clear()
self.update(*args, **kwds)
def clear(self):
self.__end = end = []
# noinspection PyUnusedLocal
end += [None, end, end] # sentinel node for doubly linked list
self.__map = {} # key --> [key, prev, next]
dict.clear(self)
def __setitem__(self, key, value):
if key not in self:
end = self.__end
curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end]
dict.__setitem__(self, key, value)
def __delitem__(self, key):
dict.__delitem__(self, key)
key, prev, next = self.__map.pop(key)
prev[2] = next
next[1] = prev
def __iter__(self):
end = self.__end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.__end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def popitem(self, last=True):
if not self:
raise KeyError('dictionary is empty')
if last:
# noinspection PyUnresolvedReferences
key = reversed(self).next()
else:
key = iter(self).next()
value = self.pop(key)
return key, value
def __reduce__(self):
items = [[k, self[k]] for k in self]
tmp = self.__map, self.__end
del self.__map, self.__end
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return self.__class__, (items,), inst_dict
return self.__class__, (items,)
def keys(self):
return list(self)
setdefault = DictMixin.setdefault
update = DictMixin.update
pop = DictMixin.pop
values = DictMixin.values
items = DictMixin.items
iterkeys = DictMixin.iterkeys
itervalues = DictMixin.itervalues
iteritems = DictMixin.iteritems
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
def copy(self):
return self.__class__(self)
# noinspection PyMethodOverriding
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
if isinstance(other, OrderedDict):
if len(self) != len(other):
return False
for p, q in zip(self.items(), other.items()):
if p != q:
return False
return True
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other

View File

@ -9,7 +9,7 @@ import errno
import mimetypes import mimetypes
import getpass import getpass
from io import BytesIO from io import BytesIO
from collections import namedtuple, Iterable from collections import namedtuple, Iterable, OrderedDict
# noinspection PyCompatibility # noinspection PyCompatibility
from argparse import ArgumentParser, ArgumentTypeError, ArgumentError from argparse import ArgumentParser, ArgumentTypeError, ArgumentError
@ -18,7 +18,7 @@ from argparse import ArgumentParser, ArgumentTypeError, ArgumentError
from httpie.plugins import plugin_manager from httpie.plugins import plugin_manager
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
from httpie.compat import OrderedDict, urlsplit, str, is_pypy, is_py27 from httpie.compat import urlsplit, str, is_pypy, is_py27
from httpie.sessions import VALID_SESSION_NAME_PATTERN from httpie.sessions import VALID_SESSION_NAME_PATTERN
from httpie.utils import load_json_preserve_order from httpie.utils import load_json_preserve_order

View File

@ -1,12 +1,9 @@
from __future__ import division from __future__ import division
import json import json
from collections import OrderedDict
from httpie.compat import is_py26, OrderedDict
def load_json_preserve_order(s): def load_json_preserve_order(s):
if is_py26:
return json.loads(s)
return json.loads(s, object_pairs_hook=OrderedDict) return json.loads(s, object_pairs_hook=OrderedDict)

View File

@ -93,8 +93,6 @@ setup(
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.1',

View File

@ -6,7 +6,6 @@ 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
def test_debug(): def test_debug():
@ -107,10 +106,6 @@ def test_headers_empty_value_with_value_gives_error(httpbin):
http('GET', httpbin + '/headers', 'Accept;SYNTAX_ERROR') http('GET', httpbin + '/headers', 'Accept;SYNTAX_ERROR')
@pytest.mark.skipif(
is_py26,
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'
)
def test_json_input_preserve_order(httpbin_both): def test_json_input_preserve_order(httpbin_both):
r = http('PATCH', httpbin_both + '/patch', r = http('PATCH', httpbin_both + '/patch',
'order:={"map":{"1":"first","2":"second"}}') 'order:={"map":{"1":"first","2":"second"}}')

View File

@ -3,7 +3,7 @@
[tox] [tox]
envlist = py26, py27, py35, py36, pypy, codestyle envlist = py27, py35, py36, pypy, codestyle
[testenv] [testenv]