format everything with black

This commit is contained in:
Istvan Ruzman
2020-09-21 18:16:03 +02:00
parent 2b5e7ceeed
commit 334445c54e
12 changed files with 353 additions and 426 deletions

View File

@@ -1 +1 @@
skips: ['B101'] skips: ["B101"]

View File

@@ -1,7 +1,22 @@
{ pkgs ? import <nixpkgs> {} }: { buildPythonPackage, lib, pytest, }:
let buildPythonPackage rec {
app = pkgs.poetry2nix.mkPoetryApplication { pname = "pyrad3";
projectDir = ./.; version = "3.0.0";
src = "./.";
checkInputs = [ pytest ];
checkPhase = ''
pytest
'';
meta = with lib; {
description = "Python RADIUS Implementation";
homepage = "";
license = [licenses.mit licenses.apache2];
maintainers = [ maintainers.lvkm ];
}; };
in app.dependencyEnv }

535
poetry.lock generated
View File

@@ -1,26 +1,26 @@
[[package]] [[package]]
category = "dev"
description = "apipkg: namespace control and lazy-import mechanism"
name = "apipkg" name = "apipkg"
version = "1.5"
description = "apipkg: namespace control and lazy-import mechanism"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.5"
[[package]] [[package]]
category = "dev"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
name = "appdirs" name = "appdirs"
version = "1.4.4"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "1.4.4"
[[package]] [[package]]
category = "dev"
description = "An abstract syntax tree for Python with inference support."
name = "astroid" name = "astroid"
version = "2.4.2"
description = "An abstract syntax tree for Python with inference support."
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "2.4.2"
[package.dependencies] [package.dependencies]
lazy-object-proxy = ">=1.4.0,<1.5.0" lazy-object-proxy = ">=1.4.0,<1.5.0"
@@ -28,25 +28,25 @@ six = ">=1.12,<2.0"
wrapt = ">=1.11,<2.0" wrapt = ">=1.11,<2.0"
[package.dependencies.typed-ast] [package.dependencies.typed-ast]
python = "<3.8"
version = ">=1.4.0,<1.5" version = ">=1.4.0,<1.5"
python = "<3.8"
[[package]] [[package]]
category = "dev"
description = "Atomic file writes."
marker = "sys_platform == \"win32\""
name = "atomicwrites" name = "atomicwrites"
version = "1.4.0"
description = "Atomic file writes."
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.4.0" marker = "sys_platform == \"win32\""
[[package]] [[package]]
category = "dev"
description = "Classes Without Boilerplate"
name = "attrs" name = "attrs"
version = "20.2.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "20.2.0"
[package.extras] [package.extras]
dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"]
@@ -55,97 +55,99 @@ tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six
tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
[[package]] [[package]]
category = "dev"
description = "Security oriented static analyser for python code."
name = "bandit" name = "bandit"
version = "1.6.2"
description = "Security oriented static analyser for python code."
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "1.6.2"
[package.dependencies] [package.dependencies]
colorama = ">=0.3.9"
GitPython = ">=1.0.1" GitPython = ">=1.0.1"
PyYAML = ">=3.13" PyYAML = ">=3.13"
colorama = ">=0.3.9"
six = ">=1.10.0" six = ">=1.10.0"
stevedore = ">=1.20.0" stevedore = ">=1.20.0"
[[package]] [[package]]
category = "dev"
description = "The uncompromising code formatter."
name = "black" name = "black"
version = "20.8b1"
description = "The uncompromising code formatter."
category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
version = "19.10b0"
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
[package.dependencies] [package.dependencies]
appdirs = "*" appdirs = "*"
attrs = ">=18.1.0" click = ">=7.1.2"
click = ">=6.5" mypy-extensions = ">=0.4.3"
pathspec = ">=0.6,<1" pathspec = ">=0.6,<1"
regex = "*" regex = ">=2020.1.8"
toml = ">=0.9.4" toml = ">=0.10.1"
typed-ast = ">=1.4.0" typed-ast = ">=1.4.0"
typing-extensions = ">=3.7.4"
[package.extras]
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
[[package]] [[package]]
category = "dev"
description = "Composable command line interface toolkit"
name = "click" name = "click"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "7.1.2" version = "7.1.2"
description = "Composable command line interface toolkit"
[[package]]
category = "dev" category = "dev"
description = "Cross-platform colored terminal text."
marker = "platform_system == \"Windows\" or sys_platform == \"win32\""
name = "colorama"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "0.4.3"
[[package]] [[package]]
name = "colorama"
version = "0.4.3"
description = "Cross-platform colored terminal text."
category = "dev" category = "dev"
description = "Code coverage measurement for Python" optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
marker = "platform_system == \"Windows\" or sys_platform == \"win32\""
[[package]]
name = "coverage" name = "coverage"
version = "5.3"
description = "Code coverage measurement for Python"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
version = "5.2.1"
[package.extras] [package.extras]
toml = ["toml"] toml = ["toml"]
[[package]] [[package]]
category = "dev"
description = "execnet: rapid multi-Python deployment"
name = "execnet" name = "execnet"
version = "1.7.1"
description = "execnet: rapid multi-Python deployment"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.7.1"
[package.dependencies]
apipkg = ">=1.4"
[package.extras] [package.extras]
testing = ["pre-commit"] testing = ["pre-commit"]
[[package]] [package.dependencies]
category = "dev" apipkg = ">=1.4"
description = "A platform independent file lock."
name = "filelock"
optional = false
python-versions = "*"
version = "3.0.12"
[[package]] [[package]]
name = "filelock"
version = "3.0.12"
description = "A platform independent file lock."
category = "dev" category = "dev"
description = "the modular source code checker: pep8 pyflakes and co" optional = false
python-versions = "*"
[[package]]
name = "flake8" name = "flake8"
version = "3.8.3"
description = "the modular source code checker: pep8 pyflakes and co"
category = "dev"
optional = false optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "3.8.3"
[package.dependencies] [package.dependencies]
mccabe = ">=0.6.0,<0.7.0" mccabe = ">=0.6.0,<0.7.0"
@@ -153,215 +155,214 @@ pycodestyle = ">=2.6.0a1,<2.7.0"
pyflakes = ">=2.2.0,<2.3.0" pyflakes = ">=2.2.0,<2.3.0"
[package.dependencies.importlib-metadata] [package.dependencies.importlib-metadata]
python = "<3.8"
version = "*" version = "*"
python = "<3.8"
[[package]] [[package]]
category = "dev"
description = "Polyfill package for Flake8 plugins"
name = "flake8-polyfill" name = "flake8-polyfill"
version = "1.0.2"
description = "Polyfill package for Flake8 plugins"
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "1.0.2"
[package.dependencies] [package.dependencies]
flake8 = "*" flake8 = "*"
[[package]] [[package]]
category = "dev"
description = "Git Object Database"
name = "gitdb" name = "gitdb"
version = "4.0.5"
description = "Git Object Database"
category = "dev"
optional = false optional = false
python-versions = ">=3.4" python-versions = ">=3.4"
version = "4.0.5"
[package.dependencies] [package.dependencies]
smmap = ">=3.0.1,<4" smmap = ">=3.0.1,<4"
[[package]] [[package]]
category = "dev"
description = "Python Git Library"
name = "gitpython" name = "gitpython"
version = "3.1.8"
description = "Python Git Library"
category = "dev"
optional = false optional = false
python-versions = ">=3.4" python-versions = ">=3.4"
version = "3.1.8"
[package.dependencies] [package.dependencies]
gitdb = ">=4.0.1,<5" gitdb = ">=4.0.1,<5"
[[package]] [[package]]
category = "dev"
description = "Read metadata from Python packages"
marker = "python_version < \"3.8\""
name = "importlib-metadata" name = "importlib-metadata"
version = "1.7.0"
description = "Read metadata from Python packages"
category = "dev"
optional = false optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
version = "1.7.0" marker = "python_version < \"3.8\""
[package.dependencies]
zipp = ">=0.5"
[package.extras] [package.extras]
docs = ["sphinx", "rst.linker"] docs = ["sphinx", "rst.linker"]
testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
[[package]] [package.dependencies]
category = "dev" zipp = ">=0.5"
description = "iniconfig: brain-dead simple config-ini parsing"
name = "iniconfig"
optional = false
python-versions = "*"
version = "1.0.1"
[[package]] [[package]]
name = "iniconfig"
version = "1.0.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev" category = "dev"
description = "A Python utility / library to sort Python imports." optional = false
python-versions = "*"
[[package]]
name = "isort" name = "isort"
version = "5.5.3"
description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false optional = false
python-versions = ">=3.6,<4.0" python-versions = ">=3.6,<4.0"
version = "5.5.1"
[package.extras] [package.extras]
colors = ["colorama (>=0.4.3,<0.5.0)"]
pipfile_deprecated_finder = ["pipreqs", "requirementslib"] pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
requirements_deprecated_finder = ["pipreqs", "pip-api"] requirements_deprecated_finder = ["pipreqs", "pip-api"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
[[package]] [[package]]
category = "dev"
description = "A fast and thorough lazy object proxy."
name = "lazy-object-proxy" name = "lazy-object-proxy"
version = "1.4.3"
description = "A fast and thorough lazy object proxy."
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.4.3"
[[package]] [[package]]
category = "dev"
description = "McCabe checker, plugin for flake8"
name = "mccabe" name = "mccabe"
version = "0.6.1"
description = "McCabe checker, plugin for flake8"
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "0.6.1"
[[package]] [[package]]
category = "dev"
description = "More routines for operating on iterables, beyond itertools"
name = "more-itertools" name = "more-itertools"
version = "8.5.0"
description = "More routines for operating on iterables, beyond itertools"
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "8.5.0"
[[package]] [[package]]
category = "dev"
description = "Optional static typing for Python"
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
name = "mypy" name = "mypy"
version = "0.782"
description = "Optional static typing for Python"
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "0.782" marker = "python_version < \"3.8\" or python_version >= \"3.8\""
[package.extras]
dmypy = ["psutil (>=4.0)"]
[package.dependencies] [package.dependencies]
mypy-extensions = ">=0.4.3,<0.5.0" mypy-extensions = ">=0.4.3,<0.5.0"
typed-ast = ">=1.4.0,<1.5.0" typed-ast = ">=1.4.0,<1.5.0"
typing-extensions = ">=3.7.4" typing-extensions = ">=3.7.4"
[package.extras]
dmypy = ["psutil (>=4.0)"]
[[package]] [[package]]
category = "dev"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
name = "mypy-extensions" name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "0.4.3"
[[package]] [[package]]
category = "dev"
description = "Core utilities for Python packages"
name = "packaging" name = "packaging"
version = "20.4"
description = "Core utilities for Python packages"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "20.4"
[package.dependencies] [package.dependencies]
pyparsing = ">=2.0.2" pyparsing = ">=2.0.2"
six = "*" six = "*"
[[package]] [[package]]
category = "dev"
description = "Utility library for gitignore style pattern matching of file paths."
name = "pathspec" name = "pathspec"
version = "0.8.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "0.8.0"
[[package]] [[package]]
category = "dev"
description = "Python Build Reasonableness"
name = "pbr" name = "pbr"
version = "5.5.0"
description = "Python Build Reasonableness"
category = "dev"
optional = false optional = false
python-versions = ">=2.6" python-versions = ">=2.6"
version = "5.5.0"
[[package]] [[package]]
category = "dev"
description = "Check PEP-8 naming conventions, plugin for flake8"
name = "pep8-naming" name = "pep8-naming"
version = "0.11.1"
description = "Check PEP-8 naming conventions, plugin for flake8"
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "0.11.1"
[package.dependencies] [package.dependencies]
flake8-polyfill = ">=1.0.2,<2" flake8-polyfill = ">=1.0.2,<2"
[[package]] [[package]]
category = "dev"
description = "plugin and hook calling mechanisms for python"
name = "pluggy" name = "pluggy"
version = "0.13.1"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.13.1"
[package.dependencies]
[package.dependencies.importlib-metadata]
python = "<3.8"
version = ">=0.12"
[package.extras] [package.extras]
dev = ["pre-commit", "tox"] dev = ["pre-commit", "tox"]
[package.dependencies]
[package.dependencies.importlib-metadata]
version = ">=0.12"
python = "<3.8"
[[package]] [[package]]
category = "dev"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
name = "py" name = "py"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.9.0" version = "1.9.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]] [[package]]
category = "dev"
description = "Python style guide checker"
name = "pycodestyle" name = "pycodestyle"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.6.0" version = "2.6.0"
description = "Python style guide checker"
[[package]]
category = "dev" category = "dev"
description = "passive checker of Python programs"
name = "pyflakes"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.2.0"
[[package]] [[package]]
name = "pyflakes"
version = "2.2.0"
description = "passive checker of Python programs"
category = "dev" category = "dev"
description = "python code static checker" optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "pylint" name = "pylint"
version = "2.6.0"
description = "python code static checker"
category = "dev"
optional = false optional = false
python-versions = ">=3.5.*" python-versions = ">=3.5.*"
version = "2.6.0"
[package.dependencies] [package.dependencies]
astroid = ">=2.4.0,<=2.5" astroid = ">=2.4.0,<=2.5"
@@ -371,20 +372,24 @@ mccabe = ">=0.6,<0.7"
toml = ">=0.7.1" toml = ">=0.7.1"
[[package]] [[package]]
category = "dev"
description = "Python parsing module"
name = "pyparsing" name = "pyparsing"
version = "2.4.7"
description = "Python parsing module"
category = "dev"
optional = false optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
version = "2.4.7"
[[package]] [[package]]
category = "dev"
description = "pytest: simple powerful testing with Python"
name = "pytest" name = "pytest"
version = "6.0.2"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "6.0.1"
[package.extras]
checkqa_mypy = ["mypy (0.780)"]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[package.dependencies] [package.dependencies]
atomicwrites = ">=1.0" atomicwrites = ">=1.0"
@@ -398,109 +403,105 @@ py = ">=1.8.2"
toml = "*" toml = "*"
[package.dependencies.importlib-metadata] [package.dependencies.importlib-metadata]
python = "<3.8"
version = ">=0.12" version = ">=0.12"
python = "<3.8"
[package.extras]
checkqa_mypy = ["mypy (0.780)"]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]] [[package]]
category = "dev"
description = "A pytest plugin to enable format checking with black"
name = "pytest-black" name = "pytest-black"
version = "0.3.11"
description = "A pytest plugin to enable format checking with black"
category = "dev"
optional = false optional = false
python-versions = ">=2.7" python-versions = ">=2.7"
version = "0.3.11"
[package.dependencies] [package.dependencies]
pytest = ">=3.5.0" pytest = ">=3.5.0"
toml = "*" toml = "*"
[package.dependencies.black] [package.dependencies.black]
python = ">=3.6"
version = "*" version = "*"
python = ">=3.6"
[[package]] [[package]]
category = "dev"
description = "Pytest plugin for measuring coverage."
name = "pytest-cov" name = "pytest-cov"
version = "2.10.1"
description = "Pytest plugin for measuring coverage."
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "2.10.1"
[package.extras]
testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"]
[package.dependencies] [package.dependencies]
coverage = ">=4.4" coverage = ">=4.4"
pytest = ">=4.6" pytest = ">=4.6"
[package.extras]
testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"]
[[package]] [[package]]
category = "dev"
description = "pytest plugin to check FLAKE8 requirements"
name = "pytest-flake8" name = "pytest-flake8"
version = "1.0.6"
description = "pytest plugin to check FLAKE8 requirements"
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "1.0.6"
[package.dependencies] [package.dependencies]
flake8 = ">=3.5" flake8 = ">=3.5"
pytest = ">=3.5" pytest = ">=3.5"
[[package]] [[package]]
category = "dev"
description = "run tests in isolated forked subprocesses"
name = "pytest-forked" name = "pytest-forked"
version = "1.3.0"
description = "run tests in isolated forked subprocesses"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "1.3.0"
[package.dependencies] [package.dependencies]
py = "*" py = "*"
pytest = ">=3.10" pytest = ">=3.10"
[[package]] [[package]]
category = "dev"
description = "py.test plugin to check import ordering using isort"
name = "pytest-isort" name = "pytest-isort"
version = "1.2.0"
description = "py.test plugin to check import ordering using isort"
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "1.2.0"
[package.dependencies]
isort = ">=4.0"
[package.extras] [package.extras]
tests = ["mock"] tests = ["mock"]
[package.dependencies]
isort = ">=4.0"
[[package]] [[package]]
category = "dev"
description = "Mypy static type checker plugin for Pytest"
name = "pytest-mypy" name = "pytest-mypy"
version = "0.7.0"
description = "Mypy static type checker plugin for Pytest"
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "0.7.0"
[package.dependencies] [package.dependencies]
filelock = ">=3.0" filelock = ">=3.0"
pytest = ">=3.5" pytest = ">=3.5"
[[package.dependencies.mypy]] [[package.dependencies.mypy]]
python = "<3.8"
version = ">=0.500" version = ">=0.500"
python = "<3.8"
[[package.dependencies.mypy]] [[package.dependencies.mypy]]
python = ">=3.8"
version = ">=0.700" version = ">=0.700"
python = ">=3.8"
[[package]] [[package]]
category = "dev"
description = "pytest plugin to check source code with pylint"
name = "pytest-pylint" name = "pytest-pylint"
version = "0.17.0"
description = "pytest plugin to check source code with pylint"
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "0.17.0"
[package.dependencies] [package.dependencies]
pylint = ">=2.3.0" pylint = ">=2.3.0"
@@ -508,119 +509,118 @@ pytest = ">=5.4"
toml = ">=0.7.1" toml = ">=0.7.1"
[[package]] [[package]]
category = "dev"
description = "pytest xdist plugin for distributed testing and loop-on-failing modes"
name = "pytest-xdist" name = "pytest-xdist"
version = "2.1.0"
description = "pytest xdist plugin for distributed testing and loop-on-failing modes"
category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "2.1.0"
[package.extras]
psutil = ["psutil (>=3.0)"]
testing = ["filelock"]
[package.dependencies] [package.dependencies]
execnet = ">=1.1" execnet = ">=1.1"
pytest = ">=6.0.0" pytest = ">=6.0.0"
pytest-forked = "*" pytest-forked = "*"
[package.extras]
psutil = ["psutil (>=3.0)"]
testing = ["filelock"]
[[package]] [[package]]
category = "dev"
description = "YAML parser and emitter for Python"
name = "pyyaml" name = "pyyaml"
version = "5.3.1"
description = "YAML parser and emitter for Python"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "5.3.1"
[[package]] [[package]]
category = "dev"
description = "Alternative regular expression module, to replace re."
name = "regex" name = "regex"
version = "2020.7.14"
description = "Alternative regular expression module, to replace re."
category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "2020.7.14"
[[package]] [[package]]
category = "dev"
description = "Python 2 and 3 compatibility utilities"
name = "six" name = "six"
version = "1.15.0"
description = "Python 2 and 3 compatibility utilities"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "1.15.0"
[[package]] [[package]]
category = "dev"
description = "A pure Python implementation of a sliding window memory map manager"
name = "smmap" name = "smmap"
version = "3.0.4"
description = "A pure Python implementation of a sliding window memory map manager"
category = "dev"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "3.0.4"
[[package]] [[package]]
category = "dev"
description = "Manage dynamic plugins for Python applications"
name = "stevedore" name = "stevedore"
version = "3.2.2"
description = "Manage dynamic plugins for Python applications"
category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
version = "3.2.1"
[package.dependencies] [package.dependencies]
pbr = ">=2.0.0,<2.1.0 || >2.1.0" pbr = ">=2.0.0,<2.1.0 || >2.1.0"
[package.dependencies.importlib-metadata] [package.dependencies.importlib-metadata]
python = "<3.8"
version = ">=1.7.0" version = ">=1.7.0"
python = "<3.8"
[[package]] [[package]]
category = "dev"
description = "Python Library for Tom's Obvious, Minimal Language"
name = "toml" name = "toml"
optional = false
python-versions = "*"
version = "0.10.1" version = "0.10.1"
description = "Python Library for Tom's Obvious, Minimal Language"
category = "dev"
optional = false
python-versions = "*"
[[package]] [[package]]
category = "dev"
description = "a fork of Python 2 and 3 ast modules with type comment support"
name = "typed-ast" name = "typed-ast"
optional = false
python-versions = "*"
version = "1.4.1" version = "1.4.1"
description = "a fork of Python 2 and 3 ast modules with type comment support"
category = "dev"
optional = false
python-versions = "*"
[[package]] [[package]]
category = "dev"
description = "Backported and Experimental Type Hints for Python 3.5+"
marker = "python_version < \"3.8\" or python_version >= \"3.8\""
name = "typing-extensions" name = "typing-extensions"
optional = false
python-versions = "*"
version = "3.7.4.3" version = "3.7.4.3"
description = "Backported and Experimental Type Hints for Python 3.5+"
[[package]]
category = "dev" category = "dev"
description = "Module for decorators, wrappers and monkey patching."
name = "wrapt"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "1.12.1"
[[package]] [[package]]
name = "wrapt"
version = "1.12.1"
description = "Module for decorators, wrappers and monkey patching."
category = "dev" category = "dev"
description = "Backport of pathlib-compatible object wrapper for zip files" optional = false
marker = "python_version < \"3.8\"" python-versions = "*"
[[package]]
name = "zipp" name = "zipp"
version = "3.1.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
version = "3.1.0" marker = "python_version < \"3.8\""
[package.extras] [package.extras]
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
testing = ["jaraco.itertools", "func-timeout"] testing = ["jaraco.itertools", "func-timeout"]
[metadata] [metadata]
content-hash = "cae6ccf55d29594d147c60854e21a096ff99fb7ddd17eddad568138bfde22179"
lock-version = "1.0" lock-version = "1.0"
python-versions = "^3.7" python-versions = "^3.7"
content-hash = "8dd6ef8098def46b656463f0ccb75b226e0aa719cb6fef709e1ef32bdf80e8a8"
[metadata.files] [metadata.files]
apipkg = [ apipkg = [
@@ -648,8 +648,7 @@ bandit = [
{file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"},
] ]
black = [ black = [
{file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
{file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"},
] ]
click = [ click = [
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
@@ -660,40 +659,40 @@ colorama = [
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
] ]
coverage = [ coverage = [
{file = "coverage-5.2.1-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:40f70f81be4d34f8d491e55936904db5c527b0711b2a46513641a5729783c2e4"}, {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"},
{file = "coverage-5.2.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:675192fca634f0df69af3493a48224f211f8db4e84452b08d5fcebb9167adb01"}, {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"},
{file = "coverage-5.2.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2fcc8b58953d74d199a1a4d633df8146f0ac36c4e720b4a1997e9b6327af43a8"}, {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"},
{file = "coverage-5.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:64c4f340338c68c463f1b56e3f2f0423f7b17ba6c3febae80b81f0e093077f59"}, {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"},
{file = "coverage-5.2.1-cp27-cp27m-win32.whl", hash = "sha256:52f185ffd3291196dc1aae506b42e178a592b0b60a8610b108e6ad892cfc1bb3"}, {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"},
{file = "coverage-5.2.1-cp27-cp27m-win_amd64.whl", hash = "sha256:30bc103587e0d3df9e52cd9da1dd915265a22fad0b72afe54daf840c984b564f"}, {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"},
{file = "coverage-5.2.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:9ea749fd447ce7fb1ac71f7616371f04054d969d412d37611716721931e36efd"}, {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"},
{file = "coverage-5.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ce7866f29d3025b5b34c2e944e66ebef0d92e4a4f2463f7266daa03a1332a651"}, {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"},
{file = "coverage-5.2.1-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:4869ab1c1ed33953bb2433ce7b894a28d724b7aa76c19b11e2878034a4e4680b"}, {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"},
{file = "coverage-5.2.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a3ee9c793ffefe2944d3a2bd928a0e436cd0ac2d9e3723152d6fd5398838ce7d"}, {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"},
{file = "coverage-5.2.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28f42dc5172ebdc32622a2c3f7ead1b836cdbf253569ae5673f499e35db0bac3"}, {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"},
{file = "coverage-5.2.1-cp35-cp35m-win32.whl", hash = "sha256:e26c993bd4b220429d4ec8c1468eca445a4064a61c74ca08da7429af9bc53bb0"}, {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"},
{file = "coverage-5.2.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4186fc95c9febeab5681bc3248553d5ec8c2999b8424d4fc3a39c9cba5796962"}, {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"},
{file = "coverage-5.2.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:b360d8fd88d2bad01cb953d81fd2edd4be539df7bfec41e8753fe9f4456a5082"}, {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"},
{file = "coverage-5.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:1adb6be0dcef0cf9434619d3b892772fdb48e793300f9d762e480e043bd8e716"}, {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"},
{file = "coverage-5.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:098a703d913be6fbd146a8c50cc76513d726b022d170e5e98dc56d958fd592fb"}, {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"},
{file = "coverage-5.2.1-cp36-cp36m-win32.whl", hash = "sha256:962c44070c281d86398aeb8f64e1bf37816a4dfc6f4c0f114756b14fc575621d"}, {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"},
{file = "coverage-5.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1ed2bdb27b4c9fc87058a1cb751c4df8752002143ed393899edb82b131e0546"}, {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"},
{file = "coverage-5.2.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:c890728a93fffd0407d7d37c1e6083ff3f9f211c83b4316fae3778417eab9811"}, {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"},
{file = "coverage-5.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:538f2fd5eb64366f37c97fdb3077d665fa946d2b6d95447622292f38407f9258"}, {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"},
{file = "coverage-5.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:27ca5a2bc04d68f0776f2cdcb8bbd508bbe430a7bf9c02315cd05fb1d86d0034"}, {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"},
{file = "coverage-5.2.1-cp37-cp37m-win32.whl", hash = "sha256:aab75d99f3f2874733946a7648ce87a50019eb90baef931698f96b76b6769a46"}, {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"},
{file = "coverage-5.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c2ff24df02a125b7b346c4c9078c8936da06964cc2d276292c357d64378158f8"}, {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"},
{file = "coverage-5.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:304fbe451698373dc6653772c72c5d5e883a4aadaf20343592a7abb2e643dae0"}, {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"},
{file = "coverage-5.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c96472b8ca5dc135fb0aa62f79b033f02aa434fb03a8b190600a5ae4102df1fd"}, {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"},
{file = "coverage-5.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8505e614c983834239f865da2dd336dcf9d72776b951d5dfa5ac36b987726e1b"}, {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"},
{file = "coverage-5.2.1-cp38-cp38-win32.whl", hash = "sha256:700997b77cfab016533b3e7dbc03b71d33ee4df1d79f2463a318ca0263fc29dd"}, {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"},
{file = "coverage-5.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:46794c815e56f1431c66d81943fa90721bb858375fb36e5903697d5eef88627d"}, {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"},
{file = "coverage-5.2.1-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:16042dc7f8e632e0dcd5206a5095ebd18cb1d005f4c89694f7f8aafd96dd43a3"}, {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"},
{file = "coverage-5.2.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c1bbb628ed5192124889b51204de27c575b3ffc05a5a91307e7640eff1d48da4"}, {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"},
{file = "coverage-5.2.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4f6428b55d2916a69f8d6453e48a505c07b2245653b0aa9f0dee38785939f5e4"}, {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"},
{file = "coverage-5.2.1-cp39-cp39-win32.whl", hash = "sha256:9e536783a5acee79a9b308be97d3952b662748c4037b6a24cbb339dc7ed8eb89"}, {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"},
{file = "coverage-5.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:b8f58c7db64d8f27078cbf2a4391af6aa4e4767cc08b37555c4ae064b8558d9b"}, {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"},
{file = "coverage-5.2.1.tar.gz", hash = "sha256:a34cb28e0747ea15e82d13e14de606747e9e484fb28d63c999483f5d5188e89b"}, {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"},
] ]
execnet = [ execnet = [
{file = "execnet-1.7.1-py2.py3-none-any.whl", hash = "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547"}, {file = "execnet-1.7.1-py2.py3-none-any.whl", hash = "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547"},
@@ -728,8 +727,8 @@ iniconfig = [
{file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"},
] ]
isort = [ isort = [
{file = "isort-5.5.1-py3-none-any.whl", hash = "sha256:a200d47b7ee8b7f7d0a9646650160c4a51b6a91a9413fd31b1da2c4de789f5d3"}, {file = "isort-5.5.3-py3-none-any.whl", hash = "sha256:c16eaa7432a1c004c585d79b12ad080c6c421dd18fe27982ca11f95e6898e432"},
{file = "isort-5.5.1.tar.gz", hash = "sha256:92533892058de0306e51c88f22ece002a209dc8e80288aa3cec6d443060d584f"}, {file = "isort-5.5.3.tar.gz", hash = "sha256:6187a9f1ce8784cbc6d1b88790a43e6083a6302f03e9ae482acc0f232a98c843"},
] ]
lazy-object-proxy = [ lazy-object-proxy = [
{file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"}, {file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"},
@@ -823,8 +822,8 @@ pyparsing = [
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
] ]
pytest = [ pytest = [
{file = "pytest-6.0.1-py3-none-any.whl", hash = "sha256:8b6007800c53fdacd5a5c192203f4e531eb2a1540ad9c752e052ec0f7143dbad"}, {file = "pytest-6.0.2-py3-none-any.whl", hash = "sha256:0e37f61339c4578776e090c3b8f6b16ce4db333889d65d0efb305243ec544b40"},
{file = "pytest-6.0.1.tar.gz", hash = "sha256:85228d75db9f45e06e57ef9bf4429267f81ac7c0d742cc9ed63d09886a9fe6f4"}, {file = "pytest-6.0.2.tar.gz", hash = "sha256:c8f57c2a30983f469bf03e68cdfa74dc474ce56b8f280ddcb080dfd91df01043"},
] ]
pytest-black = [ pytest-black = [
{file = "pytest-black-0.3.11.tar.gz", hash = "sha256:595eb0e7908b8a858a8564a5c8f0eae853c3926a4ec7b2afdfcedfa6fec65dd6"}, {file = "pytest-black-0.3.11.tar.gz", hash = "sha256:595eb0e7908b8a858a8564a5c8f0eae853c3926a4ec7b2afdfcedfa6fec65dd6"},
@@ -902,8 +901,8 @@ smmap = [
{file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"}, {file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"},
] ]
stevedore = [ stevedore = [
{file = "stevedore-3.2.1-py3-none-any.whl", hash = "sha256:ddc09a744dc224c84ec8e8efcb70595042d21c97c76df60daee64c9ad53bc7ee"}, {file = "stevedore-3.2.2-py3-none-any.whl", hash = "sha256:5e1ab03eaae06ef6ce23859402de785f08d97780ed774948ef16c4652c41bc62"},
{file = "stevedore-3.2.1.tar.gz", hash = "sha256:a34086819e2c7a7f86d5635363632829dab8014e5fd7be2454c7cba84ac7514e"}, {file = "stevedore-3.2.2.tar.gz", hash = "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0"},
] ]
toml = [ toml = [
{file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"},

View File

@@ -6,21 +6,26 @@ build-backend = "poetry.masonry.api"
[tool.poetry] [tool.poetry]
name = "pyrad3" name = "pyrad3"
version = "0.1.0" version = "0.1.0"
readme = "README.md" readme = "README.rst"
description = "RADIUS tools" description = "RADIUS tools"
keywords = ["AAA", "authentication", "authorization", "accounting", "RADIUS"] keywords = ["AAA", "authentication", "authorization", "accounting", "RADIUS"]
authors = ["Istvan Ruzman <istvan@ruzman.eu>"] authors = ["Istvan Ruzman <istvan@ruzman.eu>"]
classifiers = [ classifiers = [
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Intended Audience :: System Administrators",
"Intended Audience :: Telecommunications Industry", "Intended Audience :: Telecommunications Industry",
"License :: OSI Approved :: Apache Software License", "License :: OSI Approved :: Apache Software License",
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Systems Administration :: Authentication/Directory" "Topic :: System :: Networking",
"Topic :: System :: Systems Administration :: Authentication/Directory",
] ]
include = [ include = [
"LICENSE-APACHE", "LICENSE-APACHE",
@@ -37,7 +42,7 @@ python = "^3.7"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
black = { version = "^19.3.10b0", allow-prereleases = true } black = { version = "*", allow-prereleases = true }
bandit = "^1.6" bandit = "^1.6"
pep8-naming = "^0.11" pep8-naming = "^0.11"
pytest = "^6" pytest = "^6"
@@ -51,14 +56,15 @@ pytest-xdist = "^2.1.0"
[tool.black] [tool.black]
line-length = 80 line-length = 90
include = '\.py' include = '\.py'
target-version = ["py37"]
[tool.isort] [tool.isort]
combine_as_imports = true combine_as_imports = true
include_trailing_comma = true include_trailing_comma = true
line_length = 80 line_length = 90
multi_line_output = 3 multi_line_output = 3
use_parentheses = true use_parentheses = true

View File

@@ -4,6 +4,7 @@ in pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
git git
nixfmt nixfmt
freeradius
gnumake gnumake
python3 python3
python37 python37
@@ -17,6 +18,7 @@ in pkgs.mkShell {
python3Packages.coveralls python3Packages.coveralls
python3Packages.pep8-naming python3Packages.pep8-naming
python3Packages.poetry python3Packages.poetry
python3Packages.pygments
python3Packages.pytest python3Packages.pytest
python3Packages.pytest-black python3Packages.pytest-black
python3Packages.pytestcov python3Packages.pytestcov

View File

@@ -74,9 +74,7 @@ class Client(H.Host):
# have any implementation yet for non-Linux systems. # have any implementation yet for non-Linux systems.
# Better to fail loudly than to do something unexpected silently. # Better to fail loudly than to do something unexpected silently.
self._socket.setsockopt( self._socket.setsockopt(
socket.SOL_SOCKET, socket.SOL_SOCKET, socket.SO_BINDTODEVICE, self.interface.encode("utf-8"),
socket.SO_BINDTODEVICE,
self.interface.encode("utf-8"),
) )
self._poll = select.poll() self._poll = select.poll()
self._poll.register(self._socket, select.POLLIN) self._poll.register(self._socket, select.POLLIN)

View File

@@ -28,11 +28,7 @@ class ParseError(Exception):
"""RADIUS Dictionary Parser Error""" """RADIUS Dictionary Parser Error"""
def __init__( def __init__(
self, self, filename: str, msg: str = None, line: Optional[int] = None, **data,
filename: str,
msg: str = None,
line: Optional[int] = None,
**data,
): ):
super().__init__() super().__init__()
self.msg = msg self.msg = msg
@@ -115,9 +111,7 @@ class Dictionary:
loader = dict_loader(dictionary) loader = dict_loader(dictionary)
self.read_dictionary(loader) self.read_dictionary(loader)
def read_dictionary( def read_dictionary(self, reader: Generator[Tuple[int, List[str]], None, None]):
self, reader: Generator[Tuple[int, List[str]], None, None]
):
"""Read and parse a (Free)RADIUS dictionary.""" """Read and parse a (Free)RADIUS dictionary."""
self.filestack: List[str] = [] self.filestack: List[str] = []
for line_num, tokens in reader: for line_num, tokens in reader:
@@ -131,9 +125,7 @@ class Dictionary:
elif key == "FILE_OPENED": elif key == "FILE_OPENED":
LOG.info("Parsing file: %s", tokens[1]) LOG.info("Parsing file: %s", tokens[1])
if tokens[1] in self.filestack: if tokens[1] in self.filestack:
raise ParseError( raise ParseError(self.filestack[-1], "Include recursion detected")
self.filestack[-1], "Include recursion detected"
)
self.filestack.append(tokens[1]) self.filestack.append(tokens[1])
elif key == "FILE_CLOSED": elif key == "FILE_CLOSED":
filename = self.filestack.pop() filename = self.filestack.pop()
@@ -156,17 +148,13 @@ class Dictionary:
"END-TLV is deprecated and not supported by pyrad3" "END-TLV is deprecated and not supported by pyrad3"
) )
else: else:
raise ParseError( raise ParseError(self.filestack[-1], f"Invalid Token key {key}", line_num)
self.filestack[-1], f"Invalid Token key {key}", line_num
)
def _parse_vendor(self, tokens: Sequence[str], line_num: int): def _parse_vendor(self, tokens: Sequence[str], line_num: int):
"""Parse the vendor definition""" """Parse the vendor definition"""
filename = self.filestack[-1] filename = self.filestack[-1]
if len(tokens) not in [3, 4]: if len(tokens) not in [3, 4]:
raise ParseError( raise ParseError(filename, "Incorrect number of tokens for vendor statement")
filename, "Incorrect number of tokens for vendor statement"
)
vendor_name = tokens[1] vendor_name = tokens[1]
vendor_id = int(tokens[2], 0) vendor_id = int(tokens[2], 0)
continuation = False continuation = False
@@ -227,9 +215,7 @@ class Dictionary:
filename = self.filestack[-1] filename = self.filestack[-1]
if self.cur_vendor != self.rfc_vendor: if self.cur_vendor != self.rfc_vendor:
raise ParseError( raise ParseError(
filename, filename, "vendor-begin sections are not allowed to be nested", line_num,
"vendor-begin sections are not allowed to be nested",
line_num,
) )
if len(tokens) != 2: if len(tokens) != 2:
raise ParseError( raise ParseError(
@@ -252,9 +238,7 @@ class Dictionary:
filename = self.filestack[-1] filename = self.filestack[-1]
if len(tokens) != 2: if len(tokens) != 2:
raise ParseError( raise ParseError(
filename, filename, "Incorrect number of tokens for end-vendor statement", line_num,
"Incorrect number of tokens for end-vendor statement",
line_num,
) )
if self.cur_vendor.name != tokens[1]: if self.cur_vendor.name != tokens[1]:
raise ParseError( raise ParseError(
@@ -284,9 +268,7 @@ class Dictionary:
elif flag_len == 2: elif flag_len == 2:
value = flag[1] value = flag[1]
else: else:
raise ParseError( raise ParseError(filename, f"Incorrect attribute flag {flag}", line_num)
filename, f"Incorrect attribute flag {flag}", line_num
)
key = flag[0] key = flag[0]
if key == "has_tag": if key == "has_tag":
@@ -298,14 +280,10 @@ class Dictionary:
encrypt = Encrypt(int(value)) # type: ignore encrypt = Encrypt(int(value)) # type: ignore
except (ValueError, TypeError) as exc: except (ValueError, TypeError) as exc:
raise ParseError( raise ParseError(
filename, filename, f"Illegal attribute encryption {value}", line_num,
f"Illegal attribute encryption {value}",
line_num,
) from exc ) from exc
else: else:
raise ParseError( raise ParseError(filename, "Unknown attribute flag {key}", line_num)
filename, "Unknown attribute flag {key}", line_num
)
return has_tag, encrypt return has_tag, encrypt
@@ -328,9 +306,7 @@ class Dictionary:
) )
if code_num < 0: if code_num < 0:
raise ParseError( raise ParseError(
filename, filename, "negative attribute codes are not allowed", line_num,
"negative attribute codes are not allowed",
line_num,
) )
codes.append(code_num) codes.append(code_num)
return codes return codes
@@ -340,9 +316,7 @@ class Dictionary:
filename = self.filestack[-1] filename = self.filestack[-1]
if not len(tokens) in [4, 5]: if not len(tokens) in [4, 5]:
raise ParseError( raise ParseError(
filename, filename, "Incorrect number of tokens for attribute definition", line_num,
"Incorrect number of tokens for attribute definition",
line_num,
) )
has_tag, encrypt = self._parse_attribute_flags(tokens, line_num) has_tag, encrypt = self._parse_attribute_flags(tokens, line_num)
@@ -370,23 +344,15 @@ class Dictionary:
try: try:
attribute_type = Datatype[base_datatype] attribute_type = Datatype[base_datatype]
except KeyError as exc: except KeyError as exc:
raise ParseError( raise ParseError(filename, f"Illegal type: {datatype}", line_num) from exc
filename, f"Illegal type: {datatype}", line_num
) from exc
attribute = Attribute( attribute = Attribute(
name, name, codes[-1], attribute_type, {}, has_tag, encrypt, len(codes) > 1,
codes[-1],
attribute_type,
{},
has_tag,
encrypt,
len(codes) > 1,
) )
attrcode: Union[int, Tuple[int, ...]] = codes[0] if len( attrcode: Union[int, Tuple[int, ...]] = codes[0] if len(codes) == 1 else tuple(
codes codes
) == 1 else tuple(codes) )
self.cur_vendor.attrs[attrcode] = attribute self.cur_vendor.attrs[attrcode] = attribute
if self.cur_vendor != self.rfc_vendor: if self.cur_vendor != self.rfc_vendor:
@@ -398,9 +364,9 @@ class Dictionary:
) )
else: else:
LOG.info("Register Attribute %s", attribute.name) LOG.info("Register Attribute %s", attribute.name)
attrcode: Union[int, Tuple[int, ...]] = codes[0] if len( attrcode: Union[int, Tuple[int, ...]] = codes[0] if len(codes) == 1 else tuple(
codes codes
) == 1 else tuple(codes) )
self.attrindex[attrcode] = attribute self.attrindex[attrcode] = attribute
self.attrindex[name] = attribute self.attrindex[name] = attribute
@@ -409,9 +375,7 @@ class Dictionary:
filename = self.filestack[-1] filename = self.filestack[-1]
if len(tokens) != 4: if len(tokens) != 4:
raise ParseError( raise ParseError(
filename, filename, "Incorrect number of tokens for VALUE definition", line_num,
"Incorrect number of tokens for VALUE definition",
line_num,
) )
(attr_name, key, vvalue) = tokens[1:] (attr_name, key, vvalue) = tokens[1:]
@@ -429,9 +393,7 @@ class Dictionary:
attribute = self.attrindex[attr_name] attribute = self.attrindex[attr_name]
except KeyError as exc: except KeyError as exc:
raise ParseError( raise ParseError(
filename, filename, f"ATTRIBUTE {attr_name} has not been defined yet", line_num,
f"ATTRIBUTE {attr_name} has not been defined yet",
line_num,
) from exc ) from exc
try: try:
datatype = str(attribute.datatype).split(".")[1] datatype = str(attribute.datatype).split(".")[1]

View File

@@ -37,7 +37,7 @@ class Packet(OrderedDict):
radius_id: int, radius_id: int,
*, *,
request: "Packet" = None, request: "Packet" = None,
**attributes **attributes,
): ):
super().__init__(**attributes) super().__init__(**attributes)
self.code = code self.code = code
@@ -79,9 +79,7 @@ class Packet(OrderedDict):
raise PacketError("Packet has a wrong message authenticator") raise PacketError("Packet has a wrong message authenticator")
except KeyError as exc: except KeyError as exc:
if "EAP-Message" in reply: if "EAP-Message" in reply:
raise PacketError( raise PacketError("Packet is missing a message authenticator") from exc
"Packet is missing a message authenticator"
) from exc
return reply return reply
def send(self): def send(self):
@@ -134,11 +132,7 @@ class Packet(OrderedDict):
if self.code in (Code.AccessRequest, Code.StatusServer): if self.code in (Code.AccessRequest, Code.StatusServer):
hmac_builder.update(self.authenticator) hmac_builder.update(self.authenticator)
elif self.code in ( elif self.code in (Code.AccessAccept, Code.AccessChallenge, Code.AccessReject,):
Code.AccessAccept,
Code.AccessChallenge,
Code.AccessReject,
):
hmac_builder.update(self.request.authenticator) hmac_builder.update(self.request.authenticator)
else: else:
hmac_builder.update(16 * b"\00") hmac_builder.update(16 * b"\00")
@@ -202,7 +196,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
*, *,
code: Code = Code.AccessRequest, code: Code = Code.AccessRequest,
request: Optional[Packet] = None, request: Optional[Packet] = None,
**attributes **attributes,
): ):
super().__init__(host, code, radius_id, request=request, **attributes) super().__init__(host, code, radius_id, request=request, **attributes)
self.auth_type = auth_type self.auth_type = auth_type
@@ -217,7 +211,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
self.auth_type, self.auth_type,
request=self, request=self,
code=Code.AccessAccept, code=Code.AccessAccept,
**attributes **attributes,
) )
def create_reject(self, **attributes): def create_reject(self, **attributes):
@@ -228,7 +222,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
self.auth_type, self.auth_type,
request=self, request=self,
code=Code.AccessReject, code=Code.AccessReject,
**attributes **attributes,
) )
def create_challange(self, **attributes): def create_challange(self, **attributes):
@@ -239,7 +233,7 @@ class AuthPacket(Packet): # pylint: disable=abstract-method
self.auth_type, self.auth_type,
request=self, request=self,
code=Code.AccessChallenge, code=Code.AccessChallenge,
**attributes **attributes,
) )
def validate_password(self, password: bytes) -> bool: def validate_password(self, password: bytes) -> bool:
@@ -285,7 +279,7 @@ class AcctPacket(Packet): # pylint: disable=abstract-method
*, *,
code: Code = Code.AccountingRequest, code: Code = Code.AccountingRequest,
request: Optional[Packet] = None, request: Optional[Packet] = None,
**attributes **attributes,
): ):
super().__init__(host, code, radius_id, request=request, **attributes) super().__init__(host, code, radius_id, request=request, **attributes)
@@ -296,7 +290,7 @@ class AcctPacket(Packet): # pylint: disable=abstract-method
self.identifier, self.identifier,
code=Code.AccountingResponse, code=Code.AccountingResponse,
request=self, request=self,
**attributes **attributes,
) )
def increase_acct_delay_time(self, delay_time: float): def increase_acct_delay_time(self, delay_time: float):
@@ -322,26 +316,18 @@ class CoAPacket(Packet): # pylint: disable=abstract-method
*, *,
code: Code = Code.CoARequest, code: Code = Code.CoARequest,
request: Optional[Packet] = None, request: Optional[Packet] = None,
**attributes **attributes,
): ):
super().__init__(host, code, radius_id, request=request, **attributes) super().__init__(host, code, radius_id, request=request, **attributes)
def create_ack(self, **attributes): def create_ack(self, **attributes):
"""Create a RADIUS Packet of type CoA-Ack""" """Create a RADIUS Packet of type CoA-Ack"""
return CoAPacket( return CoAPacket(
self.host, self.host, self.identifier, code=Code.CoAACK, request=self, **attributes
self.identifier,
code=Code.CoAACK,
request=self,
**attributes
) )
def create_nack(self, **attributes): def create_nack(self, **attributes):
"""Create a RADIUS Packet of type CoA-Nack""" """Create a RADIUS Packet of type CoA-Nack"""
return CoAPacket( return CoAPacket(
self.host, self.host, self.identifier, code=Code.CoANAK, request=self, **attributes
self.identifier,
code=Code.CoANAK,
request=self,
**attributes
) )

View File

@@ -45,9 +45,7 @@ def encode_ipv4_address(addr: Union[str, IPv4Address]) -> bytes:
def encode_ipv4_prefix(network: Union[str, IPv4Network]) -> bytes: def encode_ipv4_prefix(network: Union[str, IPv4Network]) -> bytes:
"""Encode a RADIUS value of type ipv4prefix""" """Encode a RADIUS value of type ipv4prefix"""
address = IPv4Network(network) address = IPv4Network(network)
return ( return struct.pack("2B", 0, address.prefixlen) + address.network_address.packed
struct.pack("2B", 0, address.prefixlen) + address.network_address.packed
)
def encode_ipv6_address(addr: Union[str, IPv6Address]) -> bytes: def encode_ipv6_address(addr: Union[str, IPv6Address]) -> bytes:

View File

@@ -22,9 +22,7 @@ class PacketError(Exception):
Header = namedtuple("Header", ["code", "radius_id", "length", "authenticator"]) Header = namedtuple("Header", ["code", "radius_id", "length", "authenticator"])
Attribute = namedtuple( Attribute = namedtuple("Attribute", ["name", "pos", "type", "length", "tag", "value"])
"Attribute", ["name", "pos", "type", "length", "tag", "value"]
)
PreParsedAttributes = List[Tuple[Tuple[int, ...], bytes, int]] PreParsedAttributes = List[Tuple[Tuple[int, ...], bytes, int]]
SpecialTlvDescription = Tuple[Tuple[int, ...], bytes, int] SpecialTlvDescription = Tuple[Tuple[int, ...], bytes, int]
@@ -52,9 +50,7 @@ def decode_header(raw_packet: bytes) -> Header:
return Header(*header) return Header(*header)
def decode_attributes( def decode_attributes(rad_dict: Dictionary, raw_packet: bytes) -> List[Attribute]:
rad_dict: Dictionary, raw_packet: bytes
) -> List[Attribute]:
"""Decode the Attributes in a RADIUS Packet. """Decode the Attributes in a RADIUS Packet.
This function skips the Header. The Header must be decoded and verified This function skips the Header. The Header must be decoded and verified
@@ -139,9 +135,7 @@ def pre_decode_attributes( # pylint: disable=too-many-branches
adef = rad_dict.attrindex.get(key) adef = rad_dict.attrindex.get(key)
if adef is not None and adef.datatype == Datatype.tlv: if adef is not None and adef.datatype == Datatype.tlv:
# TODO: deal with tagged tlvs # TODO: deal with tagged tlvs
attributes.extend( attributes.extend(decode_tlv(rad_dict, list(key), value, offset))
decode_tlv(rad_dict, list(key), value, offset)
)
else: else:
attributes.append((key, value, offset)) attributes.append((key, value, offset))
offset += length offset += length
@@ -273,9 +267,7 @@ def calculate_authenticator(
secret: bytes, authenticator: bytes, raw_packet: bytes secret: bytes, authenticator: bytes, raw_packet: bytes
) -> bytes: ) -> bytes:
"""Calculate the Authenticator for the RADIUS Packet""" """Calculate the Authenticator for the RADIUS Packet"""
return MD5( return MD5(raw_packet[0:4] + authenticator + raw_packet[20:] + secret).digest()
raw_packet[0:4] + authenticator + raw_packet[20:] + secret
).digest()
def validate_pap_password( def validate_pap_password(
@@ -291,9 +283,7 @@ def validate_pap_password(
return obfuscated_password == obf_pass return obfuscated_password == obf_pass
def password_encode( def password_encode(secret: bytes, authenticator: bytes, password: bytes) -> bytes:
secret: bytes, authenticator: bytes, password: bytes
) -> bytes:
"""Obfuscate the plaintext Password for RADIUS""" """Obfuscate the plaintext Password for RADIUS"""
buf = password + b"\x00" * (16 - (len(password) % 16)) buf = password + b"\x00" * (16 - (len(password) % 16))
last = authenticator last = authenticator
@@ -348,22 +338,14 @@ def create_chap_password(
def validate_chap_password( def validate_chap_password(
chap_id: bytes, chap_id: bytes, challenge: bytes, chap_password: bytes, plaintext_password: bytes,
challenge: bytes,
chap_password: bytes,
plaintext_password: bytes,
) -> bool: ) -> bool:
"""Validate the CHAP password against the given plaintext password""" """Validate the CHAP password against the given plaintext password"""
return chap_password == create_chap_password( return chap_password == create_chap_password(chap_id, challenge, plaintext_password)
chap_id, challenge, plaintext_password
)
def salt_encrypt( def salt_encrypt(
secret: bytes, secret: bytes, authenticator: bytes, value: bytes, salt: Optional[int] = None,
authenticator: bytes,
value: bytes,
salt: Optional[int] = None,
) -> bytes: ) -> bytes:
"""Salt Encrypt the given value""" """Salt Encrypt the given value"""
if salt is None: if salt is None:

View File

@@ -63,9 +63,7 @@ def test_valid_vendor_definitions(vendor):
def test_closing_wrong_vendor(): def test_closing_wrong_vendor():
dictionary = StringIO( dictionary = StringIO(
"VENDOR TEST-VENDOR 1234\n" "VENDOR TEST-VENDOR 1234\n" "BEGIN-VENDOR TEST-VENDOR\n" "END-VENDOR WRONG-VENDOR"
"BEGIN-VENDOR TEST-VENDOR\n"
"END-VENDOR WRONG-VENDOR"
) )
with pytest.raises(ParseError): with pytest.raises(ParseError):
Dictionary("", dictionary) Dictionary("", dictionary)
@@ -121,8 +119,7 @@ def test_valid_attribute_numbers(number):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"invalid_number", "invalid_number", ["1000", "ABCD", "-1", "inf", "INF", "-INF", "2e4", "2.5e3"],
["1000", "ABCD", "-1", "inf", "INF", "-INF", "2e4", "2.5e3"],
) )
def test_invalid_attribute_numbers(invalid_number): def test_invalid_attribute_numbers(invalid_number):
dictionary = StringIO(f"ATTRIBUTE NAME {invalid_number} integer64") dictionary = StringIO(f"ATTRIBUTE NAME {invalid_number} integer64")
@@ -160,8 +157,7 @@ def test_invalid_attr_type():
@pytest.mark.parametrize("value", ["1", "0x1", "0o1"]) @pytest.mark.parametrize("value", ["1", "0x1", "0o1"])
def test_value_definition(value): def test_value_definition(value):
dictionary = StringIO( dictionary = StringIO(
"ATTRIBUTE TEST-ATTRIBUTE 1 byte\n" "ATTRIBUTE TEST-ATTRIBUTE 1 byte\n" f"VALUE TEST-ATTRIBUTE TEST-VALUE {value}"
f"VALUE TEST-ATTRIBUTE TEST-VALUE {value}"
) )
Dictionary("", dictionary) Dictionary("", dictionary)
@@ -290,9 +286,7 @@ def test_valid_datatypes_in_vendor_space(datatype):
Dictionary("", dictionary) Dictionary("", dictionary)
@pytest.mark.parametrize( @pytest.mark.parametrize("datatype", ["concat", "extended", "long-extended", "evs"])
"datatype", ["concat", "extended", "long-extended", "evs"]
)
def test_invalid_datatypes_in_vendor_space(datatype): def test_invalid_datatypes_in_vendor_space(datatype):
dictionary = StringIO( dictionary = StringIO(
"VENDOR TEST 1234\n" "VENDOR TEST 1234\n"
@@ -305,8 +299,7 @@ def test_invalid_datatypes_in_vendor_space(datatype):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"invalid_number", "invalid_number", ["ABCD", "-1", "inf", "INF", "-INF", "0.1", "2e4", "2.5e3"],
["ABCD", "-1", "inf", "INF", "-INF", "0.1", "2e4", "2.5e3"],
) )
def test_invalid_value_numbers(invalid_number): def test_invalid_value_numbers(invalid_number):
dictionary = StringIO( dictionary = StringIO(
@@ -340,9 +333,7 @@ def test_value_for_non_existing_attribute():
], ],
) )
def test_value_for_wrong_datatype(datatype): def test_value_for_wrong_datatype(datatype):
dictionary = StringIO( dictionary = StringIO(f"ATTRIBUTE NAME 123 {datatype}\n" "VALUE NAME VNAME 256")
f"ATTRIBUTE NAME 123 {datatype}\n" "VALUE NAME VNAME 256"
)
with pytest.raises(ParseError): with pytest.raises(ParseError):
Dictionary("", dictionary) Dictionary("", dictionary)
@@ -398,9 +389,7 @@ def test_get_attributes_from_dictionaries(attribute):
_ = dd[attribute] _ = dd[attribute]
@pytest.mark.parametrize( @pytest.mark.parametrize("attribute", ["RFC-ATTRIBUTE1", 8, (26, 5556, 7), (26, 5555, 8)])
"attribute", ["RFC-ATTRIBUTE1", 8, (26, 5556, 7), (26, 5555, 8)]
)
def test_get_nonexisting_attributes_from_dictionaries(attribute): def test_get_nonexisting_attributes_from_dictionaries(attribute):
dictionary = StringIO( dictionary = StringIO(
"ATTRIBUTE RFC-ATTRIBUTE 7 integer\n" "ATTRIBUTE RFC-ATTRIBUTE 7 integer\n"

View File

@@ -148,9 +148,7 @@ def flattened_product(l1, l2):
return result return result
VENDOR_TEST_ATTRIBUTES = flattened_product( VENDOR_TEST_ATTRIBUTES = flattened_product(VENDOR_FORMAT_COMBINATIONS, TEST_ATTRIBUTES)
VENDOR_FORMAT_COMBINATIONS, TEST_ATTRIBUTES
)
VENDOR_TAGGED_ATTRIBUTES = flattened_product( VENDOR_TAGGED_ATTRIBUTES = flattened_product(
VENDOR_FORMAT_COMBINATIONS, TAGGED_ATTRIBUTES VENDOR_FORMAT_COMBINATIONS, TAGGED_ATTRIBUTES
) )
@@ -206,13 +204,7 @@ def generate_vendor_attribute(vendor_id, tlen, llen, attr_bytes):
attr_bytes = attr_bytes[2:] attr_bytes = attr_bytes[2:]
packet = ( packet = (
bytes(20) bytes(20) + b"\x1a" + vsa_length + vendor_id + attr_type + attr_len + attr_bytes
+ b"\x1a"
+ vsa_length
+ vendor_id
+ attr_type
+ attr_len
+ attr_bytes
) )
return packet return packet
@@ -268,9 +260,7 @@ def test_password(plaintext, obfuscated, authenticator):
assert len(decoded) == len(plaintext) assert len(decoded) == len(plaintext)
assert decoded == plaintext assert decoded == plaintext
assert utils.validate_pap_password( assert utils.validate_pap_password(SECRET, authenticator, encoded, plaintext)
SECRET, authenticator, encoded, plaintext
)
@pytest.mark.parametrize( @pytest.mark.parametrize(