diff --git a/.gitignore b/.gitignore index b6cc1d81..43410472 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ dist/ *.egg-info/ **/*.pyc + +# Sphinx +/docs/build/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..6247f7e2 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/_static/royalblue.css b/docs/source/_static/royalblue.css new file mode 100644 index 00000000..d98fc068 --- /dev/null +++ b/docs/source/_static/royalblue.css @@ -0,0 +1,3 @@ +.wy-side-nav-search, .wy-nav-top { + background-color: #0d193b !important; +} diff --git a/docs/source/autodoc/alchemist.rst b/docs/source/autodoc/alchemist.rst new file mode 100644 index 00000000..e78f91e5 --- /dev/null +++ b/docs/source/autodoc/alchemist.rst @@ -0,0 +1,7 @@ +Alchemist autodoc +================= + +.. currentmodule:: royalnet.alchemist +.. automodule:: royalnet.alchemist + :members: + :undoc-members: diff --git a/docs/source/autodoc/baron.rst b/docs/source/autodoc/baron.rst new file mode 100644 index 00000000..22ffb8b9 --- /dev/null +++ b/docs/source/autodoc/baron.rst @@ -0,0 +1,7 @@ +Baron autodoc +================= + +.. currentmodule:: royalnet.baron +.. automodule:: royalnet.baron + :members: + :undoc-members: diff --git a/docs/source/autodoc/campaigns.rst b/docs/source/autodoc/campaigns.rst new file mode 100644 index 00000000..8d029772 --- /dev/null +++ b/docs/source/autodoc/campaigns.rst @@ -0,0 +1,7 @@ +Campaigns autodoc +================= + +.. currentmodule:: royalnet.campaigns +.. automodule:: royalnet.campaigns + :members: + :undoc-members: diff --git a/docs/source/autodoc/index.rst b/docs/source/autodoc/index.rst new file mode 100644 index 00000000..da4b4caa --- /dev/null +++ b/docs/source/autodoc/index.rst @@ -0,0 +1,15 @@ +Autogenerated documentation +=========================== + +Welcome to the autogenerated documentation of Royalnet 6! + +It may be incomplete or outdated, as it is automatically updated. + +.. toctree:: + :maxdepth: 3 + + alchemist + baron + campaigns + scrolls + typing diff --git a/docs/source/autodoc/scrolls.rst b/docs/source/autodoc/scrolls.rst new file mode 100644 index 00000000..d1dfc879 --- /dev/null +++ b/docs/source/autodoc/scrolls.rst @@ -0,0 +1,7 @@ +Scrolls autodoc +================= + +.. currentmodule:: royalnet.scrolls +.. automodule:: royalnet.scrolls + :members: + :undoc-members: diff --git a/docs/source/autodoc/typing.rst b/docs/source/autodoc/typing.rst new file mode 100644 index 00000000..b7e75a5f --- /dev/null +++ b/docs/source/autodoc/typing.rst @@ -0,0 +1,7 @@ +Typing autodoc +================= + +.. currentmodule:: royalnet.typing +.. automodule:: royalnet.typing + :members: + :undoc-members: diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..ce676d70 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,84 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# 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. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'royalnet' +# noinspection PyShadowingBuiltins +copyright = '2020, Stefano Pigozzi' +author = 'Stefano Pigozzi' + +# The full version, including alpha/beta/rc tags +release = '6.0.0a12' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['Thumbs.db', '.DS_Store'] + +# Print warnings on the page +keep_warnings = True + +# Display more warnings than usual +nitpicky = True + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Intersphinx options ----------------------------------------------------- + +intersphinx_mapping = { + "python": ("https://docs.python.org/3.8", None), + "sqlalchemy": ("https://docs.sqlalchemy.org/en/13/", None), +} + + +# -- Setup function ---------------------------------------------------------- +def setup(app): + app.connect("autodoc-skip-member", skip) + app.add_css_file('royalblue.css') + + +# -- Skip function ----------------------------------------------------------- +def skip(app, what, name: str, obj, would_skip, options): + if name == "__init__" or name == "__getitem__" or name == "__getattr__": + return not bool(obj.__doc__) + return would_skip diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..9d722c51 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,27 @@ +Royalnet 6 +========== + +Welcome to the documentation of Royalnet 6! + + +Table of contents +----------------- + +.. toctree:: + :maxdepth: 3 + + autodoc/index + + +Useful links +------------ + +* `Royalnet on GitHub `_ + + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/poetry.lock b/poetry.lock index bbe41456..66b1cdc9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +name = "alabaster" +version = "0.7.12" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "atomicwrites" version = "1.4.0" @@ -21,6 +29,33 @@ docs = ["furo", "sphinx", "zope.interface"] tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +[[package]] +name = "babel" +version = "2.9.0" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pytz = ">=2015.7" + +[[package]] +name = "certifi" +version = "2020.11.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "colorama" version = "0.4.4" @@ -30,6 +65,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" marker = "sys_platform == \"win32\"" +[[package]] +name = "docutils" +version = "0.16" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "hiredis" version = "1.1.0" @@ -38,6 +81,22 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "imagesize" +version = "1.2.0" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "iniconfig" version = "1.1.1" @@ -46,6 +105,28 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "jinja2" +version = "2.11.2" +description = "A very fast and expressive template engine." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +i18n = ["Babel (>=0.8)"] + +[package.dependencies] +MarkupSafe = ">=0.23" + +[[package]] +name = "markupsafe" +version = "1.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + [[package]] name = "packaging" version = "20.4" @@ -77,6 +158,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pygments" +version = "2.7.2" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "pyparsing" version = "2.4.7" @@ -121,6 +210,14 @@ testing = ["async-generator (>=1.3)", "coverage", "hypothesis (>=5.7.1)"] [package.dependencies] pytest = ">=5.4.0" +[[package]] +name = "pytz" +version = "2020.4" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "redis" version = "3.5.3" @@ -132,6 +229,24 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] hiredis = ["hiredis (>=0.1.3)"] +[[package]] +name = "requests" +version = "2.25.0" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.27" + [[package]] name = "six" version = "1.15.0" @@ -140,6 +255,131 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "snowballstemmer" +version = "2.0.0" +description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "sphinx" +version = "3.3.1" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.790)", "docutils-stubs"] +test = ["pytest", "pytest-cov", "html5lib", "typed-ast", "cython"] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = ">=0.3.5" +docutils = ">=0.12" +imagesize = "*" +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +setuptools = "*" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = "*" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = "*" + +[[package]] +name = "sphinx-rtd-theme" +version = "0.5.0" +description = "Read the Docs theme for Sphinx" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] + +[package.dependencies] +sphinx = "*" + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "1.0.3" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest", "html5lib"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest", "flake8", "mypy"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.4" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + [[package]] name = "sqlalchemy" version = "1.3.20" @@ -168,12 +408,29 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "urllib3" +version = "1.26.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + [metadata] lock-version = "1.0" python-versions = "^3.8" -content-hash = "18a020f5e5899c078cd9c6fe98f82323ce5c0d6f9c7301a0ebc5e3ac1ea69193" +content-hash = "2557b06a77cba254237fac5205fcbd9f9e1ee886837903af646f15b65812abb0" [metadata.files] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, @@ -182,10 +439,26 @@ attrs = [ {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] +babel = [ + {file = "Babel-2.9.0-py2.py3-none-any.whl", hash = "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5"}, + {file = "Babel-2.9.0.tar.gz", hash = "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"}, +] +certifi = [ + {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"}, + {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +docutils = [ + {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, + {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, +] hiredis = [ {file = "hiredis-1.1.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:289b31885b4996ce04cadfd5fc03d034dce8e2a8234479f7c9e23b9e245db06b"}, {file = "hiredis-1.1.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7b0f63f10a166583ab744a58baad04e0f52cfea1ac27bfa1b0c21a48d1003c23"}, @@ -234,10 +507,57 @@ hiredis = [ {file = "hiredis-1.1.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:3ef2183de67b59930d2db8b8e8d4d58e00a50fcc5e92f4f678f6eed7a1c72d55"}, {file = "hiredis-1.1.0.tar.gz", hash = "sha256:996021ef33e0f50b97ff2d6b5f422a0fe5577de21a8873b58a779a5ddd1c3132"}, ] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +imagesize = [ + {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, + {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, +] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +jinja2 = [ + {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, + {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, +] +markupsafe = [ + {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, +] packaging = [ {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, @@ -250,6 +570,10 @@ py = [ {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, ] +pygments = [ + {file = "Pygments-2.7.2-py3-none-any.whl", hash = "sha256:88a0bbcd659fcb9573703957c6b9cff9fab7295e6e76db54c9d00ae42df32773"}, + {file = "Pygments-2.7.2.tar.gz", hash = "sha256:381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0"}, +] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, @@ -262,14 +586,58 @@ pytest-asyncio = [ {file = "pytest-asyncio-0.14.0.tar.gz", hash = "sha256:9882c0c6b24429449f5f969a5158b528f39bde47dc32e85b9f0403965017e700"}, {file = "pytest_asyncio-0.14.0-py3-none-any.whl", hash = "sha256:2eae1e34f6c68fc0a9dc12d4bea190483843ff4708d24277c41568d6b6044f1d"}, ] +pytz = [ + {file = "pytz-2020.4-py2.py3-none-any.whl", hash = "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd"}, + {file = "pytz-2020.4.tar.gz", hash = "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268"}, +] redis = [ {file = "redis-3.5.3-py2.py3-none-any.whl", hash = "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"}, {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"}, ] +requests = [ + {file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"}, + {file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"}, +] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] +snowballstemmer = [ + {file = "snowballstemmer-2.0.0-py2.py3-none-any.whl", hash = "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0"}, + {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, +] +sphinx = [ + {file = "Sphinx-3.3.1-py3-none-any.whl", hash = "sha256:d4e59ad4ea55efbb3c05cde3bfc83bfc14f0c95aa95c3d75346fcce186a47960"}, + {file = "Sphinx-3.3.1.tar.gz", hash = "sha256:1e8d592225447104d1172be415bc2972bd1357e3e12fdc76edf2261105db4300"}, +] +sphinx-rtd-theme = [ + {file = "sphinx_rtd_theme-0.5.0-py2.py3-none-any.whl", hash = "sha256:373413d0f82425aaa28fb288009bf0d0964711d347763af2f1b65cafcb028c82"}, + {file = "sphinx_rtd_theme-0.5.0.tar.gz", hash = "sha256:22c795ba2832a169ca301cd0a083f7a434e09c538c70beb42782c073651b707d"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-1.0.3.tar.gz", hash = "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"}, + {file = "sphinxcontrib_htmlhelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.4.tar.gz", hash = "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc"}, + {file = "sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl", hash = "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"}, +] sqlalchemy = [ {file = "SQLAlchemy-1.3.20-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bad73f9888d30f9e1d57ac8829f8a12091bdee4949b91db279569774a866a18e"}, {file = "SQLAlchemy-1.3.20-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:e32e3455db14602b6117f0f422f46bc297a3853ae2c322ecd1e2c4c04daf6ed5"}, @@ -314,3 +682,7 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +urllib3 = [ + {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, + {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, +] diff --git a/pyproject.toml b/pyproject.toml index 925423e4..89bbdec1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,8 @@ toml = "^0.10.1" [tool.poetry.dev-dependencies] pytest = "^6.1.1" pytest-asyncio = "^0.14.0" +sphinx = "^3.3.1" +sphinx_rtd_theme = "^0.5.0" [build-system] requires = ["poetry>=0.12"] diff --git a/royalnet/alchemist/__init__.py b/royalnet/alchemist/__init__.py index 67d160d4..336fc481 100644 --- a/royalnet/alchemist/__init__.py +++ b/royalnet/alchemist/__init__.py @@ -1,4 +1,18 @@ +""" +This module defines multiple objects that simplify some :mod:`sqlalchemy` tasks. +""" + from .func import * from .make import * from .repr import * from .update import * + +__all__ = ( + "ieq", + "ineq", + "Makeable", + "ColRepr", + "Updatable", + "DoNotUpdateType", + "DoNotUpdate", +) diff --git a/royalnet/alchemist/func.py b/royalnet/alchemist/func.py index 0afa985f..ff6a3db0 100644 --- a/royalnet/alchemist/func.py +++ b/royalnet/alchemist/func.py @@ -3,22 +3,24 @@ import sqlalchemy def ieq(one, two): """ - Create a case-insensitive equality filter for SQLAlchemy. :: + Create a case-insensitive equality filter to be used in :meth:`sqlalchemy.orm.query.Query.filter`. + + Equal to: :: lower(one) == lower(two) - """ return sqlalchemy.func.lower(one) == sqlalchemy.func.lower(two) def ineq(one, two): """ - Create a case-insensitive inequality filter for SQLAlchemy. :: + Create a case-insensitive inequality filter to be used in :meth:`sqlalchemy.orm.query.Query.filter`. + + Equal to: :: lower(one) != lower(two) - """ return sqlalchemy.func.lower(one) != sqlalchemy.func.lower(two) diff --git a/royalnet/alchemist/make.py b/royalnet/alchemist/make.py index a930e41c..b223889e 100644 --- a/royalnet/alchemist/make.py +++ b/royalnet/alchemist/make.py @@ -17,7 +17,8 @@ class Makeable: Find the item with the specified name, or create it if it doesn't exist. :param session: The session to be used in the query and creation. - :param kwargs: Arguments to use in the filter_by clause and in the item constructor. + :param kwargs: Arguments to use in the :meth:`~sqlalchemy.orm.query.Query.filter_by` clause and in the item + constructor. :return: The retrieved or created item. """ # Find the item @@ -35,7 +36,8 @@ class Makeable: Find the item with the specified name, and delete it if it exists. :param session: The session to be used in the query and creation. - :param kwargs: Arguments to use in the filter_by clause and in the item constructor. + :param kwargs: Arguments to use in the :meth:`~sqlalchemy.orm.query.Query.filter_by` clause and in the item + constructor. """ # Find the item item = session.query(cls).filter_by(**kwargs).one_or_none() diff --git a/royalnet/alchemist/repr.py b/royalnet/alchemist/repr.py index d2ca235c..2bc1482f 100644 --- a/royalnet/alchemist/repr.py +++ b/royalnet/alchemist/repr.py @@ -1,6 +1,7 @@ class ColRepr: """ - A mixin that can be added to a declared class to display all table columns in the __repr__. + A mixin that can be added to a declared class to display all columns of the table with their values in the + ``__repr__``. """ def __repr__(self): diff --git a/royalnet/alchemist/update.py b/royalnet/alchemist/update.py index fc513637..ad756525 100644 --- a/royalnet/alchemist/update.py +++ b/royalnet/alchemist/update.py @@ -1,11 +1,11 @@ class Updatable: """ A mixin that can be added to a declared class to add update methods, allowing attributes to be set from - a dict. + a :class:`dict`. """ def update(self, **kwargs): - """Set attributes from the kwargs, ignoring non-existant key/columns.""" + """Set attributes from the ``kwargs``, ignoring non-existant key/columns.""" for key, value in kwargs.items(): if value is DoNotUpdate: continue @@ -13,7 +13,7 @@ class Updatable: setattr(self, key, value) def set(self, **kwargs): - """Set attributes from the kwargs, without checking for non-existant key/columns.""" + """Set attributes from the ``kwargs``, without checking for non-existant key/columns.""" for key, value in kwargs.items(): if value is DoNotUpdate: continue @@ -22,7 +22,7 @@ class Updatable: class DoNotUpdateType: """ - A type, similar to NoneType, used to mark fields that should be skipped in update and set operations. + A type, similar to :data:`None`, used to mark fields that should be skipped in update and set operations. """ __slots__ = () diff --git a/royalnet/baron/__init__.py b/royalnet/baron/__init__.py index 0c492725..ea40c692 100644 --- a/royalnet/baron/__init__.py +++ b/royalnet/baron/__init__.py @@ -1,8 +1,18 @@ +""" +.. deprecated:: 6.0.0a13 + +This module defines a class that can be used to easily load configuration from a :mod:`json` or :mod:`toml` file and +from :data:`os.environ`. +""" + from __future__ import annotations from royalnet.typing import * import threading import redis +import warnings +warnings.warn("The Baron module is deprecated", DeprecationWarning, stacklevel=2) + __all__ = ( "Baron", diff --git a/royalnet/campaigns/__init__.py b/royalnet/campaigns/__init__.py index d6a02a7a..3324b8e8 100644 --- a/royalnet/campaigns/__init__.py +++ b/royalnet/campaigns/__init__.py @@ -1,3 +1,8 @@ +""" +This module defines multiple classes that can be used to facilitate the implementation of a conversational interface +in chat bots. +""" + from .campaign import * from .asynccampaign import * from .challenge import * diff --git a/royalnet/campaigns/asynccampaign.py b/royalnet/campaigns/asynccampaign.py index 14ac6a44..ff35b2b9 100644 --- a/royalnet/campaigns/asynccampaign.py +++ b/royalnet/campaigns/asynccampaign.py @@ -17,16 +17,17 @@ class AsyncCampaign: The AsyncCampaign module allows for branching asyncgenerator-based back-and-forths between the software and the user. - An AsyncCampaign consists of multiple chained AsyncAdventures, which are AsyncGenerators yielding tuples with an + An :class:`.AsyncCampaign` consists of multiple chained AsyncAdventures, which are AsyncGenerators yielding tuples + with an AsyncChallenge and optional data. """ def __init__(self, start: AsyncAdventure, challenge: Optional[AsyncChallenge], *args, **kwargs): """ - Initialize an AsyncCampaign object. + Initialize an :class:`.AsyncCampaign` object. - .. warning:: Do not use this, use the AsyncCampaign.create() method instead! + .. warning:: Do not use this, use the :meth:`.create()` method instead! - :param start: The starting adventure for the AsyncCampaign. + :param start: The starting adventure for the :class:`.AsyncCampaign`. """ self.adventure: AsyncAdventure = start self.challenge: AsyncChallenge = challenge or TrueAsyncChallenge() @@ -35,11 +36,11 @@ class AsyncCampaign: @classmethod async def create(cls, start: AsyncAdventure, challenge: Optional[AsyncChallenge] = None, *args, **kwargs) -> AsyncCampaign: """ - Create a new AsyncCampaign object. + Create a new :class:`.AsyncCampaign` object. - :param start: The starting Adventure for the AsyncCampaign. + :param start: The starting Adventure for the :class:`.AsyncCampaign`. :param challenge: The AsyncChallenge the campaign should start with. - :return: The created AsyncCampaign. + :return: The created :class:`.AsyncCampaign`. """ campaign = cls(start=start, challenge=challenge, *args, **kwargs) await campaign._asend(None) @@ -68,7 +69,7 @@ class AsyncCampaign: async def next(self, data: Any = None) -> List: """ - Try to advance the AsyncCampaign with the passed data. + Try to advance the :class:`.AsyncCampaign` with the passed data. :param data: The data to pass to the current AsyncAdventure. :return: Optional additional data returned by the AsyncAdventure. diff --git a/royalnet/campaigns/asyncchallenge.py b/royalnet/campaigns/asyncchallenge.py index 125c35ba..3d03ebf0 100644 --- a/royalnet/campaigns/asyncchallenge.py +++ b/royalnet/campaigns/asyncchallenge.py @@ -8,7 +8,7 @@ __all__ = ( class AsyncChallenge(metaclass=abc.ABCMeta): - """A filter for inputs passed to an AsyncCampaign.""" + """A filter for inputs passed to an :class:`.AsyncCampaign`.""" @abc.abstractmethod async def filter(self, data: Any) -> bool: @@ -17,7 +17,8 @@ class AsyncChallenge(metaclass=abc.ABCMeta): class TrueAsyncChallenge(AsyncChallenge): - """An AsyncChallenge which always returns True.""" + """An :class:`.AsyncChallenge` which always returns :data:`True`.""" async def filter(self, data: Any) -> bool: + """Decide if the data should be skipped or not.""" return True diff --git a/royalnet/campaigns/campaign.py b/royalnet/campaigns/campaign.py index 015c8d4f..a11db6e5 100644 --- a/royalnet/campaigns/campaign.py +++ b/royalnet/campaigns/campaign.py @@ -17,15 +17,15 @@ class Campaign: The Campaign module allows for branching generator-based back-and-forths between the software and the user. - A Campaign consists of multiple chained Adventures, which are Generators yielding tuples with a Campaign and - optional data. + A :class:`.Campaign` consists of multiple chained Adventures, which are Generators yielding tuples with a + :class:`.Campaign` and optional data. """ def __init__(self, start: Adventure, challenge: Optional[Challenge] = None, *args, **kwargs): """ - Initialize a Campaign object. + Initialize a :class:`.Campaign` object. - .. warning:: Do not use this, use the Campaign.create() method instead! + .. warning:: Do not use this, use the :meth:`.create` method instead! """ self.adventure: Adventure = start self.challenge: Challenge = challenge or TrueChallenge() @@ -34,11 +34,11 @@ class Campaign: @classmethod def create(cls, start: Adventure, challenge: Optional[Challenge] = None, *args, **kwargs) -> Campaign: """ - Create a new Campaign object. + Create a new :class:`.Campaign` object. - :param start: The starting Adventure for the Campaign. - :param challenge: The Challenge the campaign should start with. - :return: The created Campaign. + :param start: The starting Adventure for the :class:`.Campaign`. + :param challenge: The Challenge the :class:`.Campaign` should start with. + :return: The created :class:`.Campaign`. """ campaign = cls(start=start, challenge=challenge, *args, **kwargs) campaign.adventure.send(None) @@ -46,11 +46,11 @@ class Campaign: def next(self, data: Any = None) -> List: """ - Try to advance the Campaign with the passed data. + Try to advance the :class:`.Campaign` with the passed data. :param data: The data to pass to the current Adventure. :return: Optional additional data returned by the Adventure. - :raises ChallengeFailedError: if the data passed fails the Challenge check. + :raises .ChallengeFailedError: if the data passed fails the Challenge check. """ self.last_update = datetime.datetime.now() if not self.challenge.filter(data): diff --git a/royalnet/campaigns/challenge.py b/royalnet/campaigns/challenge.py index 90bf1635..20c3003d 100644 --- a/royalnet/campaigns/challenge.py +++ b/royalnet/campaigns/challenge.py @@ -8,7 +8,7 @@ __all__ = ( class Challenge(metaclass=abc.ABCMeta): - """A filter for inputs passed to a Campaign.""" + """A filter for inputs passed to a :class:`.Campaign`.""" @abc.abstractmethod def filter(self, data: Any) -> bool: @@ -17,7 +17,8 @@ class Challenge(metaclass=abc.ABCMeta): class TrueChallenge(Challenge): - """A Challenge which always returns True.""" + """A :class:`.Challenge` which always returns :data:`True`.""" async def filter(self, data: Any) -> bool: + """Decide if the data should be skipped or not.""" return True diff --git a/royalnet/campaigns/exc.py b/royalnet/campaigns/exc.py index 2e1a0af0..7a9d039f 100644 --- a/royalnet/campaigns/exc.py +++ b/royalnet/campaigns/exc.py @@ -2,7 +2,9 @@ from ..exc import RoyalnetException class CampaignsError(RoyalnetException): - """An error related to the campaigns module.""" + """ + An error related to the campaigns module. + """ class ChallengeFailedError(CampaignsError): diff --git a/royalnet/scrolls/__init__.py b/royalnet/scrolls/__init__.py index 1764ee8e..0c8e0c89 100644 --- a/royalnet/scrolls/__init__.py +++ b/royalnet/scrolls/__init__.py @@ -1,3 +1,9 @@ +""" +This module defines a class that can be used to easily load configuration from a :mod:`json` or :mod:`toml` file and +from :data:`os.environ`. +""" + +from __future__ import annotations from royalnet.typing import * import os import re @@ -8,33 +14,65 @@ from .exc import * class Scroll: - """A configuration handler that allows getting values from both the environment variables and a config file.""" + """ + A configuration handler that allows getting values from both the environment variables and a config file. + """ key_validator = re.compile(r"^[A-Za-z.]+$") + """ + A regex used to validate config keys. + """ loaders = { ".json": json.load, ".toml": toml.load } + """ + An extension to deserialization function map. + """ def __init__(self, namespace: str, config: Optional[Dict[str, JSON]] = None): self.namespace: str = namespace self.config: Optional[Dict[str, JSON]] = config @classmethod - def from_toml(cls, namespace: str, file_path: os.PathLike): + def from_toml(cls, namespace: str, file_path: os.PathLike) -> Scroll: + """ + Create a new :class:`.Scroll` from a :mod:`toml` file. + + :param namespace: A string prefixed to the environment variable keys to disambiguate between multiple scroll + objects. + :param file_path: The path of the :mod:`toml` file to load. + :return: The created :class:`.Scroll` object. + """ with open(file_path) as file: config = toml.load(file) return cls(namespace, config) @classmethod - def from_json(cls, namespace: str, file_path: os.PathLike): + def from_json(cls, namespace: str, file_path: os.PathLike) -> Scroll: + """ + Create a new :class:`.Scroll` from a :mod:`json` file. + + :param namespace: A string prefixed to the environment variable keys to disambiguate between multiple scroll + objects. + :param file_path: The path of the :mod:`json` file to load. + :return: The created :class:`.Scroll` object. + """ with open(file_path) as file: config = json.load(file) return cls(namespace, config) @classmethod - def from_file(cls, namespace: str, file_path: os.PathLike): + def from_file(cls, namespace: str, file_path: os.PathLike) -> Scroll: + """ + Try to guess the type of the file and create a new :class:`.Scroll` from it. + + :param namespace: A string prefixed to the environment variable keys to disambiguate between multiple scroll + objects. + :param file_path: The path of the file to load. + :return: The created :class:`.Scroll` object. + """ _, ext = os.path.splitext(file_path) lext = ext.lower() diff --git a/royalnet/typing/__init__.py b/royalnet/typing/__init__.py index f0caf8c3..d56058d4 100644 --- a/royalnet/typing/__init__.py +++ b/royalnet/typing/__init__.py @@ -1,4 +1,5 @@ -"""This package adds some new common types to the default typing package. +""" +This module adds some new common types to the default typing package. It should be imported with: :: @@ -14,12 +15,19 @@ JSONScalar = Union[ int, str, ] +""" +A non-recursive JSON value: either :data:`None`, a :class:`float`, a :class:`int` or a :class:`str`. +""" JSON = Union[ JSONScalar, List["JSON"], Dict[str, "JSON"], ] +""" +A recursive JSON value: either a :data:`.JSONScalar`, or a :class:`list` of :data:`.JSON` objects, or a :class:`dict` +of :class:`str` to :data:`.JSON` mappings. +""" Adventure = Generator[ Union[ @@ -34,6 +42,14 @@ Adventure = Generator[ Any, Any, ] +""" +A generator yielding either: + +* a :class:`tuple` of a :class:`.Challenge` and extra data; +* a single :class:`.Challenge`;for SQLAlchemy. +* another :data:`.Adventure`; +* :data:`None`. +""" AsyncAdventure = AsyncGenerator[ Union[ @@ -47,3 +63,11 @@ AsyncAdventure = AsyncGenerator[ ], Any, ] +""" +An async generator yielding either: + +* a :class:`tuple` of an :class:`.AsyncChallenge` and extra data; +* a single :class:`.AsyncChallenge`; +* another :data:`.AsyncAdventure`; +* :data:`None`. +"""