Skip to content

Commit

Permalink
removed support for Python 3.8 (which officially ended on 2024-10-07)
Browse files Browse the repository at this point in the history
  • Loading branch information
dskrypa committed Nov 2, 2024
1 parent e74d159 commit 7ff1797
Show file tree
Hide file tree
Showing 14 changed files with 19 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
fail-fast: false
matrix:
language: ["python"]
python-version: ["3.11"]
python-version: ["3.12"]

steps:
- name: Checkout repository
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.11"]
python-version: ["3.12"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Add test locales
run: |
Expand Down
16 changes: 3 additions & 13 deletions docs/_src/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ CLI Command Parser

|downloads| |py_version| |coverage_badge| |build_status| |Ruff|

.. |py_version| image:: https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20-blue
.. |py_version| image:: https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20-blue
:target: https://pypi.org/project/cli-command-parser/

.. |coverage_badge| image:: https://codecov.io/gh/dskrypa/cli_command_parser/branch/main/graph/badge.svg
Expand Down Expand Up @@ -85,18 +85,8 @@ with optional dependencies::
Python Version Compatibility
============================

Python versions 3.8 and above are currently supported. The last release of CLI Command Parser that supported 3.7 was
2023-04-30. Support for Python 3.7 `officially ended on 2023-06-27 <https://devguide.python.org/versions/>`__.

When using Python 3.8, some additional packages that backport functionality that was added in later Python versions
are required for compatibility.

To use the argparse to cli-command-parser conversion script with Python 3.8, there is a dependency on
`astunparse <https://astunparse.readthedocs.io>`__. If you are using Python 3.9 or above, then ``astunparse`` is not
necessary because the relevant code was added to the stdlib ``ast`` module. If you're unsure, you can install
cli-command-parser with the following command to automatically handle whether that extra dependency is needed or not::

$ pip install -U cli-command-parser[conversion]
Python versions 3.9 and above are currently supported. The last release of CLI Command Parser that supported 3.8 was
2024-09-07. Support for Python 3.8 `officially ended on 2024-10-07 <https://devguide.python.org/versions/>`__.


User Guide
Expand Down
11 changes: 1 addition & 10 deletions lib/cli_command_parser/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from collections.abc import Collection, Iterable
from functools import lru_cache
from inspect import isclass
from typing import Union, Optional, get_type_hints as _get_type_hints, get_origin, get_args as _get_args
from typing import Optional, Union, get_args, get_origin, get_type_hints as _get_type_hints

try:
from types import NoneType
Expand Down Expand Up @@ -42,15 +42,6 @@ def get_annotation_value_type(annotation, from_union: bool = True, from_collecti
return None


def get_args(annotation) -> tuple:
"""
Wrapper around :func:`python:typing.get_args` for 3.7~8 compatibility, to make it behave more like it does in 3.9+
"""
if getattr(annotation, '_special', False): # 3.7-3.8 generic collection alias with no content types
return ()
return _get_args(annotation)


def _type_from_union(annotation) -> Optional[type]:
args = get_args(annotation)
# Note: Unions of a single argument return the argument; i.e., Union[T] returns T, so the len can never be 1
Expand Down
10 changes: 0 additions & 10 deletions lib/cli_command_parser/compat.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
"""
Compatibility / Patch module - used to back-port features to Python 3.7 and to avoid breaking changes in Enum/Flag in
3.11.
Contains stdlib CPython functions / classes from Python 3.8 and 3.10.
The :class:`WCTextWrapper` in this module extends the stdlib :class:`python:textwrap.TextWrapper` to support wide
characters.
"""
Expand All @@ -16,8 +11,6 @@

__all__ = ['WCTextWrapper']

# region textwrap


class WCTextWrapper(TextWrapper):
"""
Expand Down Expand Up @@ -119,6 +112,3 @@ def _wrap_chunks(self, chunks: list[str]) -> list[str]:
break

return lines


# endregion
21 changes: 2 additions & 19 deletions lib/cli_command_parser/conversion/utils.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
from __future__ import annotations

from ast import AST, expr, Call, Attribute, Name, Dict, List, Set, Tuple

try:
from ast import unparse
except ImportError: # added in 3.9
try:
from astunparse import unparse as _unparse
except ImportError as e:
raise RuntimeError(
'Missing required dependency: astunparse (only required in Python 3.8 and below'
' - upgrade to 3.9 or above to avoid this dependency)'
)
else:

def unparse(node):
return ''.join(_unparse(node).splitlines())


from typing import Union, Iterator, List as _List
from ast import AST, Attribute, Call, Dict, List, Name, Set, Tuple, expr, unparse
from typing import Iterator, List as _List, Union

__all__ = ['get_name_repr', 'iter_module_parents', 'collection_contents']

Expand Down
2 changes: 1 addition & 1 deletion lib/cli_command_parser/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,6 @@ def write_rst(self, name: str, content: str, subdir: str = None):
path = target_dir.joinpath(name + self.ext)
log.debug(f'{prefix} {path.as_posix()}')
if not self.dry_run:
# Path.write_text on 3.8 does not support `newline`
# Path.write_text on 3.9 does not support `newline`
with path.open('w', encoding=self.encoding, newline=self.newline) as f:
f.write(content)
2 changes: 1 addition & 1 deletion lib/cli_command_parser/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def mod_obj_prog_map(self) -> dict[str, dict[str, str]]:
def _get_console_scripts(cls) -> tuple[EntryPoint, ...]:
try:
return entry_points(group='console_scripts') # noqa
except TypeError: # Python 3.8 or 3.9
except TypeError: # Python 3.9
return entry_points()['console_scripts'] # noqa

def normalize(
Expand Down
16 changes: 3 additions & 13 deletions readme.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ CLI Command Parser

|downloads| |py_version| |coverage_badge| |build_status| |Ruff|

.. |py_version| image:: https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20-blue
.. |py_version| image:: https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20-blue
:target: https://pypi.org/project/cli-command-parser/

.. |coverage_badge| image:: https://codecov.io/gh/dskrypa/cli_command_parser/branch/main/graph/badge.svg
Expand Down Expand Up @@ -85,18 +85,8 @@ with optional dependencies::
Python Version Compatibility
============================

Python versions 3.8 and above are currently supported. The last release of CLI Command Parser that supported 3.7 was
2023-04-30. Support for Python 3.7 `officially ended on 2023-06-27 <https://devguide.python.org/versions/>`__.

When using Python 3.8, some additional packages that backport functionality that was added in later Python versions
are required for compatibility.

To use the argparse to cli-command-parser conversion script with Python 3.8, there is a dependency on
`astunparse <https://astunparse.readthedocs.io>`__. If you are using Python 3.9 or above, then ``astunparse`` is not
necessary because the relevant code was added to the stdlib ``ast`` module. If you're unsure, you can install
cli-command-parser with the following command to automatically handle whether that extra dependency is needed or not::

$ pip install -U cli-command-parser[conversion]
Python versions 3.9 and above are currently supported. The last release of CLI Command Parser that supported 3.8 was
2024-09-07. Support for Python 3.8 `officially ended on 2024-10-07 <https://devguide.python.org/versions/>`__.


Links
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-e .[wcwidth,conversion]
-e .[wcwidth]
-r docs/requirements.txt
pre-commit
ruff
Expand Down
5 changes: 1 addition & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ classifiers =
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Expand All @@ -36,7 +35,7 @@ include_package_data = True
entry_points = file: entry_points.txt
packages = find:
package_dir = = lib
python_requires = >=3.8
python_requires = >=3.9
tests_require = testtools; coverage

[options.packages.find]
Expand All @@ -45,5 +44,3 @@ where = lib
[options.extras_require]
wcwidth =
wcwidth
conversion =
astunparse; python_version<"3.9"
2 changes: 1 addition & 1 deletion tests/test_core/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def test_prog_from_sys_argv(self):
def test_entry_points_old(self):
entry_points = {'console_scripts': ep_scripts(('bar.py', 'foo:bar'), ('baz.py', 'foo:baz'))}
expected = {'foo': {'bar': 'bar.py', 'baz': 'baz.py'}}
with patch(f'{MODULE}.entry_points', side_effect=[TypeError, entry_points]): # Simulate py 3.8/3.9
with patch(f'{MODULE}.entry_points', side_effect=[TypeError, entry_points]): # Simulate py 3.9
self.assertDictEqual(expected, ProgFinder().mod_obj_prog_map)

def test_entry_points_new(self):
Expand Down
10 changes: 2 additions & 8 deletions tests/test_parameters/test_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,17 @@

import sys
from pathlib import Path
from typing import Optional, Collection, Sequence, Iterable, Union
from typing import Collection, Iterable, Optional, Sequence, Union
from unittest import main, skipIf
from unittest.mock import Mock

from cli_command_parser import Command, Positional, Option, inputs
from cli_command_parser.annotations import get_args
from cli_command_parser import Command, Option, Positional, inputs
from cli_command_parser.testing import ParserTest, load_command

THIS_FILE = Path(__file__).resolve()
TEST_DATA_DIR = THIS_FILE.parents[1].joinpath('data', 'command_test_cases')


class AnnotationsTest(ParserTest):
def test_get_args(self):
# This is for coverage in 3.9+ for the get_args compatibility wrapper, to mock the attr present in 3.8 & below
self.assertEqual((), get_args(Mock(_special=True)))

def test_annotation_using_forward_ref(self):
with load_command(TEST_DATA_DIR, 'annotation_using_forward_ref.py', 'AnnotatedCommand') as AnnotatedCmd:
self.assertIs(None, AnnotatedCmd.paths_a.type)
Expand Down

0 comments on commit 7ff1797

Please sign in to comment.