diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index fcb2689..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: lint -on: push - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: "3.11.0" - - name: Install poetry - uses: abatilo/actions-poetry@v2 - with: - poetry-version: 1.2.2 - - name: Install dependencies - run: poetry install - - name: Run flake8 - uses: julianwachholz/flake8-action@v2 - with: - checkName: "Python Lint" - path: . - plugins: flake8-spellcheck - config: flake8.ini - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..51832a5 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,622 @@ +[MAIN] + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Load and enable all available extensions. Use --list-extensions to see a list +# all available extensions. +#enable-all-extensions= + +# In error mode, messages with a category besides ERROR or FATAL are +# suppressed, and no reports are done by default. Error mode is compatible with +# disabling specific errors. +#errors-only= + +# Always return a 0 (non-error) status code, even if lint errors are found. +# This is primarily useful in continuous integration scripts. +#exit-zero= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-allow-list= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. (This is an alternative name to extension-pkg-allow-list +# for backward compatibility.) +extension-pkg-whitelist= + +# Return non-zero exit code if any of these messages/categories are detected, +# even if score is above --fail-under value. Syntax same as enable. Messages +# specified are enabled, while categories only check already-enabled messages. +fail-on= + +# Specify a score threshold under which the program will exit with error. +fail-under=10 + +# Interpret the stdin as a python script, whose filename needs to be passed as +# the module_or_package argument. +#from-stdin= + +# Files or directories to be skipped. They should be base names, not paths. +ignore=CVS + +# Add files or directories matching the regular expressions patterns to the +# ignore-list. The regex matches against paths and can be in Posix or Windows +# format. Because '\' represents the directory delimiter on Windows systems, it +# can't be used as an escape character. +ignore-paths= + +# Files or directories matching the regular expression patterns are skipped. +# The regex matches against base names, not paths. The default value ignores +# Emacs file locks +ignore-patterns=^\.# + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use, and will cap the count on Windows to +# avoid hangs. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Minimum Python version to use for version dependent checks. Will default to +# the version used to run pylint. +py-version=3.11 + +# Discover python modules and packages in the file system subtree. +recursive=no + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + +# In verbose mode, extra non-checker-related info will be displayed. +#verbose= + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. If left empty, argument names will be checked with the set +# naming style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. If left empty, attribute names will be checked with the set naming +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs= + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. If left empty, class attribute names will be checked +# with the set naming style. +#class-attribute-rgx= + +# Naming style matching correct class constant names. +class-const-naming-style=UPPER_CASE + +# Regular expression matching correct class constant names. Overrides class- +# const-naming-style. If left empty, class constant names will be checked with +# the set naming style. +#class-const-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. If left empty, class names will be checked with the set naming style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. If left empty, constant names will be checked with the set naming +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. If left empty, function names will be checked with the set +# naming style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. If left empty, inline iteration names will be checked +# with the set naming style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. If left empty, method names will be checked with the set naming style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. If left empty, module names will be checked with the set naming style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Regular expression matching correct type variable names. If left empty, type +# variable names will be checked with the set naming style. +#typevar-rgx= + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. If left empty, variable names will be checked with the set +# naming style. +#variable-rgx= + + +[CLASSES] + +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] + +# List of regular expressions of class ancestor names to ignore when counting +# public methods (see R0903) +exclude-too-few-public-methods= + +# List of qualified class names to ignore when counting class parents (see +# R0901) +ignored-parents= + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when caught. +overgeneral-exceptions=BaseException, + Exception + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules= + +# Output a graph (.gv or any supported image format) of external dependencies +# to the given file (report RP0402 must not be disabled). +ext-import-graph= + +# Output a graph (.gv or any supported image format) of all (i.e. internal and +# external) dependencies to the given file (report RP0402 must not be +# disabled). +import-graph= + +# Output a graph (.gv or any supported image format) of internal dependencies +# to the given file (report RP0402 must not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[LOGGING] + +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, +# UNDEFINED. +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + missing-module-docstring, + missing-class-docstring, + missing-function-docstring, + too-few-public-methods + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[METHOD_ARGS] + +# List of qualified names (i.e., library.method) which require a timeout +# parameter e.g. 'requests.api.get,requests.api.post' +timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + +# Regular expression of note tags to take in consideration. +notes-rgx= + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'fatal', 'error', 'warning', 'refactor', +# 'convention', and 'info' which contain the number of messages in each +# category, as well as 'statement' which is the total number of statements +# analyzed. This score is used by the global evaluation report (RP0004). +evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +#output-format= + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[SIMILARITIES] + +# Comments are removed from the similarity computation +ignore-comments=yes + +# Docstrings are removed from the similarity computation +ignore-docstrings=yes + +# Imports are removed from the similarity computation +ignore-imports=yes + +# Signatures are removed from the similarity computation +ignore-signatures=yes + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it work, +# install the 'python-enchant' package. +spelling-dict= + +# List of comma separated words that should be considered directives if they +# appear at the beginning of a comment and should not be checked. +spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no + +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. +check-str-concat-over-line-jumps=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of symbolic message names to ignore for Mixin members. +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# Regex pattern to define which classes are considered mixins. +mixin-class-rgx=.*[Mm]ixin + +# List of decorators that change the signature of a decorated function. +signature-mutators= + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of names allowed to shadow builtins +allowed-redefined-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4ee41ee --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +all: black test typehint lint + +black: + isort --multi-line 3 --profile black stacosys/ + black stacosys/ + +test: + pytest + +typehint: + mypy --ignore-missing-imports stacosys/ + +lint: + pylint stacosys/ + diff --git a/poetry.lock b/poetry.lock index 010c9fa..2842c27 100644 --- a/poetry.lock +++ b/poetry.lock @@ -26,12 +26,16 @@ twisted = ["twisted"] zookeeper = ["kazoo"] [[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." +name = "astroid" +version = "2.12.12" +description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.7.2" + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} [[package]] name = "attrs" @@ -121,6 +125,9 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +[package.dependencies] +toml = {version = "*", optional = true, markers = "extra == \"toml\""} + [package.extras] toml = ["toml"] @@ -140,6 +147,17 @@ requests = ">=1.0.0" [package.extras] yaml = ["PyYAML (>=3.10)"] +[[package]] +name = "dill" +version = "0.3.6" +description = "serialize all of python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +graph = ["objgraph (>=1.7.2)"] + [[package]] name = "distlib" version = "0.3.6" @@ -231,6 +249,20 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "isort" +version = "5.10.1" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6.1,<4.0" + +[package.extras] +colors = ["colorama (>=0.4.3,<0.5.0)"] +pipfile-deprecated-finder = ["pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + [[package]] name = "itsdangerous" version = "2.1.2" @@ -253,6 +285,14 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "lazy-object-proxy" +version = "1.8.0" +description = "A fast and thorough lazy object proxy." +category = "dev" +optional = false +python-versions = ">=3.7" + [[package]] name = "markdown" version = "3.4.1" @@ -282,19 +322,19 @@ python-versions = ">=3.6" [[package]] name = "mypy" -version = "0.942" +version = "0.991" description = "Optional static typing for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] mypy-extensions = ">=0.4.3" -tomli = ">=1.1.0" typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] python2 = ["typed-ast (>=1.4.0,<2)"] reports = ["lxml"] @@ -381,6 +421,27 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "pylint" +version = "2.15.6" +description = "python code static checker" +category = "dev" +optional = false +python-versions = ">=3.7.2" + +[package.dependencies] +astroid = ">=2.12.12,<=2.14.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = ">=0.2" +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomlkit = ">=0.10.1" + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + [[package]] name = "pyparsing" version = "3.0.9" @@ -402,37 +463,33 @@ python-versions = "*" [[package]] name = "pytest" -version = "6.2.5" +version = "7.2.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pytest-cov" -version = "2.12.1" +version = "4.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -coverage = ">=5.2.1" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" -toml = "*" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] @@ -476,7 +533,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "setuptools" -version = "65.5.1" +version = "65.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "main" optional = false @@ -511,6 +568,14 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "tomlkit" +version = "0.11.6" +description = "Style preserving TOML library" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "tox" version = "3.27.1" @@ -532,6 +597,14 @@ virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2, docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] +[[package]] +name = "types-markdown" +version = "3.4.2.1" +description = "Typing stubs for Markdown" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "typing-extensions" version = "4.4.0" @@ -608,18 +681,27 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog"] +[[package]] +name = "wrapt" +version = "1.14.1" +description = "Module for decorators, wrappers and monkey patching." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + [metadata] lock-version = "1.1" python-versions = "~3.11" -content-hash = "ae1b03e2363b31597bef4cbb441218e1750e9747115e61dd91898400973771c6" +content-hash = "94614b000f5848489ed0e32caf25a06df9daa05bc063d0e2fe03a00f6859d27b" [metadata.files] apscheduler = [ {file = "APScheduler-3.9.1.post1-py2.py3-none-any.whl", hash = "sha256:c8c618241dbb2785ed5a687504b14cb1851d6f7b5a4edf3a51e39cc6a069967a"}, {file = "APScheduler-3.9.1.post1.tar.gz", hash = "sha256:b2bea0309569da53a7261bfa0ce19c67ddbfe151bda776a6a907579fdbd3eb2a"}, ] -atomicwrites = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +astroid = [ + {file = "astroid-2.12.12-py3-none-any.whl", hash = "sha256:72702205200b2a638358369d90c222d74ebc376787af8fb2f7f2a86f7b5cc85f"}, + {file = "astroid-2.12.12.tar.gz", hash = "sha256:1c00a14f5a3ed0339d38d2e2e5b74ea2591df5861c0936bb292b84ccf3a78d83"}, ] attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, @@ -726,6 +808,10 @@ coveralls = [ {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"}, {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"}, ] +dill = [ + {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, + {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, +] distlib = [ {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, @@ -757,6 +843,10 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +isort = [ + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, +] itsdangerous = [ {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, @@ -765,6 +855,27 @@ jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] +lazy-object-proxy = [ + {file = "lazy-object-proxy-1.8.0.tar.gz", hash = "sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156"}, + {file = "lazy_object_proxy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe"}, + {file = "lazy_object_proxy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25"}, + {file = "lazy_object_proxy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b"}, + {file = "lazy_object_proxy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7"}, + {file = "lazy_object_proxy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e"}, + {file = "lazy_object_proxy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d"}, + {file = "lazy_object_proxy-1.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c"}, + {file = "lazy_object_proxy-1.8.0-cp37-cp37m-win32.whl", hash = "sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd"}, + {file = "lazy_object_proxy-1.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858"}, + {file = "lazy_object_proxy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada"}, + {file = "lazy_object_proxy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f"}, + {file = "lazy_object_proxy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c"}, + {file = "lazy_object_proxy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288"}, + {file = "lazy_object_proxy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f"}, + {file = "lazy_object_proxy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0"}, + {file = "lazy_object_proxy-1.8.0-pp37-pypy37_pp73-any.whl", hash = "sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891"}, + {file = "lazy_object_proxy-1.8.0-pp38-pypy38_pp73-any.whl", hash = "sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec"}, + {file = "lazy_object_proxy-1.8.0-pp39-pypy39_pp73-any.whl", hash = "sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8"}, +] markdown = [ {file = "Markdown-3.4.1-py3-none-any.whl", hash = "sha256:08fb8465cffd03d10b9dd34a5c3fea908e20391a2a90b88d66362cb05beed186"}, {file = "Markdown-3.4.1.tar.gz", hash = "sha256:3b809086bb6efad416156e00a0da66fe47618a5d6918dd688f53f40c8e4cfeff"}, @@ -816,29 +927,36 @@ mccabe = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mypy = [ - {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, - {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, - {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, - {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, - {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, - {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, - {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, - {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, - {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, - {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, - {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, - {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, - {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, - {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, - {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, - {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, - {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, - {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, - {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, - {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, - {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, - {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, - {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, + {file = "mypy-0.991-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab"}, + {file = "mypy-0.991-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d"}, + {file = "mypy-0.991-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c8f3be99e8a8bd403caa8c03be619544bc2c77a7093685dcf308c6b109426c6"}, + {file = "mypy-0.991-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9ec663ed6c8f15f4ae9d3c04c989b744436c16d26580eaa760ae9dd5d662eb"}, + {file = "mypy-0.991-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4307270436fd7694b41f913eb09210faff27ea4979ecbcd849e57d2da2f65305"}, + {file = "mypy-0.991-cp310-cp310-win_amd64.whl", hash = "sha256:901c2c269c616e6cb0998b33d4adbb4a6af0ac4ce5cd078afd7bc95830e62c1c"}, + {file = "mypy-0.991-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d13674f3fb73805ba0c45eb6c0c3053d218aa1f7abead6e446d474529aafc372"}, + {file = "mypy-0.991-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c8cd4fb70e8584ca1ed5805cbc7c017a3d1a29fb450621089ffed3e99d1857f"}, + {file = "mypy-0.991-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:209ee89fbb0deed518605edddd234af80506aec932ad28d73c08f1400ef80a33"}, + {file = "mypy-0.991-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37bd02ebf9d10e05b00d71302d2c2e6ca333e6c2a8584a98c00e038db8121f05"}, + {file = "mypy-0.991-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:26efb2fcc6b67e4d5a55561f39176821d2adf88f2745ddc72751b7890f3194ad"}, + {file = "mypy-0.991-cp311-cp311-win_amd64.whl", hash = "sha256:3a700330b567114b673cf8ee7388e949f843b356a73b5ab22dd7cff4742a5297"}, + {file = "mypy-0.991-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1f7d1a520373e2272b10796c3ff721ea1a0712288cafaa95931e66aa15798813"}, + {file = "mypy-0.991-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:641411733b127c3e0dab94c45af15fea99e4468f99ac88b39efb1ad677da5711"}, + {file = "mypy-0.991-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3d80e36b7d7a9259b740be6d8d906221789b0d836201af4234093cae89ced0cd"}, + {file = "mypy-0.991-cp37-cp37m-win_amd64.whl", hash = "sha256:e62ebaad93be3ad1a828a11e90f0e76f15449371ffeecca4a0a0b9adc99abcef"}, + {file = "mypy-0.991-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b86ce2c1866a748c0f6faca5232059f881cda6dda2a893b9a8373353cfe3715a"}, + {file = "mypy-0.991-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac6e503823143464538efda0e8e356d871557ef60ccd38f8824a4257acc18d93"}, + {file = "mypy-0.991-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0cca5adf694af539aeaa6ac633a7afe9bbd760df9d31be55ab780b77ab5ae8bf"}, + {file = "mypy-0.991-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12c56bf73cdab116df96e4ff39610b92a348cc99a1307e1da3c3768bbb5b135"}, + {file = "mypy-0.991-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:652b651d42f155033a1967739788c436491b577b6a44e4c39fb340d0ee7f0d70"}, + {file = "mypy-0.991-cp38-cp38-win_amd64.whl", hash = "sha256:4175593dc25d9da12f7de8de873a33f9b2b8bdb4e827a7cae952e5b1a342e243"}, + {file = "mypy-0.991-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:98e781cd35c0acf33eb0295e8b9c55cdbef64fcb35f6d3aa2186f289bed6e80d"}, + {file = "mypy-0.991-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6d7464bac72a85cb3491c7e92b5b62f3dcccb8af26826257760a552a5e244aa5"}, + {file = "mypy-0.991-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c9166b3f81a10cdf9b49f2d594b21b31adadb3d5e9db9b834866c3258b695be3"}, + {file = "mypy-0.991-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8472f736a5bfb159a5e36740847808f6f5b659960115ff29c7cecec1741c648"}, + {file = "mypy-0.991-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e80e758243b97b618cdf22004beb09e8a2de1af481382e4d84bc52152d1c476"}, + {file = "mypy-0.991-cp39-cp39-win_amd64.whl", hash = "sha256:74e259b5c19f70d35fcc1ad3d56499065c601dfe94ff67ae48b85596b9ec1461"}, + {file = "mypy-0.991-py3-none-any.whl", hash = "sha256:de32edc9b0a7e67c2775e574cb061a537660e51210fbf6006b0b36ea695ae9bb"}, + {file = "mypy-0.991.tar.gz", hash = "sha256:3c0165ba8f354a6d9881809ef29f1a9318a236a6d81c690094c5df32107bde06"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, @@ -875,6 +993,10 @@ pyflakes = [ {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, ] +pylint = [ + {file = "pylint-2.15.6-py3-none-any.whl", hash = "sha256:15060cc22ed6830a4049cf40bc24977744df2e554d38da1b2657591de5bcd052"}, + {file = "pylint-2.15.6.tar.gz", hash = "sha256:25b13ddcf5af7d112cf96935e21806c1da60e676f952efb650130f2a4483421c"}, +] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, @@ -883,12 +1005,12 @@ pyrss2gen = [ {file = "PyRSS2Gen-1.1.tar.gz", hash = "sha256:7960aed7e998d2482bf58716c316509786f596426f879b05f8d84e98b82c6ee7"}, ] pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, + {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, ] pytest-cov = [ - {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, - {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, + {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, + {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, ] pytz = [ {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, @@ -903,8 +1025,8 @@ requests = [ {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] setuptools = [ - {file = "setuptools-65.5.1-py3-none-any.whl", hash = "sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31"}, - {file = "setuptools-65.5.1.tar.gz", hash = "sha256:e197a19aa8ec9722928f2206f8de752def0e4c9fc6953527360d1c36d94ddb2f"}, + {file = "setuptools-65.6.0-py3-none-any.whl", hash = "sha256:6211d2f5eddad8757bd0484923ca7c0a6302ebc4ab32ea5e94357176e0ca0840"}, + {file = "setuptools-65.6.0.tar.gz", hash = "sha256:d1eebf881c6114e51df1664bc2c9133d022f78d12d5f4f665b9191f084e2862d"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -918,10 +1040,18 @@ tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +tomlkit = [ + {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, + {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, +] tox = [ {file = "tox-3.27.1-py2.py3-none-any.whl", hash = "sha256:f52ca66eae115fcfef0e77ef81fd107133d295c97c52df337adedb8dfac6ab84"}, {file = "tox-3.27.1.tar.gz", hash = "sha256:b2a920e35a668cc06942ffd1cf3a4fb221a4d909ca72191fb6d84b0b18a7be04"}, ] +types-markdown = [ + {file = "types-Markdown-3.4.2.1.tar.gz", hash = "sha256:03c0904cf5886a7d8193e2f50bcf842afc89e0ab80f060f389f6c2635c65628f"}, + {file = "types_Markdown-3.4.2.1-py3-none-any.whl", hash = "sha256:b2333f6f4b8f69af83de359e10a097e4a3f14bbd6d2484e1829d9b0ec56fa0cb"}, +] typing-extensions = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, @@ -946,3 +1076,69 @@ werkzeug = [ {file = "Werkzeug-2.2.2-py3-none-any.whl", hash = "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5"}, {file = "Werkzeug-2.2.2.tar.gz", hash = "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f"}, ] +wrapt = [ + {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, + {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, + {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, + {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, + {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, + {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, + {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, + {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, + {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, + {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, + {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, + {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, + {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, + {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, + {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, + {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, +] diff --git a/pyproject.toml b/pyproject.toml index d8d8746..d1ec3da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,14 +17,15 @@ peewee = "^3.14.8" tox = "^3.24.5" background = "^0.2.1" Flask = "^2.1.1" +types-markdown = "^3.4.2.1" -[tool.poetry.dev-dependencies] -mypy = "^0.942" -flake8-black = "^0.3.2" -black = "^22.3.0" -pytest = "^6.2.4" -pytest-cov = "^2.12.1" -coveralls = "^3.2.0" +[tool.poetry.group.dev.dependencies] +pylint = "^2.15.5" +mypy = "^0.991" +pytest = "^7.2.0" +coveralls = "^3.3.1" +flake8-black = "^0.3.4" +pytest-cov = "^4.0.0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/run.sh b/run.sh index 3ee772c..fb544ec 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ #!/bin/sh -python3 run.py "$@" +python3 stacosys/run.py "$@" diff --git a/stacosys.code-workspace b/stacosys.code-workspace deleted file mode 100644 index 876a149..0000000 --- a/stacosys.code-workspace +++ /dev/null @@ -1,8 +0,0 @@ -{ - "folders": [ - { - "path": "." - } - ], - "settings": {} -} \ No newline at end of file diff --git a/stacosys.sublime-project b/stacosys.sublime-project new file mode 100644 index 0000000..7d00994 --- /dev/null +++ b/stacosys.sublime-project @@ -0,0 +1,19 @@ +{ + "folders": + [ + { + "path": ".", + "folder_exclude_patterns": ["__pycache__",".pytest_cache", ".mypy_cache"], + "file_exclude_patterns": [".coverage"] + } + ], + "settings": { + "LSP": { + "LSP-pyright": { + "settings": { + "python.analysis.diagnosticMode": "workspace" + } + } + } + } +} diff --git a/stacosys.sublime-workspace b/stacosys.sublime-workspace new file mode 100644 index 0000000..21684d5 --- /dev/null +++ b/stacosys.sublime-workspace @@ -0,0 +1,975 @@ +{ + "auto_complete": + { + "selected_items": + [ + [ + "get", + "get_int" + ] + ] + }, + "buffers": + [ + { + "file": "run.sh", + "settings": + { + "buffer_size": 40, + "encoding": "UTF-8", + "line_ending": "Unix" + } + }, + { + "file": "stacosys/run.py", + "settings": + { + "buffer_size": 3298, + "encoding": "UTF-8", + "line_ending": "Unix" + }, + "undo_stack": + [ + [ + 34, + 1, + "insert", + { + "characters": "no" + }, + "AgAAAOcFAAAAAAAA6AUAAAAAAAAAAAAA6AUAAAAAAADpBQAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADnBQAAAAAAAOcFAAAAAAAAAAAAAAAA8L8" + ], + [ + 35, + 1, + "insert", + { + "characters": " " + }, + "AQAAAOkFAAAAAAAA6gUAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADpBQAAAAAAAOkFAAAAAAAAAAAAAAAA8L8" + ], + [ + 36, + 1, + "left_delete", + null, + "AQAAAOkFAAAAAAAA6QUAAAAAAAABAAAAIA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADqBQAAAAAAAOoFAAAAAAAAAAAAAAAA8L8" + ], + [ + 37, + 1, + "insert", + { + "characters": "r" + }, + "AQAAAOkFAAAAAAAA6gUAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADpBQAAAAAAAOkFAAAAAAAAAAAAAAAA8L8" + ], + [ + 38, + 1, + "insert", + { + "characters": " " + }, + "AQAAAOoFAAAAAAAA6wUAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADqBQAAAAAAAOoFAAAAAAAAAAAAAAAA8L8" + ], + [ + 39, + 1, + "paste", + null, + "AQAAAOsFAAAAAAAA9gUAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADrBQAAAAAAAOsFAAAAAAAAAAAAAAAA8L8" + ], + [ + 40, + 1, + "insert", + { + "characters": " or" + }, + "AwAAAPYFAAAAAAAA9wUAAAAAAAAAAAAA9wUAAAAAAAD4BQAAAAAAAAAAAAD4BQAAAAAAAPkFAAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAD2BQAAAAAAAPYFAAAAAAAAAAAAAAAA8L8" + ], + [ + 41, + 1, + "insert", + { + "characters": " " + }, + "AQAAAPkFAAAAAAAA+gUAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAD5BQAAAAAAAPkFAAAAAAAAAAAAAAAA8L8" + ], + [ + 46, + 1, + "left_delete", + null, + "AQAAAOkFAAAAAAAA6QUAAAAAAAABAAAAcg", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADqBQAAAAAAAOoFAAAAAAAAAAAAAAAA8L8" + ], + [ + 47, + 1, + "insert", + { + "characters": "t" + }, + "AQAAAOkFAAAAAAAA6gUAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADpBQAAAAAAAOkFAAAAAAAAAAAAAAAA8L8" + ], + [ + 59, + 1, + "insert_completion", + { + "completion": "lsp_select_completion_item {\"session_name\":\"LSP-pyright\",\"item\":{\"label\":\"get_int\",\"data\":{\"workspacePath\":\"/home/yannic/work/stacosys\",\"position\":{\"character\":21,\"line\":91},\"symbolLabel\":\"get_int\",\"filePath\":\"/home/yannic/work/stacosys/stacosys/run.py\"},\"kind\":2,\"sortText\":\"09.9999.get_int\"}}", + "format": "command", + "keep_prefix": false, + "must_insert": false, + "trigger": "get_int" + }, + "AgAAAMgLAAAAAAAAyAsAAAAAAAADAAAAZ2V0yAsAAAAAAADPCwAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAADLCwAAAAAAAMsLAAAAAAAAAAAAAAAA8L8" + ] + ] + }, + { + "file": "Makefile", + "settings": + { + "buffer_size": 533, + "encoding": "UTF-8", + "line_ending": "Unix" + } + }, + { + "file": "stacosys/core/mailer.py", + "settings": + { + "buffer_size": 1087, + "encoding": "UTF-8", + "line_ending": "Unix" + }, + "undo_stack": + [ + [ + 11, + 1, + "insert", + { + "characters": "\n" + }, + "AgAAAEIEAAAAAAAAQwQAAAAAAAAAAAAAQwQAAAAAAABPBAAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAABCBAAAAAAAAEIEAAAAAAAAAAAAAAAA8L8" + ], + [ + 12, + 1, + "left_delete", + null, + "AQAAAEsEAAAAAAAASwQAAAAAAAAEAAAAICAgIA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAABPBAAAAAAAAE8EAAAAAAAAAAAAAAAA8L8" + ], + [ + 13, + 1, + "insert", + { + "characters": "else:" + }, + "BQAAAEsEAAAAAAAATAQAAAAAAAAAAAAATAQAAAAAAABNBAAAAAAAAAAAAABNBAAAAAAAAE4EAAAAAAAAAAAAAE4EAAAAAAAATwQAAAAAAAAAAAAATwQAAAAAAABQBAAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAABLBAAAAAAAAEsEAAAAAAAAAAAAAAAA8L8" + ], + [ + 14, + 1, + "insert", + { + "characters": "\n" + }, + "AwAAAFAEAAAAAAAAUQQAAAAAAAAAAAAAUQQAAAAAAABZBAAAAAAAAAAAAABZBAAAAAAAAF0EAAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAABQBAAAAAAAAFAEAAAAAAAAAAAAAAAA8L8" + ], + [ + 16, + 1, + "insert", + { + "characters": "False" + }, + "BQAAAF0EAAAAAAAAXgQAAAAAAAAAAAAAXgQAAAAAAABfBAAAAAAAAAAAAABfBAAAAAAAAGAEAAAAAAAAAAAAAGAEAAAAAAAAYQQAAAAAAAAAAAAAYQQAAAAAAABiBAAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAABdBAAAAAAAAF0EAAAAAAAAAAAAAAAA8L8" + ], + [ + 44, + 1, + "insert", + { + "characters": "s" + }, + "AQAAAB4CAAAAAAAAHwIAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAAeAgAAAAAAAB4CAAAAAAAAAAAAAAAA8L8" + ], + [ + 53, + 1, + "left_delete", + null, + "AQAAAEQEAAAAAAAARAQAAAAAAAA1AAAAICAgICAgICBlbHNlOgogICAgICAgICAgICBGYWxzZQogICAgICAgIHJldHVybiBGYWxzZQo", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAABEBAAAAAAAAHkEAAAAAAAAAAAAAAAAAAA" + ], + [ + 56, + 1, + "right_delete", + null, + "AQAAACwEAAAAAAAALAQAAAAAAAAXAAAAICAgICAgICAgICAgcmV0dXJuIFRydWU", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAAsBAAAAAAAAEMEAAAAAAAA////////738" + ], + [ + 70, + 1, + "left_delete", + null, + "AQAAAB4CAAAAAAAAHgIAAAAAAAABAAAAcw", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAAfAgAAAAAAAB8CAAAAAAAAAAAAAAAA8L8" + ], + [ + 80, + 1, + "reindent", + null, + "AQAAACsEAAAAAAAANwQAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAArBAAAAAAAACsEAAAAAAAAAAAAAAAA8L8" + ], + [ + 81, + 1, + "left_delete", + null, + "AQAAADMEAAAAAAAAMwQAAAAAAAAEAAAAICAgIA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAA3BAAAAAAAADcEAAAAAAAAAAAAAAAA8L8" + ], + [ + 82, + 1, + "insert", + { + "characters": "reru" + }, + "BAAAADMEAAAAAAAANAQAAAAAAAAAAAAANAQAAAAAAAA1BAAAAAAAAAAAAAA1BAAAAAAAADYEAAAAAAAAAAAAADYEAAAAAAAANwQAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAAzBAAAAAAAADMEAAAAAAAAAAAAAAAA8L8" + ], + [ + 83, + 2, + "left_delete", + null, + "AgAAADYEAAAAAAAANgQAAAAAAAABAAAAdTUEAAAAAAAANQQAAAAAAAABAAAAcg", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAA3BAAAAAAAADcEAAAAAAAAAAAAAAAA8L8" + ], + [ + 84, + 1, + "insert", + { + "characters": "turn" + }, + "BAAAADUEAAAAAAAANgQAAAAAAAAAAAAANgQAAAAAAAA3BAAAAAAAAAAAAAA3BAAAAAAAADgEAAAAAAAAAAAAADgEAAAAAAAAOQQAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAA1BAAAAAAAADUEAAAAAAAAAAAAAAAA8L8" + ], + [ + 85, + 1, + "insert", + { + "characters": " True" + }, + "BQAAADkEAAAAAAAAOgQAAAAAAAAAAAAAOgQAAAAAAAA7BAAAAAAAAAAAAAA7BAAAAAAAADwEAAAAAAAAAAAAADwEAAAAAAAAPQQAAAAAAAAAAAAAPQQAAAAAAAA+BAAAAAAAAAAAAAA", + "AgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPC/AAAAAAEAAAA5BAAAAAAAADkEAAAAAAAAAAAAAAAA8L8" + ] + ] + }, + { + "file": "stacosys/db/dao.py", + "settings": + { + "buffer_size": 1633, + "line_ending": "Unix" + }, + "undo_stack": + [ + ] + }, + { + "file": "stacosys.sublime-project", + "settings": + { + "buffer_size": 381, + "encoding": "UTF-8", + "line_ending": "Unix" + }, + "undo_stack": + [ + [ + 4, + 1, + "", + null, + "AgAAAMMAAAAAAAAAZQEAAAAAAAAAAAAAZQEAAAAAAABlAQAAAAAAAPMAAAAgICAgInNldHRpbmdzIjoKICAgIHsKICAgICAgICAiTFNQIjoKICAgICAgICB7CiAgICAgICAgICAgICJMU1AtcHlsc3AiOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAic2V0dGluZ3MiOgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICJweWxzcC5wbHVnaW5zLmplZGkuZW52aXJvbm1lbnQiOiAiLi8udmVudiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0", + "AQAAAAAAAAABAAAAtgEAAAAAAADDAAAAAAAAAAAAAAAAAPC/" + ], + [ + 8, + 1, + "paste", + null, + "AgAAACYBAAAAAAAAUwEAAAAAAAAAAAAAUwEAAAAAAABTAQAAAAAAABkAAAAvLyBQdXQgeW91ciBzZXR0aW5ncyBoZXJl", + "AQAAAAAAAAABAAAAJgEAAAAAAAA/AQAAAAAAAP///////+9/" + ] + ] + }, + { + "file": "stacosys/model/comment.py", + "settings": + { + "buffer_size": 471, + "line_ending": "Unix" + } + }, + { + "file": "stacosys/conf/config.py", + "settings": + { + "buffer_size": 2481, + "encoding": "UTF-8", + "line_ending": "Unix" + } + } + ], + "build_system": "", + "build_system_choices": + [ + ], + "build_varint": "", + "command_palette": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "diag", + "LSP: Goto Diagnostic in Project" + ], + [ + "lsp", + "LSP: Toggle Diagnostics Panel" + ], + [ + "Package Control: ", + "Package Control: Install Package" + ], + [ + "distr", + "View: Toggle Distraction Free" + ], + [ + "upg", + "Package Control: Upgrade Package" + ], + [ + "comment", + "Toggle Comment" + ], + [ + "form", + "LSP: Format Document" + ], + [ + "format", + "LSP: Format Document" + ], + [ + "lspc", + "LSP: Clear Diagnostics" + ], + [ + "ren", + "LSP: Rename Symbol" + ], + [ + "instal", + "Package Control: Install Package" + ], + [ + "install", + "Package Control: Install Package" + ], + [ + "package re", + "Package Control: Remove Package" + ], + [ + "paka", + "Package Control: Remove Package" + ], + [ + "remove", + "Package Control: Remove Package" + ], + [ + "insta", + "Package Control: Install Package" + ], + [ + "inst", + "Package Control: Install Package" + ], + [ + "pac", + "Package Control: Remove Package" + ] + ], + "width": 0.0 + }, + "console": + { + "height": 164.0, + "history": + [ + ] + }, + "distraction_free": + { + "menu_visible": true, + "show_minimap": false, + "show_open_files": false, + "show_tabs": false, + "side_bar_visible": false, + "status_bar_visible": false + }, + "expanded_folders": + [ + "/home/yannic/work/stacosys", + "/home/yannic/work/stacosys/stacosys", + "/home/yannic/work/stacosys/stacosys/conf", + "/home/yannic/work/stacosys/stacosys/core", + "/home/yannic/work/stacosys/stacosys/db", + "/home/yannic/work/stacosys/stacosys/interface", + "/home/yannic/work/stacosys/stacosys/interface/web", + "/home/yannic/work/stacosys/stacosys/model", + "/home/yannic/work/stacosys/tests" + ], + "file_history": + [ + "/home/yannic/.cache/sublime-text-3/Package Storage/LSP-pyright/18.7.0/language-server/node_modules/pyright/dist/typeshed-fallback/stdlib/sys.pyi", + "/home/yannic/work/stacosys/stacosys/conf/config.py", + "/usr/lib64/python3.11/logging/__init__.py", + "/home/yannic/work/stacosys/stacosys.sublime-project", + "/home/yannic/work/stacosys/flake8.ini", + "/home/yannic/work/stacosys/Makefile", + "/home/yannic/work/stacosys/stacosys/__init__.py", + "/home/yannic/work/stacosys/stacosys/core/rss.py" + ], + "find": + { + "height": 28.0 + }, + "find_in_files": + { + "height": 0.0, + "where_history": + [ + ] + }, + "find_state": + { + "case_sensitive": false, + "find_history": + [ + "background" + ], + "highlight": true, + "in_selection": false, + "preserve_case": false, + "regex": false, + "replace_history": + [ + ], + "reverse": false, + "scrollbar_highlights": true, + "show_context": true, + "use_buffer2": true, + "use_gitignore": true, + "whole_word": false, + "wrap": true + }, + "groups": + [ + { + "sheets": + [ + { + "buffer": 0, + "file": "run.sh", + "semi_transient": false, + "settings": + { + "buffer_size": 40, + "regions": + { + }, + "selection": + [ + [ + 27, + 27 + ] + ], + "settings": + { + "lsp_uri": "file:///home/yannic/work/stacosys/run.sh", + "syntax": "Packages/ShellScript/Bash.sublime-syntax" + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "stack_index": 7, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 1, + "file": "stacosys/run.py", + "semi_transient": false, + "settings": + { + "buffer_size": 3298, + "regions": + { + }, + "selection": + [ + [ + 1918, + 1918 + ] + ], + "settings": + { + "auto_complete_triggers": + [ + { + "characters": "<", + "selector": "text.html, text.xml" + }, + { + "rhs_empty": true, + "selector": "punctuation.accessor" + }, + { + "characters": ".[", + "selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", + "server": "LSP-pyright" + } + ], + "lsp_active": true, + "lsp_hover_provider_count": 10, + "lsp_uri": "file:///home/yannic/work/stacosys/stacosys/run.py", + "show_definitions": false, + "syntax": "Packages/Python/Python.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 964.0, + "zoom_level": 1.0 + }, + "stack_index": 6, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 2, + "file": "Makefile", + "semi_transient": false, + "settings": + { + "buffer_size": 533, + "regions": + { + }, + "selection": + [ + [ + 334, + 334 + ] + ], + "settings": + { + "lsp_uri": "file:///home/yannic/work/stacosys/Makefile", + "syntax": "Packages/Makefile/Makefile.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": false + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "stack_index": 1, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 3, + "file": "stacosys/core/mailer.py", + "selected": true, + "semi_transient": false, + "settings": + { + "buffer_size": 1087, + "regions": + { + }, + "selection": + [ + [ + 1086, + 1086 + ] + ], + "settings": + { + "auto_complete_triggers": + [ + { + "characters": "<", + "selector": "text.html, text.xml" + }, + { + "rhs_empty": true, + "selector": "punctuation.accessor" + }, + { + "characters": ".[", + "selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", + "server": "LSP-pyright" + } + ], + "lsp_active": true, + "lsp_hover_provider_count": 10, + "lsp_uri": "file:///home/yannic/work/stacosys/stacosys/core/mailer.py", + "show_definitions": false, + "syntax": "Packages/Python/Python.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 399.0, + "zoom_level": 1.0 + }, + "stack_index": 0, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 4, + "file": "stacosys/db/dao.py", + "semi_transient": true, + "settings": + { + "buffer_size": 1633, + "regions": + { + }, + "selection": + [ + [ + 524, + 524 + ] + ], + "settings": + { + "auto_complete_triggers": + [ + { + "characters": "<", + "selector": "text.html, text.xml" + }, + { + "rhs_empty": true, + "selector": "punctuation.accessor" + }, + { + "characters": ".[", + "selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", + "server": "LSP-pyright" + } + ], + "lsp_active": true, + "lsp_hover_provider_count": 1, + "lsp_uri": "file:///home/yannic/work/stacosys/stacosys/db/dao.py", + "show_definitions": false, + "syntax": "Packages/Python/Python.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "stack_index": 3, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 5, + "file": "stacosys.sublime-project", + "semi_transient": false, + "settings": + { + "buffer_size": 381, + "regions": + { + }, + "selection": + [ + [ + 364, + 364 + ] + ], + "settings": + { + "lsp_uri": "file:///home/yannic/work/stacosys/stacosys.sublime-project", + "syntax": "Packages/JSON/JSON.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "stack_index": 2, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 6, + "file": "stacosys/model/comment.py", + "semi_transient": false, + "settings": + { + "buffer_size": 471, + "regions": + { + }, + "selection": + [ + [ + 150, + 150 + ] + ], + "settings": + { + "auto_complete_triggers": + [ + { + "characters": "<", + "selector": "text.html, text.xml" + }, + { + "rhs_empty": true, + "selector": "punctuation.accessor" + }, + { + "characters": ".[", + "selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", + "server": "LSP-pyright" + } + ], + "lsp_active": true, + "lsp_hover_provider_count": 6, + "lsp_uri": "file:///home/yannic/work/stacosys/stacosys/model/comment.py", + "show_definitions": false, + "syntax": "Packages/Python/Python.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "stack_index": 4, + "stack_multiselect": false, + "type": "text" + }, + { + "buffer": 7, + "file": "stacosys/conf/config.py", + "semi_transient": false, + "settings": + { + "buffer_size": 2481, + "regions": + { + }, + "selection": + [ + [ + 0, + 0 + ] + ], + "settings": + { + "auto_complete_triggers": + [ + { + "characters": "<", + "selector": "text.html, text.xml" + }, + { + "rhs_empty": true, + "selector": "punctuation.accessor" + }, + { + "characters": ".[", + "selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", + "server": "LSP-pyright" + } + ], + "lsp_active": true, + "lsp_hover_provider_count": 6, + "lsp_uri": "file:///home/yannic/work/stacosys/stacosys/conf/config.py", + "show_definitions": false, + "syntax": "Packages/Python/Python.sublime-syntax", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 1539.0, + "zoom_level": 1.0 + }, + "stack_index": 5, + "stack_multiselect": false, + "type": "text" + } + ] + } + ], + "incremental_find": + { + "height": 28.0 + }, + "input": + { + "height": 0.0 + }, + "layout": + { + "cells": + [ + [ + 0, + 0, + 1, + 1 + ] + ], + "cols": + [ + 0.0, + 1.0 + ], + "rows": + [ + 0.0, + 1.0 + ] + }, + "menu_visible": true, + "output.LSP Log Panel": + { + "height": 0.0 + }, + "output.diagnostics": + { + "height": 261.0 + }, + "output.find_results": + { + "height": 0.0 + }, + "output.language servers": + { + "height": 132.0 + }, + "output.mdpopups": + { + "height": 0.0 + }, + "output.references": + { + "height": 208.0 + }, + "pinned_build_system": "", + "project": "stacosys.sublime-project", + "replace": + { + "height": 52.0 + }, + "save_all_on_build": true, + "select_file": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_project": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_symbol": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "selected_group": 0, + "settings": + { + }, + "show_minimap": true, + "show_open_files": false, + "show_tabs": true, + "side_bar_visible": true, + "side_bar_width": 311.0, + "status_bar_visible": true, + "template_settings": + { + } +} diff --git a/stacosys/__init__.py b/stacosys/__init__.py index 587c2ab..e69de29 100644 --- a/stacosys/__init__.py +++ b/stacosys/__init__.py @@ -1 +0,0 @@ -__version__ = "3.3" diff --git a/stacosys/conf/config.py b/stacosys/conf/config.py index 5315036..78adea8 100644 --- a/stacosys/conf/config.py +++ b/stacosys/conf/config.py @@ -1,9 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from enum import Enum - import configparser +from enum import Enum class ConfigParameter(Enum): @@ -44,7 +43,7 @@ class Config: section, param = str(key.value).split(".") if not param: param = section - section = None + section = "" return (section, param) def exists(self, key: ConfigParameter): diff --git a/stacosys/core/mailer.py b/stacosys/core/mailer.py index b58f75b..43ec706 100644 --- a/stacosys/core/mailer.py +++ b/stacosys/core/mailer.py @@ -4,7 +4,6 @@ import logging import smtplib import ssl - from email.mime.text import MIMEText logger = logging.getLogger(__name__) @@ -35,10 +34,10 @@ class Mailer: msg["From"] = sender context = ssl.create_default_context() + # TODO catch SMTP failure with smtplib.SMTP_SSL( self._smtp_host, self._smtp_port, context=context ) as server: server.login(self._smtp_login, self._smtp_password) server.send_message(msg, sender, receivers) - return True - return False + return True diff --git a/stacosys/core/rss.py b/stacosys/core/rss.py index 958f155..42f9b8d 100644 --- a/stacosys/core/rss.py +++ b/stacosys/core/rss.py @@ -3,8 +3,8 @@ from datetime import datetime -import PyRSS2Gen import markdown +import PyRSS2Gen from stacosys.model.comment import Comment @@ -34,11 +34,20 @@ class Rss: .order_by(-Comment.published) .limit(10) ): - item_link = "%s://%s%s" % (self._rss_proto, self._site_url, row.url) + item_link = "%s://%s%s" % ( + self._rss_proto, + self._site_url, + row.url, + ) items.append( PyRSS2Gen.RSSItem( title="%s - %s://%s%s" - % (self._rss_proto, row.author_name, self._site_url, row.url), + % ( + self._rss_proto, + row.author_name, + self._site_url, + row.url, + ), link=item_link, description=md.convert(row.content), guid=PyRSS2Gen.Guid("%s/%d" % (item_link, row.id)), diff --git a/stacosys/db/dao.py b/stacosys/db/dao.py index 597579d..fcd3689 100644 --- a/stacosys/db/dao.py +++ b/stacosys/db/dao.py @@ -7,8 +7,8 @@ from stacosys.model.comment import Comment TIME_FORMAT = "%Y-%m-%d %H:%M:%S" -def find_comment_by_id(id): - return Comment.get_by_id(id) +def find_comment_by_id(comment_id): + return Comment.get_by_id(comment_id) def notify_comment(comment: Comment): diff --git a/stacosys/db/database.py b/stacosys/db/database.py index 73c2591..08a7580 100644 --- a/stacosys/db/database.py +++ b/stacosys/db/database.py @@ -1,5 +1,6 @@ #!/usr/bin/python # -*- coding: UTF-8 -*- +# pylint: disable=import-outside-toplevel from peewee import Model from playhouse.db_url import SqliteDatabase diff --git a/stacosys/interface/api.py b/stacosys/interface/api.py index 042f0fc..8c88a2e 100644 --- a/stacosys/interface/api.py +++ b/stacosys/interface/api.py @@ -21,18 +21,18 @@ def query_comments(): comments = [] url = request.args.get("url", "") - logger.info("retrieve comments for url %s" % url) + logger.info("retrieve comments for url %s", url) for comment in dao.find_published_comments_by_url(url): - d = { + comment_dto = { "author": comment.author_name, "content": comment.content, "avatar": comment.author_gravatar, "date": comment.published.strftime("%Y-%m-%d %H:%M:%S"), } if comment.author_site: - d["site"] = comment.author_site - logger.debug(d) - comments.append(d) + comment_dto["site"] = comment.author_site + logger.debug(comment_dto) + comments.append(comment_dto) return jsonify({"data": comments}) diff --git a/stacosys/interface/form.py b/stacosys/interface/form.py index 6955d44..04b52b3 100644 --- a/stacosys/interface/form.py +++ b/stacosys/interface/form.py @@ -14,12 +14,12 @@ logger = logging.getLogger(__name__) @app.route("/newcomment", methods=["POST"]) def new_form_comment(): data = request.form - logger.info("form data " + str(data)) + logger.info("form data %s", str(data)) # honeypot for spammers captcha = data.get("remarque", "") if captcha: - logger.warning("discard spam: data %s" % data) + logger.warning("discard spam: data %s", data) abort(400) url = data.get("url", "") @@ -32,10 +32,10 @@ def new_form_comment(): # anti-spam again if not url or not author_name or not message: - logger.warning("empty field: data %s" % data) + logger.warning("empty field: data %s", data) abort(400) if not check_form_data(data.to_dict()): - logger.warning("additional field: data %s" % data) + logger.warning("additional field: data %s", data) abort(400) # add a row to Comment table @@ -49,23 +49,24 @@ def new_form_comment(): return redirect(app.config.get("SITE_REDIRECT"), code=302) -def check_form_data(d): +def check_form_data(posted_comment): fields = ["url", "message", "site", "remarque", "author", "token", "email"] - filtered = dict(filter(lambda x: x[0] not in fields, d.items())) + filtered = dict(filter(lambda x: x[0] not in fields, posted_comment.items())) return not filtered @background.task def submit_new_comment(comment): + site_url = app.config.get("SITE_URL") comment_list = ( - "Web admin interface: %s/web/admin" % app.config.get("SITE_URL"), + f"Web admin interface: {site_url}/web/admin", "", - "author: %s" % comment.author_name, - "site: %s" % comment.author_site, - "date: %s" % comment.created, - "url: %s" % comment.url, + f"author: {comment.author_name}", + f"site: {comment.author_site}", + f"date: {comment.created}", + f"url: {comment.url}", "", - "%s" % comment.content, + comment.content, "", ) email_body = "\n".join(comment_list) @@ -78,9 +79,10 @@ def submit_new_comment(comment): # save notification datetime dao.notify_comment(comment) else: - logger.warning("rescheduled. send mail failure " + subject) + logger.warning("rescheduled. send mail failure %s", subject) @background.callback def submit_new_comment_callback(future): - pass + # TODO use future to log submit status + logger.debug(future) diff --git a/stacosys/interface/web/admin.py b/stacosys/interface/web/admin.py index c65ee0a..26d172f 100644 --- a/stacosys/interface/web/admin.py +++ b/stacosys/interface/web/admin.py @@ -4,7 +4,7 @@ import hashlib import logging -from flask import request, redirect, flash, render_template, session +from flask import flash, redirect, render_template, request, session from stacosys.db import dao from stacosys.interface import app @@ -40,7 +40,7 @@ def login(): flash("Identifiant ou mot de passe incorrect") return redirect("/web/login") # GET - return render_template("login_" + app.config.get("LANG") + ".html") + return render_template("login_" + app.config.get("LANG", "fr") + ".html") @app.route("/web/logout", methods=["GET"]) @@ -58,7 +58,7 @@ def admin_homepage(): comments = dao.find_not_published_comments() return render_template( - "admin_" + app.config.get("LANG") + ".html", + "admin_" + app.config.get("LANG", "fr") + ".html", comments=comments, baseurl=app.config.get("SITE_URL"), ) diff --git a/stacosys/model/comment.py b/stacosys/model/comment.py index 843e8b6..a6f3324 100644 --- a/stacosys/model/comment.py +++ b/stacosys/model/comment.py @@ -1,9 +1,7 @@ #!/usr/bin/python # -*- coding: UTF-8 -*- -from peewee import CharField -from peewee import DateTimeField -from peewee import TextField +from peewee import CharField, DateTimeField, TextField from stacosys.db.database import BaseModel diff --git a/run.py b/stacosys/run.py similarity index 82% rename from run.py rename to stacosys/run.py index 0f7c1a3..197215b 100644 --- a/run.py +++ b/stacosys/run.py @@ -10,9 +10,7 @@ from stacosys.conf.config import Config, ConfigParameter from stacosys.core.mailer import Mailer from stacosys.core.rss import Rss from stacosys.db import database -from stacosys.interface import api -from stacosys.interface import app -from stacosys.interface import form +from stacosys.interface import api, app, form from stacosys.interface.web import admin @@ -20,11 +18,11 @@ from stacosys.interface.web import admin def configure_logging(level): root_logger = logging.getLogger() root_logger.setLevel(level) - ch = logging.StreamHandler() - ch.setLevel(level) + handler = logging.StreamHandler() + handler.setLevel(level) formatter = logging.Formatter("[%(asctime)s] %(name)s %(levelname)s %(message)s") - ch.setFormatter(formatter) - root_logger.addHandler(ch) + handler.setFormatter(formatter) + root_logger.addHandler(handler) def stacosys_server(config_pathname): @@ -36,21 +34,21 @@ def stacosys_server(config_pathname): # check config file exists if not os.path.isfile(config_pathname): - logger.error(f"Configuration file '{config_pathname}' not found.") + logger.error("Configuration file '%s' not found.", config_pathname) sys.exit(1) # load config conf = Config.load(config_pathname) is_config_ok, erreur_config = conf.check() if not is_config_ok: - logger.error(f"Configuration incorrecte '{erreur_config}'") + logger.error("Configuration incorrecte '%s'", erreur_config) sys.exit(1) logger.info(conf) # check database file exists (prevents from creating a fresh db) db_pathname = conf.get(ConfigParameter.DB_SQLITE_FILE) - if not os.path.isfile(db_pathname): - logger.error(f"Database file '{db_pathname}' not found.") + if not db_pathname or not os.path.isfile(db_pathname): + logger.error("Database file '%s' not found.", db_pathname) sys.exit(1) # initialize database @@ -86,12 +84,12 @@ def stacosys_server(config_pathname): app.config.update(WEB_PASSWORD=conf.get(ConfigParameter.WEB_PASSWORD)) app.config.update(MAILER=mailer) app.config.update(RSS=rss) - logger.info(f"start interfaces {api} {form} {admin}") + logger.info("start interfaces %s %s %s", api, form, admin) # start Flask app.run( host=conf.get(ConfigParameter.HTTP_HOST), - port=conf.get(ConfigParameter.HTTP_PORT), + port=conf.get_int(ConfigParameter.HTTP_PORT), debug=False, use_reloader=False, ) diff --git a/tests/test_stacosys.py b/tests/test_stacosys.py deleted file mode 100644 index 55e0869..0000000 --- a/tests/test_stacosys.py +++ /dev/null @@ -1,8 +0,0 @@ -import unittest - -from stacosys import __version__ - - -class StacosysTestCase(unittest.TestCase): - def test_version(self): - self.assertEqual("3.3", __version__)