Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for running with 3.4 #6592

Merged
merged 4 commits into from Mar 27, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions .travis.yml
Expand Up @@ -14,9 +14,6 @@ env:

jobs:
include:
- name: "run test suite with python 3.4"
python: 3.4
dist: trusty
# Specifically request 3.5.1 because we need to be compatible with that.
- name: "run test suite with python 3.5.1"
python: 3.5.1
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -64,7 +64,7 @@ See 'Development status' below.
Requirements
------------

You need Python 3.4 or later to run mypy. You can have multiple Python
You need Python 3.5 or later to run mypy. You can have multiple Python
versions (2.x and 3.x) installed on the same system without problems.

In Ubuntu, Mint and Debian you can install Python 3 like this:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/common_issues.rst
Expand Up @@ -14,7 +14,7 @@ Can't install mypy using pip

If installation fails, you've probably hit one of these issues:

* Mypy needs Python 3.4 or later to run.
* Mypy needs Python 3.5 or later to run.
* You may have to run pip like this:
``python3 -m pip install mypy``.

Expand Down
2 changes: 1 addition & 1 deletion docs/source/getting_started.rst
Expand Up @@ -12,7 +12,7 @@ may not make much sense otherwise.
Installing and running mypy
***************************

Mypy requires Python 3.4 or later to run. Once you've
Mypy requires Python 3.5 or later to run. Once you've
`installed Python 3 <https://www.python.org/downloads/>`_,
install mypy using pip:

Expand Down
2 changes: 1 addition & 1 deletion mypy/dmypy_server.py
Expand Up @@ -14,6 +14,7 @@
import sys
import time
import traceback
from contextlib import redirect_stderr, redirect_stdout

from typing import AbstractSet, Any, Callable, Dict, List, Mapping, Optional, Sequence, Tuple

Expand All @@ -30,7 +31,6 @@
from mypy.options import Options
from mypy.suggestions import SuggestionFailure, SuggestionEngine
from mypy.typestate import reset_global_state
from mypy.util import redirect_stderr, redirect_stdout
from mypy.version import __version__


Expand Down
6 changes: 3 additions & 3 deletions mypy/main.py
Expand Up @@ -54,9 +54,9 @@ def main(script_path: Optional[str], args: Optional[List[str]] = None) -> None:
be used.
"""
# Check for known bad Python versions.
if sys.version_info[:2] < (3, 4):
sys.exit("Running mypy with Python 3.3 or lower is not supported; "
"please upgrade to 3.4 or newer")
if sys.version_info[:2] < (3, 5):
sys.exit("Running mypy with Python 3.4 or lower is not supported; "
"please upgrade to 3.5 or newer")
if sys.version_info[:3] == (3, 5, 0):
sys.exit("Running mypy with Python 3.5.0 is not supported; "
"please upgrade to 3.5.1 or newer")
Expand Down
18 changes: 0 additions & 18 deletions mypy/test/helpers.py
Expand Up @@ -397,24 +397,6 @@ def split_lines(*streams: bytes) -> List[str]:
]


def run_command(cmdline: List[str], *, env: Optional[Dict[str, str]] = None,
timeout: int = 300, cwd: str = test_temp_dir) -> Tuple[int, List[str]]:
"""A poor man's subprocess.run() for 3.4 compatibility."""
process = subprocess.Popen(
cmdline,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=cwd,
)
try:
out, err = process.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
out = err = b''
process.kill()
return process.returncode, split_lines(out, err)


def copy_and_fudge_mtime(source_path: str, target_path: str) -> None:
# In some systems, mtime has a resolution of 1 second which can
# cause annoying-to-debug issues when a file has the same size
Expand Down
23 changes: 12 additions & 11 deletions mypy/test/testpep561.py
@@ -1,6 +1,8 @@
from contextlib import contextmanager
from enum import Enum
import os
import subprocess
from subprocess import PIPE
import sys
import tempfile
from typing import Tuple, List, Generator, Optional
Expand All @@ -9,7 +11,6 @@
import mypy.api
from mypy.modulefinder import get_site_packages_dirs
from mypy.test.config import package_path
from mypy.test.helpers import run_command
from mypy.util import try_find_python2_interpreter

# NOTE: options.use_builtins_fixtures should not be set in these
Expand Down Expand Up @@ -135,13 +136,13 @@ def virtualenv(self,
# Sadly, we need virtualenv, as the Python 3 venv module does not support creating a venv
# for Python 2, and Python 2 does not have its own venv.
with tempfile.TemporaryDirectory() as venv_dir:
returncode, lines = run_command([sys.executable,
'-m',
'virtualenv',
'-p{}'.format(python_executable),
venv_dir], cwd=os.getcwd())
if returncode != 0:
err = '\n'.join(lines)
proc = subprocess.run([sys.executable,
'-m',
'virtualenv',
'-p{}'.format(python_executable),
venv_dir], cwd=os.getcwd(), stdout=PIPE, stderr=PIPE)
if proc.returncode != 0:
err = proc.stdout.decode('utf-8') + proc.stderr.decode('utf-8')
self.fail("Failed to create venv. Do you have virtualenv installed?\n" + err)
if sys.platform == 'win32':
yield venv_dir, os.path.abspath(os.path.join(venv_dir, 'Scripts', 'python'))
Expand All @@ -165,9 +166,9 @@ def install_package(self, pkg: str,
install_cmd.append('develop')
else:
install_cmd.append('install')
returncode, lines = run_command(install_cmd, cwd=working_dir)
if returncode != 0:
self.fail('\n'.join(lines))
proc = subprocess.run(install_cmd, cwd=working_dir, stdout=PIPE, stderr=PIPE)
if proc.returncode != 0:
self.fail(proc.stdout.decode('utf-8') + proc.stderr.decode('utf-8'))

def setUp(self) -> None:
self.simple_prog = ExampleProg(SIMPLE_PROGRAM)
Expand Down
8 changes: 5 additions & 3 deletions mypy/test/testpythoneval.py
Expand Up @@ -13,6 +13,8 @@
import os
import os.path
import re
import subprocess
from subprocess import PIPE
import sys
from tempfile import TemporaryDirectory

Expand All @@ -23,7 +25,7 @@
from mypy.defaults import PYTHON3_VERSION
from mypy.test.config import test_temp_dir
from mypy.test.data import DataDrivenTestCase, DataSuite
from mypy.test.helpers import assert_string_arrays_equal, run_command
from mypy.test.helpers import assert_string_arrays_equal, split_lines
from mypy.util import try_find_python2_interpreter
from mypy import api

Expand Down Expand Up @@ -90,8 +92,8 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None
output.append(line.rstrip("\r\n"))
if returncode == 0:
# Execute the program.
returncode, interp_out = run_command([interpreter, program])
output.extend(interp_out)
proc = subprocess.run([interpreter, program], cwd=test_temp_dir, stdout=PIPE, stderr=PIPE)
output.extend(split_lines(proc.stdout, proc.stderr))
# Remove temp file.
os.remove(program_path)
for i, line in enumerate(output):
Expand Down
47 changes: 0 additions & 47 deletions mypy/util.py
Expand Up @@ -257,50 +257,3 @@ def hard_exit(status: int = 0) -> None:
def unmangle(name: str) -> str:
"""Remove internal suffixes from a short name."""
return name.rstrip("'")


# The following is a backport of stream redirect utilities from Lib/contextlib.py
# We need this for 3.4 support. They can be removed in March 2019!


class _RedirectStream:

_stream = None # type: ClassVar[str]

def __init__(self, new_target: TextIO) -> None:
self._new_target = new_target
# We use a list of old targets to make this CM re-entrant
self._old_targets = [] # type: List[TextIO]

def __enter__(self) -> TextIO:
self._old_targets.append(getattr(sys, self._stream))
setattr(sys, self._stream, self._new_target)
return self._new_target

def __exit__(self,
exc_ty: 'Optional[Type[BaseException]]' = None,
exc_val: Optional[BaseException] = None,
exc_tb: Optional[TracebackType] = None,
) -> bool:
setattr(sys, self._stream, self._old_targets.pop())
return False


class redirect_stdout(_RedirectStream):
"""Context manager for temporarily redirecting stdout to another file.
# How to send help() to stderr
with redirect_stdout(sys.stderr):
help(dir)
# How to write help() to a file
with open('help.txt', 'w') as f:
with redirect_stdout(f):
help(pow)
"""

_stream = "stdout"


class redirect_stderr(_RedirectStream):
"""Context manager for temporarily redirecting stderr to another file."""

_stream = "stderr"
2 changes: 1 addition & 1 deletion runtests.py
Expand Up @@ -6,7 +6,7 @@


# Use the Python provided to execute the script, or fall back to a sane default
if version_info >= (3, 4, 0):
if version_info >= (3, 5, 0):
python_name = executable
else:
if platform == 'win32':
Expand Down
6 changes: 2 additions & 4 deletions setup.py
Expand Up @@ -5,8 +5,8 @@
import os.path
import sys

if sys.version_info < (3, 4, 0):
sys.stderr.write("ERROR: You need Python 3.4 or later to use mypy.\n")
if sys.version_info < (3, 5, 0):
sys.stderr.write("ERROR: You need Python 3.5 or later to use mypy.\n")
exit(1)

# we'll import stuff from the source tree, let's ensure is on the sys path
Expand Down Expand Up @@ -150,7 +150,6 @@ def run(self):
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
Expand Down Expand Up @@ -179,7 +178,6 @@ def run(self):
'mypy_extensions >= 0.4.0, < 0.5.0',
],
extras_require = {
':python_version < "3.5"': 'typing >= 3.5.3',
'dmypy': 'psutil >= 5.4.0, < 5.5.0; sys_platform!="win32"',
},
include_package_data=True,
Expand Down