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 Python 3.5 #988

Merged
merged 8 commits into from Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
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