Skip to content

Commit

Permalink
Merge pull request #36 from TeamSpen210/typing
Browse files Browse the repository at this point in the history
Add type hints
  • Loading branch information
VincentVanlaer authored Sep 18, 2023
2 parents 65ab938 + e78527c commit a6144a1
Show file tree
Hide file tree
Showing 16 changed files with 439 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ htmlcov/
.coverage.*
.cache
.pytest_cache
.mypy_cache
nosetests.xml
coverage.xml

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include README.rst CHEATSHEET.rst LICENSE* CODE_OF_CONDUCT* CONTRIBUTING*
include .coveragerc .style.yapf
include test-requirements.txt
include src/outcome/py.typed
recursive-include docs *
prune docs/build
recursive-include tests *.py
48 changes: 41 additions & 7 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ pip install -U pip setuptools wheel
python setup.py sdist --formats=zip
pip install dist/*.zip

# Install dependencies.
pip install -Ur test-requirements.txt

if [ "$CHECK_FORMATTING" = "1" ]; then
pip install yapf==${YAPF_VERSION} isort>=5
pip install yapf==${YAPF_VERSION} isort>=5 mypy pyright
if ! yapf -rpd setup.py src tests; then
cat <<EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Expand All @@ -29,9 +32,6 @@ EOF
exit 1
fi

# required for isort to order test imports correctly
pip install -Ur test-requirements.txt

if ! isort --check-only --diff . ; then
cat <<EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Expand All @@ -49,12 +49,46 @@ in your local checkout.
EOF
exit 1
fi

if ! mypy src/ tests/type_tests.py ; then
cat <<EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Type checking errors were found (listed above). To get more detail, run
pip install mypy
mypy src/ tests/type_tests.py
in your local checkout.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
EOF
exit 1
fi

if ! pyright --verifytypes outcome src/outcome/ ; then
cat <<EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Types are not complete (listed above). To get more detail, run
pip install pyright
pyright --verifytypes outcome src/outcome/
in your local checkout.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
EOF
exit 1
fi

exit 0
fi

# Actual tests
pip install -Ur test-requirements.txt

pytest -W error -ra -v tests --cov --cov-config=.coveragerc

bash <(curl -s https://codecov.io/bash)
2 changes: 1 addition & 1 deletion ci/rtd-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RTD is currently installing 1.5.3, which has a bug in :lineno-match:
sphinx >= 1.6.1
sphinx >= 4.0, < 6.2
sphinx_rtd_theme
sphinxcontrib-trio
12 changes: 12 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ API Reference
:members:
:inherited-members:

.. py:data:: Maybe
:value: Value[ResultT] | Error

A convenience alias to a union of both results. This allows type checkers to perform
exhaustiveness checking when ``isinstance()`` is used with either class::

outcome: Maybe[int] = capture(some_function, 1, 2, 3)
if isinstance(outcome, Value):
# Type checkers know it's a Value[int] here.
else:
# It must be an Error.

.. autoclass:: Value
:members:
:inherited-members:
Expand Down
30 changes: 16 additions & 14 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#
import os
import sys

# So autodoc can import our package
sys.path.insert(0, os.path.abspath('../..'))

Expand All @@ -27,6 +28,13 @@
nitpick_ignore = [
# Format is ('sphinx reference type', 'string'), e.g.:
('py:obj', 'bytes-like'),
# Typevars aren't found, for some reason.
('py:class', 'ArgsT'),
('py:class', 'ArgsT.args'),
('py:class', 'ArgsT.kwargs'),
('py:class', 'ResultT'),
('py:class', 'outcome._impl.ResultT'),
('py:class', 'outcome._impl.ValueT'),
]

# -- General configuration ------------------------------------------------
Expand Down Expand Up @@ -76,6 +84,7 @@
#
# The short X.Y version.
import outcome

version = outcome.__version__
# The full version, including alpha/beta/rc tags.
release = version
Expand All @@ -101,7 +110,6 @@
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand All @@ -113,6 +121,7 @@
# testing, but also because if we don't then RTD will throw away our
# html_theme_options.
import sphinx_rtd_theme

html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

Expand All @@ -135,13 +144,11 @@
# so a file named 'default.css' will overwrite the builtin 'default.css'.
html_static_path = ['_static']


# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'outcomedoc'


# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
Expand All @@ -166,28 +173,23 @@
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'outcome.tex', 'Trio Documentation',
author, 'manual'),
(master_doc, 'outcome.tex', 'Trio Documentation', author, 'manual'),
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'outcome', 'outcome Documentation',
[author], 1)
]

man_pages = [(master_doc, 'outcome', 'outcome Documentation', [author], 1)]

# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'outcome', 'outcome Documentation',
author, 'outcome', 'Capture the outcome of Python function call.',
'Miscellaneous'),
(
master_doc, 'outcome', 'outcome Documentation', author, 'outcome',
'Capture the outcome of Python function call.', 'Miscellaneous'
),
]
3 changes: 3 additions & 0 deletions newsfragments/36.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added type hints to the package. :py:class:`Value` and :py:class`Outcome` are now generic.
A type alias was also added (:py:data:`Maybe`) for the union of :py:class:`Value`
and :py:class:`Error`.
30 changes: 30 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,33 @@ filename = "docs/source/history.rst"
directory = "newsfragments"
underlines = ["-", "~", "^"]
issue_format = "`#{issue} <https://github.com/python-trio/outcome/issues/{issue}>`__"

[tool.isort]
combine_as_imports = true
profile = "black"
skip_gitignore = true

[tool.mypy]
# Be strict about use of Mypy
strict = true
warn_unused_ignores = true
warn_unused_configs = true
warn_redundant_casts = true
warn_no_return = true
warn_unreachable = true
warn_return_any = true

# Avoid subtle backsliding
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_any_unimported = true
disallow_any_generics = true
disallow_any_explicit = false

check_untyped_defs = true
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_untyped_decorators = true

# DO NOT use `ignore_errors`; it doesn't apply
# downstream and users have to deal with them.
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ branch = True
source =
outcome
tests/
omit =
tests/type_tests.py

[coverage:report]
precision = 1
exclude_lines =
pragma: no cover
abc.abstractmethod
if TYPE_CHECKING:
@overload

[tool:pytest]
asyncio_mode = strict
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
license='MIT OR Apache-2.0',
packages=find_packages('src'),
package_dir={'': 'src'},
include_package_data=True,
install_requires=['attrs>=19.2.0'],
python_requires='>=3.7',
keywords='result',
Expand Down
16 changes: 12 additions & 4 deletions src/outcome/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"""Top-level package for outcome."""

from ._impl import Error, Outcome, Value, acapture, capture
from ._util import AlreadyUsedError, fixup_module_metadata
from ._version import __version__
from ._impl import (
Error as Error,
Maybe as Maybe,
Outcome as Outcome,
Value as Value,
acapture as acapture,
capture as capture,
)
from ._util import AlreadyUsedError as AlreadyUsedError, fixup_module_metadata
from ._version import __version__ as __version__

__all__ = (
'Error', 'Outcome', 'Value', 'acapture', 'capture', 'AlreadyUsedError'
'Error', 'Outcome', 'Value', 'Maybe', 'acapture', 'capture',
'AlreadyUsedError'
)

fixup_module_metadata(__name__, globals())
Expand Down
Loading

0 comments on commit a6144a1

Please sign in to comment.