From b3d2c1876e23e7de7afe588e4f64160d17201b45 Mon Sep 17 00:00:00 2001 From: Jakub Roztocil Date: Thu, 29 Aug 2019 08:53:56 +0200 Subject: [PATCH] Python 2.7 support removal WIP --- .travis.yml | 20 +------------------- README.rst | 30 ++---------------------------- httpie/__init__.py | 2 +- httpie/client.py | 1 - httpie/compat.py | 35 ----------------------------------- httpie/core.py | 3 +-- httpie/downloads.py | 2 +- httpie/input.py | 14 ++------------ httpie/models.py | 2 +- httpie/output/streams.py | 1 - httpie/sessions.py | 2 +- setup.py | 8 ++------ tests/test_downloads.py | 2 +- tests/test_output.py | 2 +- tests/test_ssl.py | 1 - tests/utils.py | 1 - tox.ini | 7 +------ 17 files changed, 15 insertions(+), 118 deletions(-) diff --git a/.travis.yml b/.travis.yml index d340af99..33e85b25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,15 +7,12 @@ env: global: - NEWEST_PYTHON=3.7 python: - # - - 2.7 # Python 3.4 fails installing packages # # - 3.4 - 3.5 - 3.6 # - 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 @@ -23,23 +20,8 @@ cache: pip matrix: include: - # Manually defined macOS builds + # Manually defined macOS build # - - # FIXME: stock macOS python fails with InterpreterNotFound - # - # - 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 language: generic env: diff --git a/README.rst b/README.rst index baf1323d..5f7a6da3 100644 --- a/README.rst +++ b/README.rst @@ -47,7 +47,6 @@ Main features * Custom headers * Persistent sessions * Wget-like downloads -* Python 2.7 and 3.x support * Linux, macOS and Windows support * Plugins * Documentation @@ -125,12 +124,7 @@ and always provides the latest version) is to use `pip`_: Python version -------------- -Although Python 2.7 is supported as well, it is strongly recommended to -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``. +Starting with version 2.0.0 (currently under development) Python 3.x is required. Unstable version @@ -945,26 +939,6 @@ available set of protocols may vary depending on your OpenSSL installation.) $ 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 ============== @@ -1755,4 +1729,4 @@ have contributed. .. |downloads| image:: https://pepy.tech/badge/httpie :target: https://pepy.tech/project/httpie :alt: Download count - + diff --git a/httpie/__init__.py b/httpie/__init__.py index 121cc76d..6b28eeef 100644 --- a/httpie/__init__.py +++ b/httpie/__init__.py @@ -2,7 +2,7 @@ HTTPie - a CLI, cURL-like tool for humans. """ -__version__ = '1.0.3' +__version__ = '2.0.0-dev' __author__ = 'Jakub Roztocil' __licence__ = 'BSD' diff --git a/httpie/client.py b/httpie/client.py index 21a7f67a..91677ea8 100644 --- a/httpie/client.py +++ b/httpie/client.py @@ -7,7 +7,6 @@ from requests.structures import CaseInsensitiveDict from httpie import sessions from httpie import __version__ -from httpie.compat import str from httpie.input import SSL_VERSION_ARG_MAPPING from httpie.plugins import plugin_manager from httpie.utils import repr_dict_nice diff --git a/httpie/compat.py b/httpie/compat.py index d81e508b..f508bbb3 100644 --- a/httpie/compat.py +++ b/httpie/compat.py @@ -1,39 +1,4 @@ -""" -Python 2.7, and 3.x compatibility. - -""" 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() - - -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 diff --git a/httpie/core.py b/httpie/core.py index 8ad0e2a6..fb3d9662 100644 --- a/httpie/core.py +++ b/httpie/core.py @@ -19,7 +19,6 @@ from requests import __version__ as requests_version from pygments import __version__ as pygments_version from httpie import __version__ as httpie_version, ExitStatus -from httpie.compat import str, bytes, is_py3 from httpie.client import get_response from httpie.downloads import Downloader from httpie.context import Environment @@ -132,7 +131,7 @@ def program(args, env, log_error): 'flush': env.stdout_isatty or args.stream } 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) else: write_stream(**write_stream_kwargs) diff --git a/httpie/downloads.py b/httpie/downloads.py index 9f4c761f..839869ca 100644 --- a/httpie/downloads.py +++ b/httpie/downloads.py @@ -12,11 +12,11 @@ import mimetypes import threading from time import sleep, time from mailbox import Message +from urllib.parse import urlsplit from httpie.output.streams import RawStream from httpie.models import HTTPResponse from httpie.utils import humanize_bytes -from httpie.compat import urlsplit PARTIAL_CONTENT = 206 diff --git a/httpie/input.py b/httpie/input.py index 1ab34c9b..53b9924a 100644 --- a/httpie/input.py +++ b/httpie/input.py @@ -15,10 +15,11 @@ from argparse import ArgumentParser, ArgumentTypeError, ArgumentError # TODO: Use MultiDict for headers once added to `requests`. # https://github.com/jakubroztocil/httpie/issues/130 +from urllib.parse import urlsplit + from httpie.plugins import plugin_manager 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.utils import load_json_preserve_order @@ -615,17 +616,6 @@ parse_auth = AuthCredentialsArgType(SEP_CREDENTIALS) class RequestItemsDict(OrderedDict): """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 def __setitem__(self, key, value): """ If `key` is assigned more than once, `self[key]` holds a diff --git a/httpie/models.py b/httpie/models.py index ef359431..52174859 100644 --- a/httpie/models.py +++ b/httpie/models.py @@ -1,4 +1,4 @@ -from httpie.compat import urlsplit, str +from urllib.parse import urlsplit class HTTPMessage(object): diff --git a/httpie/output/streams.py b/httpie/output/streams.py index 3483a6d3..6f0d5620 100644 --- a/httpie/output/streams.py +++ b/httpie/output/streams.py @@ -1,7 +1,6 @@ from itertools import chain from functools import partial -from httpie.compat import str from httpie.context import Environment from httpie.models import HTTPRequest, HTTPResponse from httpie.input import (OUT_REQ_BODY, OUT_REQ_HEAD, diff --git a/httpie/sessions.py b/httpie/sessions.py index 56614f20..0971eac0 100644 --- a/httpie/sessions.py +++ b/httpie/sessions.py @@ -3,10 +3,10 @@ """ import re import os +from urllib.parse import urlsplit from requests.cookies import RequestsCookieJar, create_cookie -from httpie.compat import urlsplit from httpie.config import BaseConfigDict, DEFAULT_CONFIG_DIR from httpie.plugins import plugin_manager diff --git a/setup.py b/setup.py index bb304288..0914da1f 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ from setuptools import setup, find_packages from setuptools.command.test import test as TestCommand import httpie -from httpie.compat import is_py27 class PyTest(TestCommand): @@ -34,9 +33,6 @@ tests_require = [ 'mock', ] -if is_py27: - tests_require.append('pyOpenSSL') - install_requires = [ 'requests>=2.21.0', @@ -77,7 +73,7 @@ setup( version=httpie.__version__, description=httpie.__doc__.strip(), long_description=long_description(), - url='http://httpie.org/', + url='https://httpie.org/', download_url='https://github.com/jakubroztocil/httpie', author=httpie.__author__, author_email='jakub@roztocil.co', @@ -95,7 +91,6 @@ setup( classifiers=[ 'Development Status :: 5 - Production/Stable', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.2', @@ -103,6 +98,7 @@ setup( 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Environment :: Console', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', diff --git a/tests/test_downloads.py b/tests/test_downloads.py index e14fcef3..ac5dbc1a 100644 --- a/tests/test_downloads.py +++ b/tests/test_downloads.py @@ -1,12 +1,12 @@ import os import tempfile import time +from urllib.request import urlopen import pytest import mock from requests.structures import CaseInsensitiveDict -from httpie.compat import urlopen from httpie.downloads import ( parse_content_range, filename_from_content_disposition, filename_from_url, get_unique_filename, ContentRangeError, Downloader, diff --git a/tests/test_output.py b/tests/test_output.py index 26cbae96..8bdfa572 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -1,11 +1,11 @@ import os from tempfile import gettempdir +from urllib.request import urlopen import pytest from utils import MockEnvironment, http, HTTP_OK, COLOR, CRLF from httpie import ExitStatus -from httpie.compat import urlopen from httpie.output.formatters.colors import get_lexer diff --git a/tests/test_ssl.py b/tests/test_ssl.py index d4227d1e..607c4726 100644 --- a/tests/test_ssl.py +++ b/tests/test_ssl.py @@ -5,7 +5,6 @@ import pytest_httpbin.certs import requests.exceptions from httpie import ExitStatus -from httpie.compat import is_pypy from httpie.input import SSL_VERSION_ARG_MAPPING from utils import HTTP_OK, TESTS_ROOT, http diff --git a/tests/utils.py b/tests/utils.py index 23bca713..d51f8cb9 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,7 +9,6 @@ import tempfile from httpie import ExitStatus, EXIT_STATUS_LABELS from httpie.context import Environment from httpie.core import main -from httpie.compat import bytes, str TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) diff --git a/tox.ini b/tox.ini index 7bbbd0d5..d44bce8f 100644 --- a/tox.ini +++ b/tox.ini @@ -4,16 +4,14 @@ [tox] # pypy3 currently fails because of a Flask issue -envlist = py27, py37, pypy +envlist = py37 [testenv] -# pyOpenSSL only needed for Python 2.7 deps = mock pytest pytest-httpbin>=0.0.6 - pyOpenSSL commands = @@ -23,6 +21,3 @@ commands = --verbose \ --doctest-modules \ {posargs:./httpie ./tests} - -[testenv:py27-osx-builtin] -basepython = /usr/bin/python2.7