Skip to content

Commit 3692eba

Browse files
authored
Drop Python 3.6 support (Lightning-AI#11117)
1 parent 9da78a9 commit 3692eba

File tree

23 files changed

+32
-86
lines changed

23 files changed

+32
-86
lines changed

.circleci/config.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@ references:
3737
run:
3838
name: Make Documentation
3939
command: |
40-
# First run the same pipeline as Read-The-Docs
41-
# apt-get update && apt-get install -y cmake
42-
# using: https://hub.docker.com/r/readthedocs/build
43-
# we need to use py3.7 ot higher becase of an issue with metaclass inheritence
40+
# the image uses python 2.7 by default, force a different version
4441
pyenv global 3.7.3
4542
python --version
4643
pip install -r requirements/docs.txt

.github/workflows/ci_pkg-install.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
# max-parallel: 6
1717
matrix:
1818
os: [ubuntu-20.04, macOS-10.15, windows-2019]
19-
python-version: [3.6, 3.9]
19+
python-version: [3.7, 3.9]
2020

2121
steps:
2222
- uses: actions/checkout@v2

.github/workflows/ci_test-full.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ jobs:
2121
python-version: ["3.7", "3.9"] # minimum, maximum
2222
requires: ["oldest", "latest"]
2323
release: ["stable"]
24-
include:
25-
# test 3.6 only on oldest until EOL: https://github.com/PyTorchLightning/pytorch-lightning/issues/9981
26-
- {os: ubuntu-18.04, python-version: "3.6", requires: "oldest", release: "stable"}
27-
- {os: windows-2019, python-version: "3.6", requires: "oldest", release: "stable"}
28-
- {os: macOS-10.15, python-version: "3.6", requires: "oldest", release: "stable"}
24+
#include:
2925
# nightly: add when there's a release candidate
3026
#- {os: ubuntu-20.04, python-version: "3.10", requires: "latest", release: "pre"}
3127

.github/workflows/release-docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
python_version: ["3.6", "3.7", "3.8", "3.9"]
18+
python_version: ["3.7", "3.8", "3.9"]
1919
pytorch_version: ["1.7", "1.8", "1.9", "1.10"]
2020
steps:
2121
- name: Checkout

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ repos:
4949
rev: v2.29.0
5050
hooks:
5151
- id: pyupgrade
52-
args: [--py36-plus]
52+
args: [--py37-plus]
5353
name: Upgrade code
5454

5555
- repo: https://github.com/myint/docformatter
@@ -80,8 +80,8 @@ repos:
8080
rev: v1.11.0
8181
hooks:
8282
- id: blacken-docs
83-
args: [ --line-length=120 ]
84-
additional_dependencies: [ black==21.7b0 ]
83+
args: [--line-length=120]
84+
additional_dependencies: [black==21.7b0]
8585

8686
- repo: https://github.com/executablebooks/mdformat
8787
rev: 0.7.10

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
308308

309309
- Removed `Accelerator.on_train_start` ([#10999](https://github.com/PyTorchLightning/pytorch-lightning/pull/10999))
310310

311+
312+
- Removed support for Python 3.6 ([#11117](https://github.com/PyTorchLightning/pytorch-lightning/pull/11117))
313+
311314
### Fixed
312315

313316
- Fixed `NeptuneLogger` when using DDP ([#11030](https://github.com/PyTorchLightning/pytorch-lightning/pull/11030))

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ Lightning is rigorously tested across multiple GPUs, TPUs CPUs and against major
8686
| Linux py3.{7,9} | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) | - | - | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) |
8787
| OSX py3.{7,9} | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) | - | - | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) |
8888
| Windows py3.{7,9} | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) | - | - | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) |
89-
| Linux py3.6 | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) | - | - | - |
90-
| OSX py3.6 | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) | - | - | - |
91-
| Windows py3.6 | [![Test](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml/badge.svg?branch=master&event=push)](https://github.com/PyTorchLightning/pytorch-lightning/actions/workflows/ci_test-full.yml) | - | - | - |
9289

9390
- _\*\* tests run on two NVIDIA P100_
9491
- _\*\*\* tests run on Google GKE TPUv2/3. TPU py3.7 means we support Colab and Kaggle env._

dockers/base-xla/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ FROM google/cloud-sdk:slim
1616

1717
LABEL maintainer="PyTorchLightning <https://github.com/PyTorchLightning>"
1818

19-
# CALL: docker image build -t pytorch-lightning:XLA-extras-py3.6 -f dockers/base-xla/Dockerfile . --build-arg PYTHON_VERSION=3.8
19+
# CALL: docker image build -t pytorch-lightning:XLA-image -f dockers/base-xla/Dockerfile . --build-arg PYTHON_VERSION=3.8
2020
ARG PYTHON_VERSION=3.9
2121
ARG CONDA_VERSION=4.9.2
2222
ARG XLA_VERSION=1.8

environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ channels:
2626
- conda-forge
2727

2828
dependencies:
29-
- python>=3.6
29+
- python>=3.7
3030
- pip>20.1
3131
- numpy>=1.17.2
3232
- pytorch>=1.7.*

pytorch_lightning/accelerators/gpu.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ def get_nvidia_gpu_stats(device: torch.device) -> Dict[str, float]:
110110
result = subprocess.run(
111111
[nvidia_smi_path, f"--query-gpu={gpu_query}", "--format=csv,nounits,noheader", f"--id={gpu_id}"],
112112
encoding="utf-8",
113-
stdout=subprocess.PIPE,
114-
stderr=subprocess.PIPE, # for backward compatibility with python version 3.6
113+
capture_output=True,
115114
check=True,
116115
)
117116

pytorch_lightning/callbacks/gpu_stats_monitor.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,7 @@ def _get_gpu_stats(self, queries: List[str]) -> List[List[float]]:
214214
f"--id={gpu_ids}",
215215
],
216216
encoding="utf-8",
217-
stdout=subprocess.PIPE,
218-
stderr=subprocess.PIPE, # for backward compatibility with python version 3.6
217+
capture_output=True,
219218
check=True,
220219
)
221220

pytorch_lightning/core/mixins/device_dtype_mixin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
try:
2121
from typing_extensions import Self
2222
except ImportError:
23-
# workaround for Python 3.6 and 3.7.
23+
# workaround for Python 3.7.
2424
# see https://www.python.org/dev/peps/pep-0673/
2525
from typing import TypeVar
2626

pytorch_lightning/profiler/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ def _prepare_streams(self) -> None:
129129

130130
def describe(self) -> None:
131131
"""Logs a profile report after the conclusion of run."""
132-
# there are pickling issues with open file handles in Python 3.6
133-
# so to avoid them, we open and close the files within this function
134-
# by calling `_prepare_streams` and `teardown`
132+
# users might call `describe` directly as the profilers can be used by themselves.
133+
# to allow this, we open and close the files within this function by calling `_prepare_streams` and `teardown`
134+
# manually instead of letting the `Trainer` do it through `setup` and `teardown`
135135
self._prepare_streams()
136136
summary = self.summary()
137137
if summary:

pytorch_lightning/trainer/connectors/logger_connector/result.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from collections.abc import Generator
1515
from dataclasses import asdict, dataclass, replace
1616
from functools import partial, wraps
17-
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
17+
from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union
1818

1919
import torch
2020
from torchmetrics import Metric
@@ -29,8 +29,7 @@
2929
from pytorch_lightning.utilities.metrics import metrics_to_scalars
3030
from pytorch_lightning.utilities.warnings import WarningCache
3131

32-
# TODO(@tchaton): Typing-pickle issue on python<3.7 (https://github.com/cloudpipe/cloudpickle/pull/318)
33-
_IN_METRIC = Any # Union[Metric, torch.Tensor] # Do not include scalars as they were converted to tensors
32+
_IN_METRIC = Union[Metric, torch.Tensor] # Do not include scalars as they were converted to tensors
3433
_OUT_METRIC = Union[torch.Tensor, Dict[str, torch.Tensor]]
3534
_PBAR_METRIC = Union[float, Dict[str, float]]
3635
_OUT_DICT = Dict[str, _OUT_METRIC]
@@ -217,6 +216,7 @@ def __init__(self, metadata: _Metadata, is_tensor: bool) -> None:
217216

218217
def update(self, value: _IN_METRIC, batch_size: int) -> None: # type: ignore[override]
219218
if self.is_tensor:
219+
value = cast(torch.Tensor, value)
220220
if not torch.is_floating_point(value):
221221
dtype = torch.get_default_dtype()
222222
warning_cache.warn(
@@ -244,6 +244,7 @@ def update(self, value: _IN_METRIC, batch_size: int) -> None: # type: ignore[ov
244244
elif self.meta.is_sum_reduction:
245245
self.value += value.mean()
246246
else:
247+
value = cast(Metric, value)
247248
self.value = value
248249
self._forward_cache = value._forward_cache
249250

@@ -405,7 +406,9 @@ def append_fn(v: _ResultMetric) -> None:
405406
apply_to_collection(list(self.values()), _ResultMetric, append_fn)
406407
return o
407408

408-
def _extract_batch_size(self, value: _METRIC_COLLECTION, batch_size: Optional[int], meta: _Metadata) -> int:
409+
def _extract_batch_size(
410+
self, value: Union[_ResultMetric, _ResultMetricCollection], batch_size: Optional[int], meta: _Metadata
411+
) -> int:
409412
# check if we have extracted the batch size already
410413
if batch_size is None:
411414
batch_size = self.batch_size

pytorch_lightning/utilities/imports.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,7 @@ def _module_available(module_path: str) -> bool:
3535
"""
3636
try:
3737
return find_spec(module_path) is not None
38-
except AttributeError:
39-
# Python 3.6
40-
return False
4138
except ModuleNotFoundError:
42-
# Python 3.7+
4339
return False
4440

4541

pytorch_lightning/utilities/memory.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,7 @@ def get_gpu_memory_map() -> Dict[str, float]:
163163
result = subprocess.run(
164164
[nvidia_smi_path, "--query-gpu=memory.used", "--format=csv,nounits,noheader"],
165165
encoding="utf-8",
166-
# capture_output=True, # valid for python version >=3.7
167-
stdout=subprocess.PIPE,
168-
stderr=subprocess.PIPE, # for backward compatibility with python version 3.6
166+
capture_output=True,
169167
check=True,
170168
)
171169

pytorch_lightning/utilities/model_summary.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import contextlib
1616
import logging
17-
import sys
1817
from collections import OrderedDict
1918
from typing import Any, Dict, List, Optional, Tuple, Union
2019

@@ -267,10 +266,8 @@ def _forward_example_input(self) -> None:
267266

268267
if trainer is not None:
269268
forward_context = trainer.precision_plugin.forward_context()
270-
elif sys.version_info >= (3, 7):
271-
forward_context = contextlib.nullcontext()
272269
else:
273-
forward_context = contextlib.suppress()
270+
forward_context = contextlib.nullcontext()
274271

275272
with torch.no_grad(), forward_context:
276273
# let the model hooks collect the input- and output shapes

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
numpy>=1.17.2
44
torch>=1.7.*
5-
future>=0.17.1 # required for builtins in setup.py
65
tqdm>=4.41.0
76
PyYAML>=5.4
87
fsspec[http]>=2021.05.0, !=2021.06.0

setup.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def _load_py_module(fname, pkg="pytorch_lightning"):
8080
long_description_content_type="text/markdown",
8181
zip_safe=False,
8282
keywords=["deep learning", "pytorch", "AI"],
83-
python_requires=">=3.6",
83+
python_requires=">=3.7",
8484
setup_requires=[],
8585
install_requires=setup_tools._load_requirements(_PATH_ROOT),
8686
extras_require=extras,
@@ -92,9 +92,7 @@ def _load_py_module(fname, pkg="pytorch_lightning"):
9292
classifiers=[
9393
"Environment :: Console",
9494
"Natural Language :: English",
95-
# How mature is this project? Common values are
96-
# 3 - Alpha, 4 - Beta, 5 - Production/Stable
97-
"Development Status :: 4 - Beta",
95+
"Development Status :: 5 - Production/Stable",
9896
# Indicate who your project is intended for
9997
"Intended Audience :: Developers",
10098
"Topic :: Scientific/Engineering :: Artificial Intelligence",
@@ -103,10 +101,8 @@ def _load_py_module(fname, pkg="pytorch_lightning"):
103101
# Pick your license as you wish
104102
"License :: OSI Approved :: Apache Software License",
105103
"Operating System :: OS Independent",
106-
# Specify the Python versions you support here. In particular, ensure
107-
# that you indicate whether you support Python 2, Python 3 or both.
104+
# Specify the Python versions you support here.
108105
"Programming Language :: Python :: 3",
109-
"Programming Language :: Python :: 3.6",
110106
"Programming Language :: Python :: 3.7",
111107
"Programming Language :: Python :: 3.8",
112108
"Programming Language :: Python :: 3.9",

tests/conftest.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# limitations under the License.
1414
import os
1515
import signal
16-
import sys
1716
import threading
1817
from functools import partial
1918
from http.server import SimpleHTTPRequestHandler
@@ -135,28 +134,8 @@ def caplog(caplog):
135134

136135
@pytest.fixture
137136
def tmpdir_server(tmpdir):
138-
if sys.version_info >= (3, 7):
139-
Handler = partial(SimpleHTTPRequestHandler, directory=str(tmpdir))
140-
from http.server import ThreadingHTTPServer
141-
else:
142-
# unfortunately SimpleHTTPRequestHandler doesn't accept the directory arg in python3.6
143-
# so we have to hack it like this
144-
145-
class Handler(SimpleHTTPRequestHandler):
146-
def translate_path(self, path):
147-
# get the path from cwd
148-
path = super().translate_path(path)
149-
# get the relative path
150-
relpath = os.path.relpath(path, os.getcwd())
151-
# return the full path from root_dir
152-
return os.path.join(str(tmpdir), relpath)
153-
154-
# ThreadingHTTPServer was added in 3.7, so we need to define it ourselves
155-
from http.server import HTTPServer
156-
from socketserver import ThreadingMixIn
157-
158-
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
159-
daemon_threads = True
137+
Handler = partial(SimpleHTTPRequestHandler, directory=str(tmpdir))
138+
from http.server import ThreadingHTTPServer
160139

161140
with ThreadingHTTPServer(("localhost", 0), Handler) as server:
162141
server_thread = threading.Thread(target=server.serve_forever)

tests/trainer/test_trainer_cli.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ def test_argparse_args_parsing(cli_args, expected):
147147
assert Trainer.from_argparse_args(args)
148148

149149

150-
@RunIf(min_python="3.7.0")
151150
@pytest.mark.parametrize(
152151
"cli_args,expected",
153152
[("", False), ("--fast_dev_run=0", False), ("--fast_dev_run=True", True), ("--fast_dev_run 2", 2)],
@@ -180,7 +179,6 @@ def test_argparse_args_parsing_gpus(cli_args, expected_parsed, expected_device_i
180179
assert trainer.data_parallel_device_ids == expected_device_ids
181180

182181

183-
@RunIf(min_python="3.7.0")
184182
@pytest.mark.parametrize(
185183
["cli_args", "extra_args"],
186184
[

tests/utilities/test_argparse.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,6 @@ def test_add_argparse_args_no_argument_group():
213213
assert args.my_parameter == 2
214214

215215

216-
def test_add_argparse_args_invalid():
217-
"""Test that `add_argparse_args` doesn't raise `TypeError` when a class has args typed as `typing.Generic` in
218-
Python 3.6."""
219-
add_argparse_args(AddArgparseArgsExampleClassGeneric, ArgumentParser())
220-
221-
222216
def test_gpus_allowed_type():
223217
assert _gpus_allowed_type("1,2") == "1,2"
224218
assert _gpus_allowed_type("1") == 1

0 commit comments

Comments
 (0)