Skip to content

Commit

Permalink
Merge pull request #177 from SethMMorton/modernize-dev-infra
Browse files Browse the repository at this point in the history
Modernize development infrastructure
  • Loading branch information
SethMMorton authored Oct 11, 2024
2 parents 607b35d + 5ac16f2 commit 9e6cd0d
Show file tree
Hide file tree
Showing 45 changed files with 508 additions and 392 deletions.
26 changes: 12 additions & 14 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ jobs:
with:
python-version: '3.8'

- name: Install black
run: pip install black

- name: Run black
run: black --quiet --check --diff .
- name: Run ruff
uses: astral-sh/ruff-action@v1
with:
args: 'format --check'

static-analysis:
name: Static Analysis
Expand All @@ -40,11 +39,8 @@ jobs:
with:
python-version: '3.8'

- name: Install Flake8
run: pip install flake8 flake8-import-order flake8-bugbear pep8-naming

- name: Run Flake8
run: flake8
- name: Run ruff
uses: astral-sh/ruff-action@v1

type-checking:
name: Type Checking
Expand All @@ -59,7 +55,10 @@ jobs:
python-version: '3.8'

- name: Install MyPy
run: pip install mypy hypothesis pytest pytest-mock fastnumbers
run: pip install mypy hypothesis pytest pytest-mock fastnumbers setuptools_scm

- name: Create _version.py file
run: python -m setuptools_scm --force-write-version-files

- name: Run MyPy
run: mypy --strict natsort tests
Expand All @@ -77,10 +76,9 @@ jobs:
python-version: '3.8'

- name: Install Validators
run: pip install twine check-manifest
run: pip install twine build

- name: Run Validation
run: |
check-manifest --ignore ".github*,*.md,.coveragerc"
python setup.py sdist
python -m build
twine check dist/*
5 changes: 2 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ jobs:

- name: Build Source Distribution and Wheel
run: |
pip install wheel
python setup.py sdist --format=gztar
pip wheel . -w dist
pip install build
python -m build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11"]
python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
os: [ubuntu-latest]
extras: [false]
include:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.py[co]
_version.py

# Packages
*.egg
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
Unreleased
---

### Changed

- Modernize development infrastructure
(PR [#162](https://github.com/SethMMorton/natsort/issues/177))
- Use `ruff` instead of `flake8` and `black`
- Move all config to `pyproject.toml`
- Use `setuptools-scm` to track `__version__`
- Remove `bumpversion` for creating new releases

### Fixed

- Eliminated mypy failure related to string literals

### Removed

- Support for EOL Python 3.7

[8.4.0] - 2023-06-19
---

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ a good reason not to be).
Located in the `dev/` folder is development collateral such as formatting and
patching scripts. The only development collateral not in the `dev/`
folder are those files that are expected to exist in the the top-level directory
(such as `setup.py`, `tox.ini`, and CI configuration). All of these scripts
(such as `pyproject.toml`, `tox.ini`, and CI configuration). All of these scripts
can either be run with the python stdandard library, or have hooks in `tox`.

I do not have strong opinions on how one should contribute, so
Expand Down
10 changes: 0 additions & 10 deletions MANIFEST.in

This file was deleted.

2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ from the command line with ``python -m natsort``. Check out the
Requirements
------------

`natsort`_ requires Python 3.7 or greater.
`natsort`_ requires Python 3.8 or greater.

Optional Dependencies
---------------------
Expand Down
72 changes: 44 additions & 28 deletions dev/bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@
INTENDED TO BE CALLED FROM PROJECT ROOT, NOT FROM dev/!
"""

import datetime
import subprocess
import sys

from setuptools_scm import get_version

# Ensure a clean repo before moving on.
ret = subprocess.run(
["git", "status", "--porcelain", "--untracked-files=no"],
check=True,
capture_output=True,
text=True,
)
if ret.stdout:
sys.exit("Cannot bump unless the git repo has no changes.")


# A valid bump must have been given.
try:
bump_type = sys.argv[1]
except IndexError:
Expand All @@ -28,44 +43,45 @@ def git(cmd, *args):
sys.exit(e.returncode)


def bumpversion(severity, *args, catch=False):
"""Wrapper for calling bumpversion"""
cmd = ["bump2version", *args, severity]
try:
if catch:
return subprocess.run(
cmd, check=True, capture_output=True, text=True
).stdout
else:
subprocess.run(cmd, check=True, text=True)
except subprocess.CalledProcessError as e:
print("Call to bump2version failed!", file=sys.stderr)
print("STDOUT:", e.stdout, file=sys.stderr)
print("STDERR:", e.stderr, file=sys.stderr)
sys.exit(e.returncode)
# Use setuptools-scm to identify the current version
current_version = get_version(
root="..",
relative_to=__file__,
local_scheme="no-local-version",
version_scheme="only-version",
)

# Increment the version according to the bump type
version_components = list(map(int, current_version.split(".")))
incr_index = {"major": 0, "minor": 1, "patch": 2}[bump_type]
version_components[incr_index] += 1
for i in range(incr_index + 1, 3):
version_components[i] = 0
next_version = ".".join(map(str, version_components))

# Do a dry run of the bump to find what the current version is and what it will become.
data = bumpversion(bump_type, "--dry-run", "--list", catch=True)
data = dict(x.split("=") for x in data.splitlines())
# Update the changelog.
with open("CHANGELOG.md") as fl:
changelog = fl.read()

# Execute the bumpversion.
bumpversion(bump_type)
# Add a date to this entry.
changelog = changelog.replace(
"Unreleased",
f"Unreleased\n---\n\n[{next_version}] - {datetime.datetime.now():%Y-%m-%d}",
)

# Post-process the changelog with things that bumpversion is not good at updating.
with open("CHANGELOG.md") as fl:
changelog = fl.read().replace(
# Add links to the entries.
changelog = changelog.replace(
"<!---Comparison links-->",
"<!---Comparison links-->\n[{new}]: {url}/{current}...{new}".format(
new=data["new_version"],
current=data["current_version"],
new=next_version,
current=current_version,
url="https://github.com/SethMMorton/natsort/compare",
),
)
with open("CHANGELOG.md", "w") as fl:
fl.write(changelog)

# Finally, add the CHANGELOG.md changes to the previous commit.
# Add the CHANGELOG.md changes and commit & tag.
git("add", "CHANGELOG.md")
git("commit", "--amend", "--no-edit")
git("tag", "--force", data["new_version"], "HEAD")
git("commit", "--message", f"Bump version: {current_version}{next_version}")
git("tag", next_version, "HEAD")
9 changes: 9 additions & 0 deletions dev/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
pathlib.Path("build"),
pathlib.Path("dist"),
pathlib.Path(".pytest_cache"),
pathlib.Path(".ruff_cache"),
pathlib.Path(".mypy_cache"),
pathlib.Path(".pytest_cache"),
pathlib.Path(".hypothesis"),
pathlib.Path(".tox"),
pathlib.Path(".coverage"),
]
dirs += pathlib.Path.cwd().glob("*.egg-info")
for d in dirs:
Expand All @@ -30,3 +34,8 @@
# Shouldn't be any .pyc left, but just in case
for f in pathlib.Path.cwd().rglob("*.pyc"):
f.unlink()

# Remove _version.py
version = pathlib.Path("natsort/_version.py")
if version.is_file():
version.unlink()
4 changes: 2 additions & 2 deletions dev/generate_new_unicode_numbers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Generate the numeric hex list of unicode numerals
"""

import os
import os.path
import sys
Expand Down Expand Up @@ -40,6 +40,6 @@
if a in "0123456789":
continue
if unicodedata.numeric(a, None) is not None:
print(" 0x{:X},".format(i), file=fl)
print(f" 0x{i:X},", file=fl)

print(")", file=fl)
4 changes: 3 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import os

import natsort

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
Expand Down Expand Up @@ -58,7 +60,7 @@
# built documents.
#
# The full version, including alpha/beta/rc tags.
release = "8.4.0"
release = natsort.__version__
# The short X.Y version.
version = ".".join(release.split(".")[0:2])

Expand Down
13 changes: 8 additions & 5 deletions natsort/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# -*- coding: utf-8 -*-

try:
# The redundant "as" tells mypy to treat as explict import
from natsort._version import __version__ as __version__
from natsort._version import __version_tuple__ as __version_tuple__
except ImportError:
__version__ = "unknown version"
__version_tuple__ = (0, 0, "unknown version")
from natsort.natsort import (
NatsortKeyType,
OSSortKeyType,
Expand All @@ -23,8 +28,6 @@
from natsort.ns_enum import NSType, ns
from natsort.utils import KeyType, NatsortInType, NatsortOutType, chain_functions

__version__ = "8.4.0"

__all__ = [
"natsort_key",
"natsort_keygen",
Expand Down Expand Up @@ -53,4 +56,4 @@
]

# Add the ns keys to this namespace for convenience.
globals().update({name: value for name, value in ns.__members__.items()})
globals().update(dict(ns.__members__.items()))
17 changes: 9 additions & 8 deletions natsort/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

import argparse
import sys
from typing import Callable, Iterable, List, Optional, Pattern, Tuple, Union, cast
Expand Down Expand Up @@ -64,7 +62,7 @@ def main(*arguments: str) -> None:
parser.add_argument(
"--version",
action="version",
version="%(prog)s {}".format(natsort.__version__),
version=f"%(prog)s {natsort.__version__}",
)
parser.add_argument(
"-p",
Expand Down Expand Up @@ -201,9 +199,9 @@ def range_check(low: Num, high: Num) -> NumPair:
"""
if low >= high:
raise ValueError("low >= high")
else:
return low, high
msg = "low >= high"
raise ValueError(msg)
return low, high


def check_filters(filters: Optional[NumPairIter]) -> Optional[List[NumPair]]:
Expand Down Expand Up @@ -231,7 +229,7 @@ def check_filters(filters: Optional[NumPairIter]) -> Optional[List[NumPair]]:
try:
return [range_check(f[0], f[1]) for f in filters]
except ValueError as err:
raise ValueError("Error in --filter: " + str(err))
raise ValueError("Error in --filter: " + str(err)) from None


def keep_entry_range(
Expand Down Expand Up @@ -273,7 +271,10 @@ def keep_entry_range(


def keep_entry_value(
entry: str, values: NumIter, converter: NumConverter, regex: Pattern[str]
entry: str,
values: NumIter,
converter: NumConverter,
regex: Pattern[str],
) -> bool:
"""
Check if an entry does not match a given value.
Expand Down
2 changes: 1 addition & 1 deletion natsort/compat/fake_fastnumbers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
"""
This module is intended to replicate some of the functionality
from the fastnumbers module in the event that module is not installed.
"""

import unicodedata
from typing import Callable, FrozenSet, Union

Expand Down
Loading

0 comments on commit 9e6cd0d

Please sign in to comment.