Merge pull request #2512 from tkoyama010/patch-6
interepolation->interpolation
diff --git a/.github/workflows/codespell-private.yml b/.github/workflows/codespell-private.yml
index fa9c5fa..1ad4e3b 100644
--- a/.github/workflows/codespell-private.yml
+++ b/.github/workflows/codespell-private.yml
@@ -1,21 +1,26 @@
# GitHub Action to check our dictionary, this should only be used by the codespell project itself
# For general usage in your repo, see the example in codespell.yml
# https://github.com/codespell-project/codespell
-name: codespell Private Actions
+# Concurrency cancels an action on a given PR once a new commit is pushed
+name: Test Codespell
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }}
+ cancel-in-progress: true
on: [push, pull_request]
jobs:
test:
env:
REQUIRE_ASPELL: true
# Make sure we're using the latest aspell dictionary
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
strategy:
+ fail-fast: false
matrix:
python-version:
- - 3.6
- - 3.7
- - 3.8
- - 3.9
+ - '3.7'
+ - '3.8'
+ - '3.9'
+ - '3.10'
name: Python ${{ matrix.python-version }} test
steps:
- uses: actions/checkout@v3
@@ -24,14 +29,15 @@
with:
python-version: ${{ matrix.python-version }}
- run: sudo apt-get install libaspell-dev aspell-en
- - run: |
+ - name: Install dependencies
+ run: |
python --version # just to check
pip install -U pip wheel # upgrade to latest pip find 3.5 wheels; wheel to avoid errors
- pip install codecov chardet "setuptools!=47.2.0" docutils
+ pip install --upgrade codecov chardet "setuptools!=47.2.0" docutils setuptools_scm[toml]
pip install aspell-python-py3
pip install -e ".[dev]" # install the codespell dev packages
- - run: python setup.py install
- run: codespell --help
+ - run: codespell --version
- run: make check
- run: codespell --check-filenames --skip="./.git/*,*.pyc,./codespell_lib/tests/test_basic.py,./codespell_lib/data/*,./example/code.c,./build/lib/codespell_lib/tests/test_basic.py,./build/lib/codespell_lib/data/*,README.rst,*.egg-info/*"
# this file has an error
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
index 32bfc59..5858912 100644
--- a/.github/workflows/codespell.yml
+++ b/.github/workflows/codespell.yml
@@ -13,4 +13,4 @@
with:
check_filenames: true
# When using this Action in other repos, the --skip option below can be removed
- skip: ./.git,./codespell_lib/data,./example/code.c,test_basic.py,*.pyc,README.rst
+ skip: "./.git,./codespell_lib/data,./example/code.c,test_basic.py,*.pyc,README.rst"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..66f131c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,56 @@
+# Upload a Python Package using Twine when a release is created
+
+name: Build
+on:
+ release:
+ types: [published]
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+
+permissions:
+ contents: read
+
+jobs:
+ package:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install build twine
+ - name: Build package
+ run: python -m build
+ - name: Check package
+ run: twine check --strict dist/*
+ - name: Check env vars
+ run: |
+ echo "Triggered by: ${{ github.event_name }}"
+ - uses: actions/upload-artifact@v3
+ with:
+ name: dist
+ path: dist
+
+ # PyPI on release
+ pypi:
+ needs: package
+ runs-on: ubuntu-latest
+ if: github.event_name == 'release'
+ steps:
+ - uses: actions/download-artifact@v3
+ with:
+ name: dist
+ path: dist
+ - name: Publish to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ user: __token__
+ password: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.gitignore b/.gitignore
index a0a7f4a..8b5d201 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
*.orig
.cache/
.pytest_cache/
+codespell_lib/_version.py
diff --git a/Makefile b/Makefile
index c297fb0..5cbe5e0 100644
--- a/Makefile
+++ b/Makefile
@@ -45,7 +45,7 @@
done
check-manifest:
- check-manifest
+ check-manifest --no-build-isolation
check-distutils:
python setup.py check --restructuredtext --strict
@@ -56,8 +56,5 @@
pytest:
pytest codespell_lib
-pypi:
- python setup.py sdist register upload
-
clean:
rm -rf codespell.1
diff --git a/README.rst b/README.rst
index 9a3f7c7..fb5702e 100644
--- a/README.rst
+++ b/README.rst
@@ -23,7 +23,7 @@
Requirements
------------
-Python 3.6 or above.
+Python 3.7 or above.
Installation
------------
@@ -103,12 +103,24 @@
count =
quiet-level = 3
-This is equivalent to running::
+Codespell will also check in the current directory for a ``pyproject.toml``
+(or a path can be specified via ``--toml <filename>``) file, and the
+``[tool.codespell]`` entry will be used as long as the tomli_ package
+is installed, for example::
+
+ [tool.codespell]
+ skip = '*.po,*.ts,./src/3rdParty,./src/Test'
+ count = ''
+ quiet-level = 3
+
+These are both equivalent to running::
codespell --quiet-level 3 --count --skip "*.po,*.ts,./src/3rdParty,./src/Test"
Any options specified in the command line will *override* options from the
-config file.
+config files.
+
+.. _tomli: https://pypi.org/project/tomli/
Dictionary format
-----------------
diff --git a/codespell_lib/__init__.py b/codespell_lib/__init__.py
index c354bd7..019d227 100644
--- a/codespell_lib/__init__.py
+++ b/codespell_lib/__init__.py
@@ -1 +1,2 @@
-from ._codespell import main, _script_main, VERSION as __version__ # noqa
+from ._codespell import main, _script_main # noqa
+from ._version import __version__ # noqa
diff --git a/codespell_lib/_codespell.py b/codespell_lib/_codespell.py
index fdad69d..598aa72 100644
--- a/codespell_lib/_codespell.py
+++ b/codespell_lib/_codespell.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -26,17 +25,19 @@
import sys
import textwrap
-word_regex_def = u"[\\w\\-'’`]+"
+# autogenerated by setuptools_scm
+from ._version import __version__ as VERSION
+
+word_regex_def = "[\\w\\-'’`]+"
# While we want to treat characters like ( or " as okay for a starting break,
# these may occur unescaped in URIs, and so we are more restrictive on the
# endpoint. Emails are more restrictive, so the endpoint remains flexible.
-uri_regex_def = (u"(\\b(?:https?|[ts]?ftp|file|git|smb)://[^\\s]+(?=$|\\s)|"
- u"\\b[\\w.%+-]+@[\\w.-]+\\b)")
+uri_regex_def = ("(\\b(?:https?|[ts]?ftp|file|git|smb)://[^\\s]+(?=$|\\s)|"
+ "\\b[\\w.%+-]+@[\\w.-]+\\b)")
encodings = ('utf-8', 'iso-8859-1')
USAGE = """
\t%prog [OPTIONS] [file1 file2 ... fileN]
"""
-VERSION = '2.3.0.dev0'
supported_languages_en = ('en', 'en_GB', 'en_US', 'en_CA', 'en_AU')
supported_languages = supported_languages_en
@@ -81,7 +82,7 @@
# file1 .. fileN Files to check spelling
-class QuietLevels(object):
+class QuietLevels:
NONE = 0
ENCODING = 1
BINARY_FILE = 2
@@ -90,7 +91,7 @@
FIXES = 16
-class GlobMatch(object):
+class GlobMatch:
def __init__(self, pattern):
if pattern:
# Pattern might be a list of comma-delimited strings
@@ -109,14 +110,14 @@
return False
-class Misspelling(object):
+class Misspelling:
def __init__(self, data, fix, reason):
self.data = data
self.fix = fix
self.reason = reason
-class TermColors(object):
+class TermColors:
def __init__(self):
self.FILE = '\033[33m'
self.WWORD = '\033[31m'
@@ -130,7 +131,7 @@
self.DISABLE = ''
-class Summary(object):
+class Summary:
def __init__(self):
self.summary = {}
@@ -150,7 +151,7 @@
width=15 - len(key)) for key in keys])
-class FileOpener(object):
+class FileOpener:
def __init__(self, use_chardet, quiet_level):
self.use_chardet = use_chardet
if use_chardet:
@@ -200,30 +201,27 @@
return lines, encoding
def open_with_internal(self, filename):
- curr = 0
- while True:
- try:
- f = codecs.open(filename, 'r', encoding=encodings[curr])
- except UnicodeDecodeError:
- if not self.quiet_level & QuietLevels.ENCODING:
- print("WARNING: Decoding file using encoding=%s failed: %s"
- % (encodings[curr], filename,), file=sys.stderr)
- try:
- print("WARNING: Trying next encoding %s"
- % encodings[curr + 1], file=sys.stderr)
- except IndexError:
- pass
-
- curr += 1
- else:
- lines = f.readlines()
- f.close()
- break
- if not lines:
+ encoding = None
+ first_try = True
+ for encoding in encodings:
+ if first_try:
+ first_try = False
+ elif not self.quiet_level & QuietLevels.ENCODING:
+ print("WARNING: Trying next encoding %s"
+ % encoding, file=sys.stderr)
+ with codecs.open(filename, 'r', encoding=encoding) as f:
+ try:
+ lines = f.readlines()
+ except UnicodeDecodeError:
+ if not self.quiet_level & QuietLevels.ENCODING:
+ print("WARNING: Decoding file using encoding=%s "
+ "failed: %s" % (encoding, filename,),
+ file=sys.stderr)
+ else:
+ break
+ else:
raise Exception('Unknown encoding')
- encoding = encodings[curr]
-
return lines, encoding
# -.-:-.-:-.-:-.:-.-:-.-:-.-:-.-:-.:-.-:-.-:-.-:-.-:-.:-.-:-
@@ -238,7 +236,7 @@
def _split_lines(self, text, width):
parts = text.split('\n')
out = list()
- for pi, part in enumerate(parts):
+ for part in parts:
# Eventually we could allow others...
indent_start = '- '
if part.startswith(indent_start):
@@ -392,7 +390,8 @@
help='print LINES of surrounding context')
parser.add_argument('--config', type=str,
help='path to config file.')
-
+ parser.add_argument('--toml', type=str,
+ help='path to a pyproject.toml file.')
parser.add_argument('files', nargs='*',
help='files or directories to check')
@@ -404,6 +403,26 @@
if options.config:
cfg_files.append(options.config)
config = configparser.ConfigParser()
+
+ # Read toml before other config files.
+ toml_files_errors = list()
+ if os.path.isfile('pyproject.toml'):
+ toml_files_errors.append(('pyproject.toml', False))
+ if options.toml:
+ toml_files_errors.append((options.toml, True))
+ for toml_file, raise_error in toml_files_errors:
+ try:
+ import tomli
+ except Exception as exc:
+ if raise_error:
+ raise ImportError(
+ f'tomli is required to read pyproject.toml but could not '
+ f'be imported, got: {exc}') from None
+ else:
+ continue
+ with open(toml_file, 'rb') as f:
+ data = tomli.load(f).get('tool', {})
+ config.read_dict(data)
config.read(cfg_files)
if config.has_section('codespell'):
@@ -439,7 +458,7 @@
def build_exclude_hashes(filename, exclude_lines):
- with codecs.open(filename, 'r') as f:
+ with codecs.open(filename, mode='r', encoding='utf-8') as f:
for line in f:
exclude_lines.add(line)
diff --git a/codespell_lib/data/dictionary.txt b/codespell_lib/data/dictionary.txt
index c964f3e..80e6a3a 100644
--- a/codespell_lib/data/dictionary.txt
+++ b/codespell_lib/data/dictionary.txt
@@ -497,7 +497,6 @@
accrediation->accreditation
accredidation->accreditation
accress->access
-accreting->accrediting
accroding->according
accrodingly->accordingly
accronym->acronym
@@ -1923,6 +1922,10 @@
anaylses->analyses
anaylsis->analysis
anaylsises->analysises
+anayltic->analytic
+anayltical->analytical
+anayltically->analytically
+anayltics->analytics
anaylze->analyze
anaylzed->analyzed
anaylzer->analyzer
@@ -6679,6 +6682,8 @@
combind->combined
combinded->combined
combinine->combine
+combintaion->combination
+combintaions->combinations
combusion->combustion
comceptually->conceptually
comdemnation->condemnation
@@ -15330,7 +15335,6 @@
falshes->flashes
falshing->flashing
falsly->falsely
-falsy->falsely, false,
falt->fault
falure->failure
familar->familiar
@@ -19213,8 +19217,12 @@
instutionalized->institutionalized
instutions->intuitions
insue->ensue, insure,
+insufficency->insufficiency
insufficent->insufficient
+insufficently->insufficiently
insuffiency->insufficiency
+insuffient->insufficient
+insuffiently->insufficiently
insurasnce->insurance
insurence->insurance
intaces->instance
@@ -27973,6 +27981,7 @@
regons->regions
regorded->recorded
regresion->regression
+regresison->regression
regresssion->regression
regrigerator->refrigerator
regsion->region
@@ -31741,6 +31750,7 @@
spefiying->specifying
spefy->specify
spefying->specifying
+speherical->spherical
speical->special
speices->species
speicfied->specified
@@ -31766,6 +31776,7 @@
speperats->separates
sperate->separate
sperately->separately
+sperhical->spherical
spermatozoan->spermatozoon
speshal->special
speshally->specially, especially,
@@ -32471,6 +32482,8 @@
substancial->substantial
substantialy->substantially
substantivly->substantively
+substask->subtask
+substasks->subtasks
substatial->substantial
substential->substantial
substentially->substantially
@@ -32508,6 +32521,8 @@
subsytem->subsystem
subsytems->subsystems
subtabels->subtables
+subtak->subtask
+subtaks->subtask, subtasks,
subtances->substances
subtarger->subtarget, sub-target,
subtargers->subtargets, sub-targets,
@@ -32519,6 +32534,8 @@
subtitution->substitution
subtitutions->substitutions
subtrafuge->subterfuge
+subtrate->substrate
+subtrates->substrates
subtring->substring
subtrings->substrings
subtsitutable->substitutable
@@ -32655,11 +32672,17 @@
sufficates->suffocates
sufficating->suffocating
suffication->suffocation
+sufficency->sufficiency
sufficent->sufficient
sufficently->sufficiently
+sufficiancy->sufficiency
sufficiant->sufficient
+sufficiantly->sufficiently
sufficiennt->sufficient
sufficienntly->sufficiently
+suffiency->sufficiency
+suffient->sufficient
+suffiently->sufficiently
suffisticated->sophisticated
suficate->suffocate
suficated->suffocated
@@ -34087,7 +34110,7 @@
toolar->toolbar
toolsbox->toolbox
toom->tomb
-tooo->todo
+tooo->todo, too, tool, took,
toos->tools
tootonic->teutonic
topicaizer->topicalizer
diff --git a/codespell_lib/data/dictionary_code.txt b/codespell_lib/data/dictionary_code.txt
index 29ee050..174a414 100644
--- a/codespell_lib/data/dictionary_code.txt
+++ b/codespell_lib/data/dictionary_code.txt
@@ -21,6 +21,7 @@
endcode->encode
errorstring->error string
exitst->exits, exists,
+falsy->falsely, false,
files'->file's
gae->game, Gael, gale,
hist->heist, his,
diff --git a/codespell_lib/data/dictionary_rare.txt b/codespell_lib/data/dictionary_rare.txt
index a6e2074..814348e 100644
--- a/codespell_lib/data/dictionary_rare.txt
+++ b/codespell_lib/data/dictionary_rare.txt
@@ -1,4 +1,5 @@
ablet->able, tablet,
+accreting->accrediting
afterwords->afterwards
amination->animation, lamination,
aminations->animations, laminations,
@@ -16,7 +17,7 @@
bloc->block
blocs->blocks
bodgy->body
-bu->by
+bu->by, be, but, bug, bun, bud, buy, bum,
buss->bus
busses->buses
calculatable->calculable
diff --git a/codespell_lib/tests/test_basic.py b/codespell_lib/tests/test_basic.py
index 64beddd..8b73584 100644
--- a/codespell_lib/tests/test_basic.py
+++ b/codespell_lib/tests/test_basic.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
import contextlib
import inspect
import os
@@ -22,7 +20,7 @@
assert EX_DATAERR == 65
-class MainWrapper(object):
+class MainWrapper:
"""Compatibility wrapper for when we used to return the count."""
def main(self, *args, count=True, std=False, **kwargs):
@@ -174,7 +172,7 @@
with FakeStdin('0\n'): # blank input -> nothing
assert cs.main('-w', '-i', '3', f.name) == 0
assert cs.main(f.name) == 0
- with open(f.name, 'r') as f_read:
+ with open(f.name) as f_read:
assert f_read.read() == 'awkward\n'
with open(f.name, 'w') as f:
f.write('ackward\n')
@@ -184,7 +182,7 @@
assert code == 0
assert 'a valid option' in stdout
assert cs.main(f.name) == 0
- with open(f.name, 'r') as f:
+ with open(f.name) as f:
assert f.read() == 'backward\n'
finally:
os.remove(f.name)
@@ -249,11 +247,11 @@
"""Test exclude file functionality."""
d = str(tmpdir)
with open(op.join(d, 'bad.txt'), 'wb') as f:
- f.write('1 abandonned 1\n2 abandonned 2\n'.encode('utf-8'))
+ f.write(b'1 abandonned 1\n2 abandonned 2\n')
bad_name = f.name
assert cs.main(bad_name) == 2
with open(op.join(d, 'tmp.txt'), 'wb') as f:
- f.write('1 abandonned 1\n'.encode('utf-8'))
+ f.write(b'1 abandonned 1\n')
assert cs.main(bad_name) == 2
assert cs.main('-x', f.name, bad_name) == 1
@@ -266,12 +264,25 @@
# with CaptureStdout() as sio:
assert cs.main(f.name) == 0
with open(f.name, 'wb') as f:
- f.write(u'naïve\n'.encode('utf-8'))
+ f.write('naïve\n'.encode())
assert cs.main(f.name) == 0
assert cs.main('-e', f.name) == 0
with open(f.name, 'ab') as f:
- f.write(u'naieve\n'.encode('utf-8'))
+ f.write(b'naieve\n')
assert cs.main(f.name) == 1
+ # Encoding detection (only try ISO 8859-1 because UTF-8 is the default)
+ with open(f.name, 'wb') as f:
+ f.write(b'Speling error, non-ASCII: h\xe9t\xe9rog\xe9n\xe9it\xe9\n')
+ # check warnings about wrong encoding are enabled with "-q 0"
+ code, stdout, stderr = cs.main('-q', '0', f.name, std=True, count=True)
+ assert code == 1
+ assert 'Speling' in stdout
+ assert 'iso-8859-1' in stderr
+ # check warnings about wrong encoding are disabled with "-q 1"
+ code, stdout, stderr = cs.main('-q', '1', f.name, std=True, count=True)
+ assert code == 1
+ assert 'Speling' in stdout
+ assert 'iso-8859-1' not in stderr
# Binary file warning
with open(f.name, 'wb') as f:
f.write(b'\x00\x00naiive\x00\x00')
@@ -382,7 +393,7 @@
# with CaptureStdout() as sio:
assert cs.main(f.name) == 0
with open(f.name, 'wb') as f:
- f.write('this has an ACII error'.encode('utf-8'))
+ f.write(b'this has an ACII error')
code, stdout, _ = cs.main(f.name, std=True)
assert code == 1
assert 'ASCII' in stdout
@@ -791,35 +802,55 @@
assert not uri_regex.findall(boilerplate % uri), uri
-def test_config(tmpdir, capsys):
- """
- Tests loading options from a config file.
- """
- d = str(tmpdir)
-
- # Create sample files.
- with open(op.join(d, 'bad.txt'), 'w') as f:
+@pytest.mark.parametrize('kind', ('toml', 'cfg'))
+def test_config_toml(tmp_path, capsys, kind):
+ """Test loading options from a config file or toml."""
+ d = tmp_path / 'files'
+ d.mkdir()
+ with open(d / 'bad.txt', 'w') as f:
f.write('abandonned donn\n')
- with open(op.join(d, 'good.txt'), 'w') as f:
+ with open(d / 'good.txt', 'w') as f:
f.write("good")
- # Create a config file.
- conffile = op.join(d, 'config.cfg')
- with open(conffile, 'w') as f:
- f.write(
- '[codespell]\n'
- 'skip = bad.txt\n'
- 'count = \n'
- )
-
# Should fail when checking both.
- code, stdout, _ = cs.main(d, count=True, std=True)
+ code, stdout, _ = cs.main(str(d), count=True, std=True)
# Code in this case is not exit code, but count of misspellings.
assert code == 2
assert 'bad.txt' in stdout
+ if kind == 'cfg':
+ conffile = str(tmp_path / 'setup.cfg')
+ args = ('--config', conffile)
+ with open(conffile, 'w') as f:
+ f.write("""\
+[codespell]
+skip = bad.txt, whatever.txt
+count =
+""")
+ else:
+ assert kind == 'toml'
+ pytest.importorskip('tomli')
+ tomlfile = str(tmp_path / 'pyproject.toml')
+ args = ('--toml', tomlfile)
+ with open(tomlfile, 'w') as f:
+ f.write("""\
+[tool.codespell]
+skip = 'bad.txt,whatever.txt'
+count = false
+""")
+
# Should pass when skipping bad.txt
- code, stdout, _ = cs.main('--config', conffile, d, count=True, std=True)
+ code, stdout, _ = cs.main(str(d), *args, count=True, std=True)
+ assert code == 0
+ assert 'bad.txt' not in stdout
+
+ # And both should automatically work if they're in cwd
+ cwd = os.getcwd()
+ try:
+ os.chdir(tmp_path)
+ code, stdout, _ = cs.main(str(d), count=True, std=True)
+ finally:
+ os.chdir(cwd)
assert code == 0
assert 'bad.txt' not in stdout
diff --git a/codespell_lib/tests/test_dictionary.py b/codespell_lib/tests/test_dictionary.py
index 6d246d3..9f3dec0 100644
--- a/codespell_lib/tests/test_dictionary.py
+++ b/codespell_lib/tests/test_dictionary.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
import glob
import os.path as op
import os
@@ -41,9 +39,9 @@
def test_dictionaries_exist():
"""Test consistency of dictionaries."""
- doc_fnames = set(op.basename(f[0]) for f in _fnames_in_aspell)
- got_fnames = set(op.basename(f)
- for f in glob.glob(op.join(_data_dir, '*.txt')))
+ doc_fnames = {op.basename(f[0]) for f in _fnames_in_aspell}
+ got_fnames = {op.basename(f)
+ for f in glob.glob(op.join(_data_dir, '*.txt'))}
assert doc_fnames == got_fnames
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..431834f
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,68 @@
+# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
+
+[project]
+name = "codespell"
+description = "Codespell"
+readme = { file = "README.rst", content-type = "text/x-rst" }
+requires-python = ">=3.7"
+license = {text = "GPL v2"}
+authors = [
+ {name = "Lucas De Marchi", email = "lucas.de.marchi@gmail.com"},
+]
+classifiers = [
+ "Intended Audience :: Developers",
+ "License :: OSI Approved",
+ "Programming Language :: Python",
+ "Topic :: Software Development",
+ "Operating System :: Microsoft :: Windows",
+ "Operating System :: POSIX",
+ "Operating System :: Unix",
+ "Operating System :: MacOS"
+]
+dependencies = []
+dynamic = ["version"]
+
+[project.optional-dependencies]
+dev = [
+ "check-manifest",
+ "flake8",
+ "pytest",
+ "pytest-cov",
+ "pytest-dependency",
+ "tomli"
+]
+hard-encoding-detection = [
+ "chardet"
+]
+toml = [
+ "tomli; python_version < '3.11'"
+]
+
+[project.scripts]
+codespell = "codespell_lib:_script_main"
+
+[project.urls]
+homepage = "https://github.com/codespell-project/codespell"
+repository = "https://github.com/codespell-project/codespell"
+
+[build-system]
+requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2", "wheel"]
+build-backend = "setuptools.build_meta"
+
+[tool.setuptools_scm]
+write_to = "codespell_lib/_version.py"
+
+[tool.setuptools.packages.find]
+exclude = [
+ "snap",
+ "dist"
+]
+
+[tool.setuptools.package-data]
+codespell_lib = [
+ "data/dictionary*.txt",
+ "data/linux-kernel.exclude"
+]
+
+[tool.check-manifest]
+ignore = ["codespell_lib/_version.py"]
diff --git a/setup.cfg b/setup.cfg
index d46869c..7074b31 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[tool:pytest]
-addopts = --cov=codespell_lib --showlocals -rs --cov-report=
+addopts = --cov=codespell_lib -rs --cov-report= --tb=short
[flake8]
exclude = build, ci-helpers
-ignore =
+ignore = W503
diff --git a/setup.py b/setup.py
index 8a6c8c7..4fe2f90 100755
--- a/setup.py
+++ b/setup.py
@@ -1,66 +1,6 @@
#! /usr/bin/env python
-# adapted from mne-python
-
-import os
-
from setuptools import setup
-from codespell_lib import __version__
-
-DISTNAME = 'codespell'
-DESCRIPTION = """Codespell"""
-MAINTAINER = 'Lucas De Marchi'
-MAINTAINER_EMAIL = 'lucas.de.marchi@gmail.com'
-URL = 'https://github.com/codespell-project/codespell/'
-LICENSE = 'GPL v2'
-DOWNLOAD_URL = 'https://github.com/codespell-project/codespell/'
-with open('README.rst', 'r') as f:
- LONG_DESCRIPTION = f.read()
-
if __name__ == "__main__":
- if os.path.exists('MANIFEST'):
- os.remove('MANIFEST')
-
- setup(name=DISTNAME,
- maintainer=MAINTAINER,
- include_package_data=True,
- maintainer_email=MAINTAINER_EMAIL,
- description=DESCRIPTION,
- license=LICENSE,
- url=URL,
- version=__version__,
- download_url=DOWNLOAD_URL,
- long_description=LONG_DESCRIPTION,
- long_description_content_type='text/x-rst',
- zip_safe=False,
- classifiers=['Intended Audience :: Developers',
- 'License :: OSI Approved',
- 'Programming Language :: Python',
- 'Topic :: Software Development',
- 'Operating System :: Microsoft :: Windows',
- 'Operating System :: POSIX',
- 'Operating System :: Unix',
- 'Operating System :: MacOS'],
- platforms='any',
- python_requires='>=3.6',
- packages=[
- 'codespell_lib',
- 'codespell_lib.tests',
- 'codespell_lib.data',
- ],
- package_data={'codespell_lib': [
- os.path.join('data', 'dictionary*.txt'),
- os.path.join('data', 'linux-kernel.exclude'),
- ]},
- entry_points={
- 'console_scripts': [
- 'codespell = codespell_lib:_script_main'
- ],
- },
- extras_require={
- "dev": ["check-manifest", "flake8", "pytest", "pytest-cov",
- "pytest-dependency"],
- "hard-encoding-detection": ["chardet"],
- }
- )
+ setup()