Python 2.7 support removal WIP

This commit is contained in:
Jakub Roztocil 2019-08-29 08:53:56 +02:00
parent c297af0012
commit b3d2c1876e
17 changed files with 15 additions and 118 deletions

View File

@ -7,15 +7,12 @@ env:
global: global:
- NEWEST_PYTHON=3.7 - NEWEST_PYTHON=3.7
python: python:
# <https://docs.travis-ci.com/user/languages/python/>
- 2.7
# Python 3.4 fails installing packages # Python 3.4 fails installing packages
# <https://travis-ci.org/jakubroztocil/httpie/jobs/403263566#L636> # <https://travis-ci.org/jakubroztocil/httpie/jobs/403263566#L636>
# - 3.4 # - 3.4
- 3.5 - 3.5
- 3.6 - 3.6
# - 3.7 # is done in the matrix below as described in travis-ci/travis-ci#9069 # - 3.7 # is done in the matrix below as described in travis-ci/travis-ci#9069
- pypy
# pypy3 currently fails because of a Flask issue # pypy3 currently fails because of a Flask issue
# - pypy3 # - pypy3
@ -23,23 +20,8 @@ cache: pip
matrix: matrix:
include: include:
# Manually defined macOS builds # Manually defined macOS build
# <https://docs.travis-ci.com/user/multi-os/#Python-example-(unsupported-languages)> # <https://docs.travis-ci.com/user/multi-os/#Python-example-(unsupported-languages)>
# FIXME: stock macOS python fails with InterpreterNotFound
# <https://travis-ci.org/jakubroztocil/httpie/jobs/578189209>
# - os: osx
# language: generic
# env:
# # Stock macOS Python
# - TOXENV=py27-osx-builtin
# - BREW_PYTHON_PACKAGE=
- os: osx
language: generic
env:
# Latest Python 2.7 from Homebrew
- TOXENV=py27
- BREW_PYTHON_PACKAGE=python@2
- os: osx - os: osx
language: generic language: generic
env: env:

View File

@ -47,7 +47,6 @@ Main features
* Custom headers * Custom headers
* Persistent sessions * Persistent sessions
* Wget-like downloads * Wget-like downloads
* Python 2.7 and 3.x support
* Linux, macOS and Windows support * Linux, macOS and Windows support
* Plugins * Plugins
* Documentation * Documentation
@ -125,12 +124,7 @@ and always provides the latest version) is to use `pip`_:
Python version Python version
-------------- --------------
Although Python 2.7 is supported as well, it is strongly recommended to Starting with version 2.0.0 (currently under development) Python 3.x is required.
install HTTPie against the latest Python 3.x whenever possible. That will
ensure that some of the newer HTTP features, such as
`SNI (Server Name Indication)`_, work out of the box.
Python 3 is the default for Homebrew installations starting with version 0.9.4.
To see which version HTTPie uses, run ``http --debug``.
Unstable version Unstable version
@ -945,26 +939,6 @@ available set of protocols may vary depending on your OpenSSL installation.)
$ http --ssl=ssl3 https://vulnerable.example.org $ http --ssl=ssl3 https://vulnerable.example.org
SNI (Server Name Indication)
----------------------------
If you use HTTPie with `Python version`_ lower than 2.7.9
(can be verified with ``http --debug``) and need to talk to servers that
use SNI (Server Name Indication) you need to install some additional
dependencies:
.. code-block:: bash
$ pip install --upgrade requests[security]
You can use the following command to test SNI support:
.. code-block:: bash
$ http https://sni.velox.ch
Output options Output options
============== ==============
@ -1755,4 +1729,4 @@ have contributed.
.. |downloads| image:: https://pepy.tech/badge/httpie .. |downloads| image:: https://pepy.tech/badge/httpie
:target: https://pepy.tech/project/httpie :target: https://pepy.tech/project/httpie
:alt: Download count :alt: Download count

View File

@ -2,7 +2,7 @@
HTTPie - a CLI, cURL-like tool for humans. HTTPie - a CLI, cURL-like tool for humans.
""" """
__version__ = '1.0.3' __version__ = '2.0.0-dev'
__author__ = 'Jakub Roztocil' __author__ = 'Jakub Roztocil'
__licence__ = 'BSD' __licence__ = 'BSD'

View File

@ -7,7 +7,6 @@ from requests.structures import CaseInsensitiveDict
from httpie import sessions from httpie import sessions
from httpie import __version__ from httpie import __version__
from httpie.compat import str
from httpie.input import SSL_VERSION_ARG_MAPPING from httpie.input import SSL_VERSION_ARG_MAPPING
from httpie.plugins import plugin_manager from httpie.plugins import plugin_manager
from httpie.utils import repr_dict_nice from httpie.utils import repr_dict_nice

View File

@ -1,39 +1,4 @@
"""
Python 2.7, and 3.x compatibility.
"""
import sys import sys
is_py2 = sys.version_info[0] == 2
is_py27 = sys.version_info[:2] == (2, 7)
is_py3 = sys.version_info[0] == 3
is_pypy = 'pypy' in sys.version.lower()
is_windows = 'win32' in str(sys.platform).lower() is_windows = 'win32' in str(sys.platform).lower()
if is_py2:
# noinspection PyShadowingBuiltins
bytes = str
# noinspection PyUnresolvedReferences,PyShadowingBuiltins
str = unicode
elif is_py3:
# noinspection PyShadowingBuiltins
str = str
# noinspection PyShadowingBuiltins
bytes = bytes
try: # pragma: no cover
# noinspection PyUnresolvedReferences,PyCompatibility
from urllib.parse import urlsplit
except ImportError: # pragma: no cover
# noinspection PyUnresolvedReferences,PyCompatibility
from urlparse import urlsplit
try: # pragma: no cover
# noinspection PyCompatibility
from urllib.request import urlopen
except ImportError: # pragma: no cover
# noinspection PyCompatibility,PyUnresolvedReferences
from urllib2 import urlopen

View File

@ -19,7 +19,6 @@ from requests import __version__ as requests_version
from pygments import __version__ as pygments_version from pygments import __version__ as pygments_version
from httpie import __version__ as httpie_version, ExitStatus from httpie import __version__ as httpie_version, ExitStatus
from httpie.compat import str, bytes, is_py3
from httpie.client import get_response from httpie.client import get_response
from httpie.downloads import Downloader from httpie.downloads import Downloader
from httpie.context import Environment from httpie.context import Environment
@ -132,7 +131,7 @@ def program(args, env, log_error):
'flush': env.stdout_isatty or args.stream 'flush': env.stdout_isatty or args.stream
} }
try: try:
if env.is_windows and is_py3 and 'colors' in args.prettify: if env.is_windows and 'colors' in args.prettify:
write_stream_with_colors_win_py3(**write_stream_kwargs) write_stream_with_colors_win_py3(**write_stream_kwargs)
else: else:
write_stream(**write_stream_kwargs) write_stream(**write_stream_kwargs)

View File

@ -12,11 +12,11 @@ import mimetypes
import threading import threading
from time import sleep, time from time import sleep, time
from mailbox import Message from mailbox import Message
from urllib.parse import urlsplit
from httpie.output.streams import RawStream from httpie.output.streams import RawStream
from httpie.models import HTTPResponse from httpie.models import HTTPResponse
from httpie.utils import humanize_bytes from httpie.utils import humanize_bytes
from httpie.compat import urlsplit
PARTIAL_CONTENT = 206 PARTIAL_CONTENT = 206

View File

@ -15,10 +15,11 @@ from argparse import ArgumentParser, ArgumentTypeError, ArgumentError
# TODO: Use MultiDict for headers once added to `requests`. # TODO: Use MultiDict for headers once added to `requests`.
# https://github.com/jakubroztocil/httpie/issues/130 # https://github.com/jakubroztocil/httpie/issues/130
from urllib.parse import urlsplit
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 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
@ -615,17 +616,6 @@ parse_auth = AuthCredentialsArgType(SEP_CREDENTIALS)
class RequestItemsDict(OrderedDict): class RequestItemsDict(OrderedDict):
"""Multi-value dict for URL parameters and form data.""" """Multi-value dict for URL parameters and form data."""
if is_pypy and is_py27:
# Manually set keys when initialized with an iterable as PyPy
# doesn't call __setitem__ in such case (pypy3 does).
def __init__(self, *args, **kwargs):
if len(args) == 1 and isinstance(args[0], Iterable):
super(RequestItemsDict, self).__init__(**kwargs)
for k, v in args[0]:
self[k] = v
else:
super(RequestItemsDict, self).__init__(*args, **kwargs)
# noinspection PyMethodOverriding # noinspection PyMethodOverriding
def __setitem__(self, key, value): def __setitem__(self, key, value):
""" If `key` is assigned more than once, `self[key]` holds a """ If `key` is assigned more than once, `self[key]` holds a

View File

@ -1,4 +1,4 @@
from httpie.compat import urlsplit, str from urllib.parse import urlsplit
class HTTPMessage(object): class HTTPMessage(object):

View File

@ -1,7 +1,6 @@
from itertools import chain from itertools import chain
from functools import partial from functools import partial
from httpie.compat import str
from httpie.context import Environment from httpie.context import Environment
from httpie.models import HTTPRequest, HTTPResponse from httpie.models import HTTPRequest, HTTPResponse
from httpie.input import (OUT_REQ_BODY, OUT_REQ_HEAD, from httpie.input import (OUT_REQ_BODY, OUT_REQ_HEAD,

View File

@ -3,10 +3,10 @@
""" """
import re import re
import os import os
from urllib.parse import urlsplit
from requests.cookies import RequestsCookieJar, create_cookie from requests.cookies import RequestsCookieJar, create_cookie
from httpie.compat import urlsplit
from httpie.config import BaseConfigDict, DEFAULT_CONFIG_DIR from httpie.config import BaseConfigDict, DEFAULT_CONFIG_DIR
from httpie.plugins import plugin_manager from httpie.plugins import plugin_manager

View File

@ -7,7 +7,6 @@ from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
import httpie import httpie
from httpie.compat import is_py27
class PyTest(TestCommand): class PyTest(TestCommand):
@ -34,9 +33,6 @@ tests_require = [
'mock', 'mock',
] ]
if is_py27:
tests_require.append('pyOpenSSL')
install_requires = [ install_requires = [
'requests>=2.21.0', 'requests>=2.21.0',
@ -77,7 +73,7 @@ setup(
version=httpie.__version__, version=httpie.__version__,
description=httpie.__doc__.strip(), description=httpie.__doc__.strip(),
long_description=long_description(), long_description=long_description(),
url='http://httpie.org/', url='https://httpie.org/',
download_url='https://github.com/jakubroztocil/httpie', download_url='https://github.com/jakubroztocil/httpie',
author=httpie.__author__, author=httpie.__author__,
author_email='jakub@roztocil.co', author_email='jakub@roztocil.co',
@ -95,7 +91,6 @@ setup(
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.2',
@ -103,6 +98,7 @@ setup(
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Environment :: Console', 'Environment :: Console',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'Intended Audience :: System Administrators', 'Intended Audience :: System Administrators',

View File

@ -1,12 +1,12 @@
import os import os
import tempfile import tempfile
import time import time
from urllib.request import urlopen
import pytest import pytest
import mock import mock
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
from httpie.compat import urlopen
from httpie.downloads import ( from httpie.downloads import (
parse_content_range, filename_from_content_disposition, filename_from_url, parse_content_range, filename_from_content_disposition, filename_from_url,
get_unique_filename, ContentRangeError, Downloader, get_unique_filename, ContentRangeError, Downloader,

View File

@ -1,11 +1,11 @@
import os import os
from tempfile import gettempdir from tempfile import gettempdir
from urllib.request import urlopen
import pytest import pytest
from utils import MockEnvironment, http, HTTP_OK, COLOR, CRLF from utils import MockEnvironment, http, HTTP_OK, COLOR, CRLF
from httpie import ExitStatus from httpie import ExitStatus
from httpie.compat import urlopen
from httpie.output.formatters.colors import get_lexer from httpie.output.formatters.colors import get_lexer

View File

@ -5,7 +5,6 @@ import pytest_httpbin.certs
import requests.exceptions import requests.exceptions
from httpie import ExitStatus from httpie import ExitStatus
from httpie.compat import is_pypy
from httpie.input import SSL_VERSION_ARG_MAPPING from httpie.input import SSL_VERSION_ARG_MAPPING
from utils import HTTP_OK, TESTS_ROOT, http from utils import HTTP_OK, TESTS_ROOT, http

View File

@ -9,7 +9,6 @@ import tempfile
from httpie import ExitStatus, EXIT_STATUS_LABELS from httpie import ExitStatus, EXIT_STATUS_LABELS
from httpie.context import Environment from httpie.context import Environment
from httpie.core import main from httpie.core import main
from httpie.compat import bytes, str
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))

View File

@ -4,16 +4,14 @@
[tox] [tox]
# pypy3 currently fails because of a Flask issue # pypy3 currently fails because of a Flask issue
envlist = py27, py37, pypy envlist = py37
[testenv] [testenv]
# pyOpenSSL only needed for Python 2.7
deps = deps =
mock mock
pytest pytest
pytest-httpbin>=0.0.6 pytest-httpbin>=0.0.6
pyOpenSSL
commands = commands =
@ -23,6 +21,3 @@ commands =
--verbose \ --verbose \
--doctest-modules \ --doctest-modules \
{posargs:./httpie ./tests} {posargs:./httpie ./tests}
[testenv:py27-osx-builtin]
basepython = /usr/bin/python2.7