Skip to content

Commit

Permalink
Drop Python 3.5 (#988)
Browse files Browse the repository at this point in the history
* Drop Python 3.5

Less than 0.5% of our downloads are 3.5 and it allows us to simplify A LOT of code.

Fixes #965

Signed-off-by: Hynek Schlawack <hs@ox.cx>

* Run 3.6 under coverage

* Add newsfragment

* Probably don't need 3.7 for coverage

* Everything is ordered!

* pre-commit autoupdate, add yesqa
  • Loading branch information
hynek committed Aug 5, 2022
1 parent 107367d commit 08f8319
Show file tree
Hide file tree
Showing 24 changed files with 110 additions and 250 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-beta - 3.11", "pypy-3.7", "pypy-3.8"]
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-beta - 3.11", "pypy-3.7", "pypy-3.8"]

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Expand Up @@ -15,7 +15,7 @@ repos:
rev: v2.37.3
hooks:
- id: pyupgrade
args: [--py3-plus, --keep-percent-format]
args: [--py36-plus, --keep-percent-format]
exclude: "tests/test_slots.py"

- repo: https://github.com/PyCQA/isort
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -113,7 +113,7 @@ Project Information
- **Changelog**: https://www.attrs.org/en/stable/changelog.html
- **Get Help**: please use the ``python-attrs`` tag on `StackOverflow <https://stackoverflow.com/questions/tagged/python-attrs>`_
- **Third-party Extensions**: https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs
- **Supported Python Versions**: 3.5 and later (last 2.7-compatible release is `21.4.0 <https://pypi.org/project/attrs/21.4.0/>`_)
- **Supported Python Versions**: 3.6 and later (last 2.7-compatible release is `21.4.0 <https://pypi.org/project/attrs/21.4.0/>`_)

If you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide <https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md>`_ to get you started!

Expand Down
1 change: 1 addition & 0 deletions changelog.d/988.breaking.rst
@@ -0,0 +1 @@
Python 3.5 is not supported anymore.
12 changes: 1 addition & 11 deletions conftest.py
@@ -1,9 +1,8 @@
# SPDX-License-Identifier: MIT


from hypothesis import HealthCheck, settings

from attr._compat import PY36, PY310
from attr._compat import PY310


def pytest_configure(config):
Expand All @@ -15,14 +14,5 @@ def pytest_configure(config):


collect_ignore = []
if not PY36:
collect_ignore.extend(
[
"tests/test_annotations.py",
"tests/test_hooks.py",
"tests/test_init_subclass.py",
"tests/test_next_gen.py",
]
)
if not PY310:
collect_ignore.extend(["tests/test_pattern_matching.py"])
1 change: 0 additions & 1 deletion docs/api.rst
Expand Up @@ -14,7 +14,6 @@ As of version 21.3.0, ``attrs`` consists of **two** top-level package names:
- The classic ``attr`` that powered the venerable `attr.s` and `attr.ib`
- The modern ``attrs`` that only contains most modern APIs and relies on `attrs.define` and `attrs.field` to define your classes.
Additionally it offers some ``attr`` APIs with nicer defaults (e.g. `attrs.asdict`).
Using this namespace requires Python 3.6 or later.

The ``attrs`` namespace is built *on top of* ``attr`` which will *never* go away.

Expand Down
2 changes: 1 addition & 1 deletion docs/examples.rst
Expand Up @@ -473,7 +473,7 @@ If you're the author of a third-party library with ``attrs`` integration, please
Types
-----

``attrs`` also allows you to associate a type with an attribute using either the *type* argument to `attr.ib` or -- as of Python 3.6 -- using :pep:`526`-annotations:
``attrs`` also allows you to associate a type with an attribute using either the *type* argument to `attr.ib` or using :pep:`526`-annotations:


.. doctest::
Expand Down
2 changes: 1 addition & 1 deletion docs/extending.rst
Expand Up @@ -124,7 +124,7 @@ Types

``attrs`` offers two ways of attaching type information to attributes:

- :pep:`526` annotations on Python 3.6 and later,
- :pep:`526` annotations,
- and the *type* argument to `attr.ib`.

This information is available to you:
Expand Down
1 change: 0 additions & 1 deletion docs/names.rst
Expand Up @@ -19,7 +19,6 @@ We recommend our modern APIs for new code:
- and `attrs.field()` to define an attribute.

They have been added in ``attrs`` 20.1.0, they are expressive, and they have modern defaults like slots and type annotation awareness switched on by default.
They are only available in Python 3.6 and later.
Sometimes they're referred to as *next-generation* or *NG* APIs.
As of ``attrs`` 21.3.0 you can also import them from the ``attrs`` package namespace.

Expand Down
15 changes: 5 additions & 10 deletions setup.py
Expand Up @@ -4,7 +4,6 @@
import os
import platform
import re
import sys

from setuptools import find_packages, setup

Expand Down Expand Up @@ -33,7 +32,6 @@
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
Expand All @@ -57,10 +55,7 @@
"pytest>=4.3.0", # 4.3.0 dropped last use of `convert`
],
}
if (
sys.version_info[:2] >= (3, 6)
and platform.python_implementation() != "PyPy"
):
if platform.python_implementation() != "PyPy":
EXTRAS_REQUIRE["tests_no_zope"].extend(
["mypy>=0.900,!=0.940", "pytest-mypy-plugins"]
)
Expand Down Expand Up @@ -92,11 +87,11 @@ def find_meta(meta):
Extract __*meta*__ from META_FILE.
"""
meta_match = re.search(
r"^__{meta}__ = ['\"]([^'\"]*)['\"]".format(meta=meta), META_FILE, re.M
rf"^__{meta}__ = ['\"]([^'\"]*)['\"]", META_FILE, re.M
)
if meta_match:
return meta_match.group(1)
raise RuntimeError("Unable to find __{meta}__ string.".format(meta=meta))
raise RuntimeError(f"Unable to find __{meta}__ string.")


LOGO = """
Expand All @@ -119,7 +114,7 @@ def find_meta(meta):
re.S,
).group(1)
+ "\n\n`Full changelog "
+ "<{url}en/stable/changelog.html>`_.\n\n".format(url=URL)
+ f"<{URL}en/stable/changelog.html>`_.\n\n"
+ read("AUTHORS.rst")
)

Expand All @@ -141,7 +136,7 @@ def find_meta(meta):
long_description_content_type="text/x-rst",
packages=PACKAGES,
package_dir={"": "src"},
python_requires=">=3.5",
python_requires=">=3.6",
zip_safe=False,
classifiers=CLASSIFIERS,
install_requires=INSTALL_REQUIRES,
Expand Down
13 changes: 5 additions & 8 deletions src/attr/__init__.py
@@ -1,8 +1,5 @@
# SPDX-License-Identifier: MIT


import sys

from functools import partial

from . import converters, exceptions, filters, setters, validators
Expand All @@ -20,6 +17,7 @@
make_class,
validate,
)
from ._next_gen import define, field, frozen, mutable
from ._version_info import VersionInfo


Expand Down Expand Up @@ -56,24 +54,23 @@
"attrs",
"cmp_using",
"converters",
"define",
"evolve",
"exceptions",
"field",
"fields",
"fields_dict",
"filters",
"frozen",
"get_run_validators",
"has",
"ib",
"make_class",
"mutable",
"resolve_types",
"s",
"set_run_validators",
"setters",
"validate",
"validators",
]

if sys.version_info[:2] >= (3, 6):
from ._next_gen import define, field, frozen, mutable # noqa: F401

__all__.extend(("define", "field", "frozen", "mutable"))
10 changes: 0 additions & 10 deletions src/attr/_compat.py
Expand Up @@ -12,19 +12,9 @@


PYPY = platform.python_implementation() == "PyPy"
PY36 = sys.version_info[:2] >= (3, 6)
HAS_F_STRINGS = PY36
PY310 = sys.version_info[:2] >= (3, 10)


if PYPY or PY36:
ordered_dict = dict
else:
from collections import OrderedDict

ordered_dict = OrderedDict


def just_warn(*args, **kw):
warnings.warn(
"Running interpreter doesn't sufficiently support code object "
Expand Down

0 comments on commit 08f8319

Please sign in to comment.