apply a consistent format to `setup.cfg` files
155
stars
501
commits
Python
primary language
Aug 17, 2026
updated
apply a consistent format to setup.cfg files
pip install setup-cfg-fmt
See pre-commit for instructions
Sample .pre-commit-config.yaml:
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v3.2.0
hooks:
- id: setup-cfg-fmt
Consult the help for the latest usage:
$ setup-cfg-fmt --help
For example, name and version (the most important metadata) will always
appear at the top.
[metadata]
-version = 1.14.4
-name = pre_commit
+name = pre_commit
+version = 1.14.4
pip will normalize names to dashes foo_bar => foo-barpython setup.py sdist produces a filename with the name verbatimpip wheel . produces a filename with an underscore-normalized name$ # with dashed name
$ python setup.py sdist && pip wheel -w dist .
...
$ ls dist/ | cat
setup_cfg_fmt-0.0.0-py2.py3-none-any.whl
setup-cfg-fmt-0.0.0.tar.gz
$ # with underscore name
$ python setup.py sdist && pip wheel -w dist .
...
$ ls dist/ | cat
setup_cfg_fmt-0.0.0-py2.py3-none-any.whl
setup_cfg_fmt-0.0.0.tar.gz
This makes it easier to upload packages to pypi since they end up with the same filename prefix.
[metadata]
-name = pre-commit
+name = pre_commit
setuptools allows dashed names but does not document them.
[metadata]
name = pre-commit
-long-description = file: README.md
+long_description = file: README.md
long_description if README is presentThis will show up on the pypi project page
[metadata]
name = pre_commit
version = 1.14.5
+long_description = file: README.md
+long_description_content_type = text/markdown
license_file / license if LICENSE exists [metadata]
name = pre_commit
version = 1.14.5
+license = MIT
+license_file = LICENSE
python_requiresA few sources are searched for guessing python_requires:
python_requires setting itselfenvlist in tox.ini if presentclassifiers that are already set--min-py-version argumentclassifiers are generated based on:
python_requires setting--max-py-version argument--include-version-classifiers is specified name = pkg
version = 1.0
+classifiers =
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.7
+ Programming Language :: Python :: 3.8
+ Programming Language :: Python :: 3.9
+ Programming Language :: Python :: 3.10
+ Programming Language :: Python :: 3.11
+ ...
without --include-version-classifiers only the major version will be included:
name = pkg
version = 1.0
+classifiers =
+ Programming Language :: Python :: 3
[metadata]
name = pre_commit
version = 1.14.5
classifiers =
- Programming Language :: Python :: 3
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.6
[options]
-dependency_links =
python_requires = >= 3.6.1
setup.py -> setup.cfgPython
100.0%
apply a consistent format to `setup.cfg` files
155
stars
501
commits
Python
primary language
Aug 17, 2026
updated
apply a consistent format to setup.cfg files
pip install setup-cfg-fmt
See pre-commit for instructions
Sample .pre-commit-config.yaml:
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v3.2.0
hooks:
- id: setup-cfg-fmt
Consult the help for the latest usage:
$ setup-cfg-fmt --help
For example, name and version (the most important metadata) will always
appear at the top.
[metadata]
-version = 1.14.4
-name = pre_commit
+name = pre_commit
+version = 1.14.4
pip will normalize names to dashes foo_bar => foo-barpython setup.py sdist produces a filename with the name verbatimpip wheel . produces a filename with an underscore-normalized name$ # with dashed name
$ python setup.py sdist && pip wheel -w dist .
...
$ ls dist/ | cat
setup_cfg_fmt-0.0.0-py2.py3-none-any.whl
setup-cfg-fmt-0.0.0.tar.gz
$ # with underscore name
$ python setup.py sdist && pip wheel -w dist .
...
$ ls dist/ | cat
setup_cfg_fmt-0.0.0-py2.py3-none-any.whl
setup_cfg_fmt-0.0.0.tar.gz
This makes it easier to upload packages to pypi since they end up with the same filename prefix.
[metadata]
-name = pre-commit
+name = pre_commit
setuptools allows dashed names but does not document them.
[metadata]
name = pre-commit
-long-description = file: README.md
+long_description = file: README.md
long_description if README is presentThis will show up on the pypi project page
[metadata]
name = pre_commit
version = 1.14.5
+long_description = file: README.md
+long_description_content_type = text/markdown
license_file / license if LICENSE exists [metadata]
name = pre_commit
version = 1.14.5
+license = MIT
+license_file = LICENSE
python_requiresA few sources are searched for guessing python_requires:
python_requires setting itselfenvlist in tox.ini if presentclassifiers that are already set--min-py-version argumentclassifiers are generated based on:
python_requires setting--max-py-version argument--include-version-classifiers is specified name = pkg
version = 1.0
+classifiers =
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.7
+ Programming Language :: Python :: 3.8
+ Programming Language :: Python :: 3.9
+ Programming Language :: Python :: 3.10
+ Programming Language :: Python :: 3.11
+ ...
without --include-version-classifiers only the major version will be included:
name = pkg
version = 1.0
+classifiers =
+ Programming Language :: Python :: 3
[metadata]
name = pre_commit
version = 1.14.5
classifiers =
- Programming Language :: Python :: 3
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.6
[options]
-dependency_links =
python_requires = >= 3.6.1
setup.py -> setup.cfgPython
100.0%