Repository: johnthagen/exitstatus (language: python)

Issue:
Missing py.typed file
mypy requires a `py.typed` file in order to run type checking on a package.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
index b8f949a..42d7aa4 100644
--- a/.github/workflows/python.yml
+++ b/.github/workflows/python.yml
@@ -7,11 +7,11 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ["3.7", "3.8", "3.9", "3.10"]
+        python-version: ["3.8", "3.9", "3.10"]
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install dependencies
diff --git a/LICENSE.txt b/LICENSE.txt
index 873ccab..da201bd 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2019-2020 John Hagen
+Copyright (c) 2019-2022 John Hagen
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to
diff --git a/MANIFEST.in b/MANIFEST.in
index 926cc7b..1db9b1d 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,3 @@
 include README.rst
 include LICENSE.txt
+include exitstatus/py.typed
diff --git a/README.rst b/README.rst
index 42b0c65..c3015bf 100644
--- a/README.rst
+++ b/README.rst
@@ -56,6 +56,13 @@ Exit status codes are defined in a simple to use
 Releases
 --------
 
+2.3.0 2022-11-02
+^^^^^^^^^^^^^^^^
+
+- Add ``py.typed`` file to package to support Mypy type checking.
+- Refactor the project into an installable package rather than an installable module.
+- Drop support for Python 3.7
+
 2.2.0 2021-11-06
 ^^^^^^^^^^^^^^^^
 
@@ -106,4 +113,4 @@ Add docstrings and simplify checking for ``enum34`` dependency need.
 1.0.0 - 2016-06-10
 ^^^^^^^^^^^^^^^^^^
 
-Initial release.
\ No newline at end of file
+Initial release.
diff --git a/dev-requirements.in b/dev-requirements.in
index a2137c9..258afef 100644
--- a/dev-requirements.in
+++ b/dev-requirements.in
@@ -1,8 +1,12 @@
 tox
+
 pytest
 pytest-cov
+
 mypy
+
 flake8
 pep8-naming
+
 black
 isort
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 5d3232f..cb6f7d6 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,60 +1,50 @@
 #
-# This file is autogenerated by pip-compile with python 3.9
+# This file is autogenerated by pip-compile with python 3.10
 # To update, run:
 #
-#    pip-compile '.\dev-requirements.in'
+#    pip-compile dev-requirements.in
 #
-atomicwrites==1.4.0
+attrs==22.1.0
     # via pytest
-attrs==21.2.0
-    # via pytest
-backports.entry-points-selectable==1.1.0
-    # via virtualenv
-black==21.10b0
-    # via -r .\dev-requirements.in
-click==8.0.3
+black==22.10.0
+    # via -r dev-requirements.in
+click==8.1.3
     # via black
-colorama==0.4.4
-    # via
-    #   click
-    #   pytest
-    #   tox
-coverage[toml]==6.1.1
+coverage[toml]==6.5.0
     # via pytest-cov
-distlib==0.3.3
+distlib==0.3.6
     # via virtualenv
-filelock==3.3.2
+exceptiongroup==1.0.0
+    # via pytest
+filelock==3.8.0
     # via
     #   tox
     #   virtualenv
-flake8==4.0.1
+flake8==5.0.4
     # via
-    #   -r .\dev-requirements.in
-    #   flake8-polyfill
+    #   -r dev-requirements.in
     #   pep8-naming
-flake8-polyfill==1.0.2
-    # via pep8-naming
 iniconfig==1.1.1
     # via pytest
-isort==5.10.0
-    # via -r .\dev-requirements.in
-mccabe==0.6.1
+isort==5.10.1
+    # via -r dev-requirements.in
+mccabe==0.7.0
     # via flake8
-mypy==0.910
-    # via -r .\dev-requirements.in
+mypy==0.982
+    # via -r dev-requirements.in
 mypy-extensions==0.4.3
     # via
     #   black
     #   mypy
-packaging==21.2
+packaging==21.3
     # via
     #   pytest
     #   tox
-pathspec==0.9.0
+pathspec==0.10.1
     # via black
-pep8-naming==0.12.1
-    # via -r .\dev-requirements.in
-platformdirs==2.4.0
+pep8-naming==0.13.2
+    # via -r dev-requirements.in
+platformdirs==2.5.2
     # via
     #   black
     #   virtualenv
@@ -63,41 +53,31 @@ pluggy==1.0.0
     #   pytest
     #   tox
 py==1.11.0
-    # via
-    #   pytest
-    #   tox
-pycodestyle==2.8.0
+    # via tox
+pycodestyle==2.9.1
     # via flake8
-pyflakes==2.4.0
+pyflakes==2.5.0
     # via flake8
-pyparsing==2.4.7
+pyparsing==3.0.9
     # via packaging
-pytest==6.2.5
+pytest==7.2.0
     # via
-    #   -r .\dev-requirements.in
+    #   -r dev-requirements.in
     #   pytest-cov
-pytest-cov==3.0.0
-    # via -r .\dev-requirements.in
-regex==2021.11.2
-    # via black
+pytest-cov==4.0.0
+    # via -r dev-requirements.in
 six==1.16.0
-    # via
-    #   tox
-    #   virtualenv
-toml==0.10.2
-    # via
-    #   mypy
-    #   pytest
-    #   tox
-tomli==1.2.2
+    # via tox
+tomli==2.0.1
     # via
     #   black
     #   coverage
-tox==3.24.4
-    # via -r .\dev-requirements.in
-typing-extensions==3.10.0.2
-    # via
-    #   black
     #   mypy
-virtualenv==20.10.0
+    #   pytest
+    #   tox
+tox==3.27.0
+    # via -r dev-requirements.in
+typing-extensions==4.4.0
+    # via mypy
+virtualenv==20.16.6
     # via tox
diff --git a/exitstatus.py b/exitstatus/__init__.py
similarity index 100%
rename from exitstatus.py
rename to exitstatus/__init__.py
diff --git a/exitstatus/py.typed b/exitstatus/py.typed
new file mode 100644
index 0000000..5f3ea3d
--- /dev/null
+++ b/exitstatus/py.typed
@@ -0,0 +1,2 @@
+# Instruct type checkers to look for inline type annotations in this package.
+# See PEP 561.
diff --git a/pyproject.toml b/pyproject.toml
index f2d391e..93edabe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,7 @@ strict = true
 
 [tool.black]
 line-length = 99
-target-version = ["py36", "py37", "py38"]
+target-version = ["py38", "py39", "py310"]
 
 [tool.isort]
 profile = "black"
@@ -16,6 +16,11 @@ line_length = 99
 force_sort_within_sections = true
 skip_gitignore = true
 
+[tool.pytest.ini_options]
+filterwarnings = [
+    "error",
+]
+
 [tool.coverage.run]
 branch = true
 omit = [".tox/*", "setup.py"]
diff --git a/setup.py b/setup.py
index 79284f3..7d7009d 100644
--- a/setup.py
+++ b/setup.py
@@ -6,15 +6,16 @@
 
 setuptools.setup(
     name="exitstatus",
-    version="2.2.0",
+    version="2.3.0",
     description="POSIX exit status codes",
     long_description=project_dir.joinpath("README.rst").read_text(encoding="utf-8"),
     keywords="exit status POSIX",
     author="John Hagen",
     author_email="johnthagen@gmail.com",
     url="https://github.com/johnthagen/exitstatus",
-    py_modules=["exitstatus"],
-    python_requires=">=3.7",
+    packages=["exitstatus"],
+    package_data={"exitstatus": ["py.typed"]},
+    python_requires=">=3.8",
     zip_safe=False,
     license="MIT",
     license_files=["LICENSE.txt"],
@@ -25,9 +26,9 @@
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
+        "Typing :: Typed",
     ],
 )
diff --git a/tox.ini b/tox.ini
index 74702ab..9dde57e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,8 +6,6 @@ extend-exclude =
 
 [gh-actions]
 python =
-    3.6: py36
-    3.7: py37
     3.8: py38, fmt-check, lint, type-check
     3.9: py39
     3.10: py310
@@ -17,18 +15,18 @@ envlist =
     fmt-check
     lint
     type-check
-    py{37,38,39,310}
+    py{38,39,310}
 skip_missing_interpreters = true
 isolated_build = true
 
 [testenv]
-passenv = CI TRAVIS TRAVIS_*
+passenv = CI
 deps =
     -r{toxinidir}/dev-requirements.txt
     codecov
 
 commands =
-    python -bb -Werror -m pytest --cov=./ tests.py {posargs}
+    python -m pytest --cov=exitstatus tests {posargs}
     codecov -e TOXENV
 
 [testenv:lint]
@@ -41,7 +39,7 @@ commands =
 [testenv:type-check]
 skip_install = true
 commands =
-    mypy exitstatus.py
+    mypy exitstatus
 
 [testenv:fmt]
 skip_install = true


Test patch:
diff --git a/tests.py b/tests.py
deleted file mode 100644
index 36cf775..0000000
--- a/tests.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import sys
-import unittest
-
-from exitstatus import ExitStatus
-
-
-class ExitStatusTestCase(unittest.TestCase):
-    def test_equality(self) -> None:
-        self.assertEqual(ExitStatus.success, 0)
-        self.assertEqual(ExitStatus.failure, 1)
-
-    def test_value(self) -> None:
-        self.assertEqual(ExitStatus.success.value, 0)
-        self.assertEqual(ExitStatus.failure.value, 1)
-
-    def test_identity(self) -> None:
-        self.assertIs(ExitStatus.success, ExitStatus.success)
-        self.assertIsNot(ExitStatus.success, ExitStatus.failure)
-
-    def test_sys_exit(self) -> None:
-        with self.assertRaises(SystemExit):
-            sys.exit(ExitStatus.success)
-
-    def test_exit(self) -> None:
-        with self.assertRaises(SystemExit):
-            exit(ExitStatus.success)
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_exitstatus.py b/tests/test_exitstatus.py
new file mode 100644
index 0000000..26f7f0c
--- /dev/null
+++ b/tests/test_exitstatus.py
@@ -0,0 +1,30 @@
+import sys
+
+import pytest
+
+from exitstatus import ExitStatus
+
+
+def test_equality() -> None:
+    assert ExitStatus.success == 0
+    assert ExitStatus.failure == 1
+
+
+def test_value() -> None:
+    assert ExitStatus.success.value == 0
+    assert ExitStatus.failure.value == 1
+
+
+def test_identity() -> None:
+    assert ExitStatus.success is ExitStatus.success
+    assert ExitStatus.success is not ExitStatus.failure
+
+
+def test_sys_exit() -> None:
+    with pytest.raises(SystemExit):
+        sys.exit(ExitStatus.success)
+
+
+def test_exit() -> None:
+    with pytest.raises(SystemExit):
+        exit(ExitStatus.success)