"]
6 | readme = "README.md"
7 | repository = "https://github.com/Luttik/auto-optional"
8 | homepage = "https://auto-optional.daanluttik.nl"
9 | documentation = "https://auto-optional.daanluttik.nl"
10 |
11 | [tool.poetry.scripts]
12 | auto-optional = "auto_optional.main:app"
13 |
14 | [tool.poetry.dependencies]
15 | python = ">3.7, <4.0"
16 | libcst = "^0.3.20"
17 | typer = "^0.4.0"
18 |
19 | [tool.poetry.dev-dependencies]
20 | pytest = "^6.2.4"
21 | black = "^21.8b0"
22 | isort = "^5.9.3"
23 | invoke = "^1.6.0"
24 | mypy = "^0.910"
25 | flake8 = "^3.9.2"
26 | flake8-annotations = "^2.6.2"
27 | flake8-black = "^0.2.3"
28 | flake8-isort = "^4.0.0"
29 | pytest-cov = "^2.12.1"
30 | codecov = "^2.1.12"
31 | mkdocs = "^1.2.3"
32 | mkdocs-material = "^7.2.6"
33 | PyYAML = "^5.4.1"
34 | pydantic = "^1.8.2"
35 | types-PyYAML = "^5.4.10"
36 |
37 | [tool.coverage.paths]
38 | source = ["src", "*/site-packages"]
39 |
40 | [tool.coverage.run]
41 | branch = true
42 | source = ["auto_optional"]
43 |
44 | [build-system]
45 | requires = ["poetry-core>=1.0.0"]
46 | build-backend = "poetry.core.masonry.api"
47 |
--------------------------------------------------------------------------------
/docs/assets/images/logo-shape-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.github/workflows/cd.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run test and lint with a variety of Python versions
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: CD
5 |
6 | on:
7 | push:
8 | tags:
9 | 'v*'
10 |
11 | jobs:
12 | build-python:
13 | runs-on: ubuntu-latest
14 | strategy:
15 | matrix:
16 | python-version: [3.8]
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 | - id: get_version
21 | name: get version from tag
22 | uses: battila7/get-version-action@v2
23 | - name: Set up Python ${{ matrix.python-version }}
24 | uses: actions/setup-python@v1
25 | with:
26 | python-version: ${{ matrix.python-version }}
27 | - name: Install python dependencies
28 | run: |
29 | python -m pip install --upgrade pip
30 | pip install poetry
31 | poetry config virtualenvs.create false
32 | poetry install
33 | - name: Lint with flake8
34 | run: |
35 | inv lint
36 | - name: Test with pytest
37 | run: |
38 | inv test
39 | - name: Publish to pypi
40 | run: |
41 | poetry version ${{ steps.get_version.outputs.version-without-v }}
42 | poetry publish --build --username "__token__" --password "${{ secrets.PYPI_TOKEN }}"
43 | - name: Upload Python resources to release
44 | uses: svenstaro/upload-release-action@v2
45 | with:
46 | repo_token: ${{ secrets.GITHUB_TOKEN }}
47 | file: dist/*
48 | tag: ${{ github.ref }}
49 | file_glob: true
50 | - name: Update docs
51 | run: |
52 | mkdocs gh-deploy --force
53 |
--------------------------------------------------------------------------------
/docs/stylesheets/extra-style.css:
--------------------------------------------------------------------------------
1 | :root [data-md-color-scheme="default"] {
2 | --md-primary-fg-color: #fff;
3 | --md-default-bg-color: #fff;
4 | --md-code-fg-color: #000;
5 | --md-primary-bg-color: #000;
6 | --md-accent-fg-color: #07a;
7 | --md-typeset-color: #000;
8 | --md-typeset-a-color: #07a;
9 | --md-inline-code-fg-color: #dd4a68;
10 | }
11 |
12 | [data-md-color-scheme="slate"] {
13 | --md-primary-fg-color: #202124;
14 | --md-default-bg-color: #202124;
15 | --md-code-fg-color: #fff;
16 | --md-typeset-color: #fff;
17 | --md-primary-bg-color: #fff;
18 | --md-accent-fg-color: #3ac5ff;
19 | --md-typeset-a-color: #3ac5ff;
20 | --md-code-bg-color: #151517;
21 | --md-inline-code-fg-color: #dd4a68;
22 | }
23 |
24 | svg {
25 | shape-rendering: geometricPrecision;
26 | }
27 |
28 |
29 | .md-typeset code {
30 | color: var(--md-inline-code-fg-color);
31 | border-radius: 6pt;
32 | padding: 4pt 6pt;
33 | font-size: .8em;
34 | }
35 |
36 | .md-typeset blockquote {
37 | color: var(--md-typeset-color);
38 | border-left-color: var(--md-accent-fg-color);
39 | }
40 |
41 | .md-footer, .md-footer-copyright {
42 | display: none;
43 | }
44 |
45 | .md-typeset {
46 | line-height: 2em;
47 | }
48 |
49 | b, strong {
50 | font-weight: 600;
51 | }
52 |
53 | .md-header {
54 | box-shadow: 0 0.2rem 0.4rem rgba(0, 0, 0, 0.1) !important;
55 | }
56 |
57 | body[data-md-color-scheme="default"] .md-header__button.md-logo img {
58 | filter: invert(1);
59 | }
60 |
61 | [data-md-color-scheme="default"] .md-header img {
62 | rgba(var(--md-primary-bg-color), .7)
63 | }
64 |
65 | .md-header .md-search__form {
66 | background-color: rgba(0, 0, 0, .05);
67 | }
68 |
69 | .md-header .md-search .md-search__input, .md-header .md-search .md-search__icon {
70 | color: var(--md-code-fg-color);
71 | }
72 |
73 | .md-header .md-search .md-search__input::placeholder {
74 | color: rgba(var(--md-typeset-color), .4)
75 | }
76 |
77 |
78 | h1,
79 | h2,
80 | h3,
81 | h4,
82 | h5,
83 | h6 {
84 | line-height: 1.5em;
85 | margin-block-start: 1.75em;
86 | margin-block-end: 0.5em;
87 | color: var(--md-typeset-color) !important;
88 | font-weight: bold !important;
89 | }
90 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run test and lint with a variety of Python versions
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: CI
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 |
13 | jobs:
14 | lint:
15 | runs-on: ubuntu-latest
16 | strategy:
17 | matrix:
18 | python-version: [3.9]
19 |
20 | steps:
21 | - uses: actions/checkout@v2
22 | - name: Set up Python ${{ matrix.python-version }}
23 | uses: actions/setup-python@v1
24 | with:
25 | python-version: ${{ matrix.python-version }}
26 | - name: Install dependencies
27 | run: |
28 | python -m pip install --upgrade pip
29 | pip install poetry
30 | poetry config virtualenvs.create false
31 | poetry install
32 | - name: Lint
33 | run: |
34 | inv lint
35 |
36 | test:
37 | runs-on: ubuntu-latest
38 | strategy:
39 | matrix:
40 | python-version: [3.7, 3.8, 3.9]
41 |
42 | steps:
43 | - uses: actions/checkout@v2
44 | - name: Set up Python ${{ matrix.python-version }}
45 | uses: actions/setup-python@v1
46 | with:
47 | python-version: ${{ matrix.python-version }}
48 | - name: Install dependencies
49 | run: |
50 | python -m pip install --upgrade pip
51 | pip install poetry
52 | poetry config virtualenvs.create false
53 | poetry install
54 | - name: Test
55 | run: |
56 | inv test
57 |
58 | code-cov:
59 | runs-on: ubuntu-latest
60 | strategy:
61 | matrix:
62 | python-version: [3.9]
63 |
64 | steps:
65 | - uses: actions/checkout@v2
66 | - name: Set up Python ${{ matrix.python-version }}
67 | uses: actions/setup-python@v1
68 | with:
69 | python-version: ${{ matrix.python-version }}
70 | - name: Install dependencies
71 | run: |
72 | python -m pip install --upgrade pip
73 | pip install poetry
74 | poetry config virtualenvs.create false
75 | poetry install
76 | - name: upload codecov data
77 | run: |
78 | pytest --cov --cov-fail-under=0 --cov-report xml
79 | codecov
80 | env:
81 | CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # auto-optional
2 |
3 |
4 |
5 |
6 | auto-optional: adds the Optional type-hint to arguments where the default value is None
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ---
31 |
32 | **Documentation**: [auto-optional.daanluttik.nl](https://auto-optional.daanluttik.nl)
33 |
34 | **Source Code**: [github.com/luttik/auto-optional](https://github.com/Luttik/auto-optional)
35 |
36 | ---
37 |
38 | ## What does auto-optional do
39 | The basic purpose of auto-optional is ensuring that whenever a default argument is `None` the type annotation is Optional.
40 |
41 | For example:
42 | ```py
43 | def foo(bar: str = None):
44 | ...
45 | ```
46 |
47 | Would turn into
48 |
49 | ```py
50 | from typing import Optional
51 | def foo(bar: Optional[str] = None):
52 | ...
53 | ```
54 |
55 | ## Why would you want this
56 |
57 | - Easily modify external libraries that didn't pay attention
58 | to proper use of optional to improve mypy lintingf.
59 | - Force consistency in your own code-base:
60 | Enforcing that `None` parameter implies an `Optional` type.
61 | - Explicit is better than implicit — [pep 20](https://www.python.org/dev/peps/pep-0020/)
62 |
63 | ## In the media:
64 | auto-optional was covered on
65 | [PythonBytes #251](https://pythonbytes.fm/episodes/show/251/a-95-complete-episode-wait-for-it)
66 |
67 | > I love these little tools that you can run against your code that will just reformat them to be better.
68 | >
69 | > — Michael Kennedy
70 |
71 | ## Install
72 | Install with `pip install auto-optional`.
73 |
74 | ## Run
75 | After installing you can run auto-optional using `auto-optional [paths...]`
76 | (if no path is provided it'll process the current working directory).
77 |
78 | ## pre-commit
79 |
80 | You can run auto-optional via [pre-commit](https://pre-commit.com/).
81 | Add the following text to your repositories `.pre-commit-config.yaml`:
82 |
83 | ```yaml
84 | repos:
85 | - repo: https://github.com/luttik/auto-optional
86 | rev: v0.3.1 # The version of auto-optional to use
87 | hooks:
88 | - id: auto-optional
89 | ```
90 |
91 | ## Things of note
92 |
93 | ### Things that are handled well
94 |
95 | - The alternatives to `Optional` are supported, that means both;
96 | - `Union[X, None]`
97 | - `x | None` (allowed since python 3.10+).
98 | - Existing imports are reused.
99 | - `import as` and `from typing import ...` statements are properly handled.
100 |
101 | ### Things that need improvement
102 | For all these points you can leave a thumbs-up if you want it. Also, I welcome pull-requests for these issues.
103 |
104 | - There is no exclude (for file patterns) option yet [[#2]](https://github.com/Luttik/auto-optional/issues/2)
105 | - There is no ignore (for code lines) option yet [[#3]](https://github.com/Luttik/auto-optional/issues/3)
106 | - Code is aways read and written as `UTF-8` (which is accurate most of the time). [[#4]](https://github.com/Luttik/auto-optional/issues/4)
107 | - There is no `diff` or `check` command yet for a dry-run or linting. [[#5]](https://github.com/Luttik/auto-optional/issues/5)
108 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | hide:
3 | - navigation
4 | ---
5 |
6 | # auto-optional
7 |
8 |
9 |
10 |
11 | auto-optional: adds the Optional type-hint to arguments where the default value is None
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | ---
36 |
37 | **Documentation**: [auto-optional.daanluttik.nl](https://auto-optional.daanluttik.nl)
38 |
39 | **Source Code**: [github.com/luttik/auto-optional](https://github.com/Luttik/auto-optional)
40 |
41 | ---
42 |
43 | ## What does auto-optional do
44 | The basic purpose of auto-optional is ensuring that whenever a default argument is `None` the type annotation is Optional.
45 |
46 | For example:
47 | ```py
48 | def foo(bar: str = None):
49 | ...
50 | ```
51 |
52 | Would turn into
53 |
54 | ```py
55 | from typing import Optional
56 | def foo(bar: Optional[str] = None):
57 | ...
58 | ```
59 |
60 | ## Why would you want this
61 |
62 | - Easily modify external libraries that didn't pay attention
63 | to proper use of optional to improve mypy linting.
64 | - Force consistency in your own code-base:
65 | Enforcing that `None` parameter implies an `Optional` type.
66 | - Explicit is better than implicit — [pep 20](https://www.python.org/dev/peps/pep-0020/)
67 |
68 | ## In the media:
69 | auto-optional was covered on
70 | [PythonBytes #251](https://pythonbytes.fm/episodes/show/251/a-95-complete-episode-wait-for-it)
71 |
72 | > I love these little tools that you can run against your code that will just reformat them to be better.
73 | >
74 | > — Michael Kennedy
75 |
76 | ## Install
77 | Install with `pip install auto-optional`.
78 |
79 | ## Run
80 | After installing you can run auto-optional using`auto-optional [paths...]`
81 | (if no path is provided it'll process the current working directory).
82 |
83 | ## pre-commit
84 |
85 | You can run auto-optional via [pre-commit](https://pre-commit.com/).
86 | Add the following text to your repositories `.pre-commit-config.yaml`:
87 |
88 | ```yaml
89 | repos:
90 | - repo: https://github.com/luttik/auto-optional
91 | rev: v0.2.0 # The version of auto-optional to use
92 | hooks:
93 | - id: auto-optional
94 | ```
95 |
96 | ## Things of note
97 |
98 | ### Things that are handled well
99 |
100 | - The alternatives to `Optional` are supported, that means both;
101 | - `Union[X, None]`
102 | - `x | None` (allowed since python 3.10+).
103 | - Existing imports are reused.
104 | - `import as` and `from typing import ...` statements are properly handled.
105 |
106 | ### Things that need improvement
107 | For all these points you can leave a thumbs-up if you want it. Also, I welcome pull-requests for these issues.
108 |
109 | - There is no exclude (for file patterns) option yet [[#2]](https://github.com/Luttik/auto-optional/issues/2)
110 | - There is no ignore (for code lines) option yet [[#3]](https://github.com/Luttik/auto-optional/issues/3)
111 | - Code is aways read and written as `UTF-8` (which is accurate most of the time). [[#4]](https://github.com/Luttik/auto-optional/issues/4)
112 | - There is no `diff` or `check` command yet for a dry-run or linting. [[#5]](https://github.com/Luttik/auto-optional/issues/5)
113 |
--------------------------------------------------------------------------------
/test/test_all.py:
--------------------------------------------------------------------------------
1 | from abc import ABC
2 | from pathlib import Path
3 | from typing import List, Union
4 |
5 | import py
6 | import pytest
7 | from pydantic import BaseModel
8 | from typer.testing import CliRunner
9 | from yaml import load
10 |
11 | from auto_optional.file_handling import convert_file
12 | from auto_optional.main import app
13 |
14 | try:
15 | from yaml import CLoader as YamlLoader
16 | except ImportError:
17 | from yaml import YamlLoader # type: ignore
18 |
19 |
20 | runner = CliRunner()
21 |
22 |
23 | class BaseTestConfig(BaseModel, ABC):
24 | name: str
25 |
26 |
27 | class BeforeAndAfterTest(BaseTestConfig):
28 | before: str
29 | after: str
30 |
31 |
32 | class UnchangedTest(BaseTestConfig):
33 | unchanged: str
34 |
35 |
36 | class SimpleTestConfig(BaseModel):
37 | tests: List[Union[BeforeAndAfterTest, UnchangedTest]]
38 |
39 |
40 | def get_singe_file_tests() -> List:
41 | with (Path(__file__).parent / "simple-tests.yaml").open() as file:
42 | return SimpleTestConfig(
43 | **load(
44 | file,
45 | Loader=YamlLoader,
46 | )
47 | ).tests
48 |
49 |
50 | SINGLE_FILE_TESTS = get_singe_file_tests()
51 |
52 |
53 | def prepare_file(
54 | test_config: Union[BeforeAndAfterTest, UnchangedTest], tmpdir: Path
55 | ) -> Path:
56 | if isinstance(test_config, BeforeAndAfterTest):
57 | code = test_config.before
58 | elif isinstance(test_config, UnchangedTest):
59 | code = test_config.unchanged
60 | else:
61 | raise NotImplementedError(
62 | f"tests of type {type(test_config)} are not yet supported"
63 | )
64 |
65 | code_path = tmpdir / f"{hash(code)}.py"
66 | code_path.write_text(code)
67 | return code_path
68 |
69 |
70 | def assert_code_processed_correctly(
71 | test_config: Union[BeforeAndAfterTest, UnchangedTest],
72 | path: Path,
73 | ) -> None:
74 | if isinstance(test_config, BeforeAndAfterTest):
75 | code = test_config.after
76 | elif isinstance(test_config, UnchangedTest):
77 | code = test_config.unchanged
78 | else:
79 | raise NotImplementedError(
80 | f"tests of type {type(test_config)} are not yet supported"
81 | )
82 |
83 | assert path.read_text() == code
84 |
85 |
86 | @pytest.mark.parametrize(
87 | "test_config",
88 | SINGLE_FILE_TESTS,
89 | ids=[test.name for test in SINGLE_FILE_TESTS],
90 | )
91 | def test_single_files_from_yaml(
92 | test_config: Union[BeforeAndAfterTest, UnchangedTest]
93 | ) -> None:
94 | if isinstance(test_config, BeforeAndAfterTest):
95 | assert convert_file(test_config.before) == test_config.after
96 | elif isinstance(test_config, UnchangedTest):
97 | assert convert_file(test_config.unchanged) == test_config.unchanged
98 | else:
99 | raise NotImplementedError(
100 | f"tests of type {type(test_config)} are not yet supported"
101 | )
102 |
103 |
104 | @pytest.mark.parametrize(
105 | "test_config",
106 | SINGLE_FILE_TESTS,
107 | ids=[test.name for test in SINGLE_FILE_TESTS],
108 | )
109 | def test_cli_single_files_from_yaml(
110 | test_config: Union[BeforeAndAfterTest, UnchangedTest], tmpdir: py.path.local
111 | ) -> None:
112 | single_code_file_path = prepare_file(test_config, Path(tmpdir))
113 | runner.invoke(app, [str(single_code_file_path)])
114 | assert_code_processed_correctly(test_config, single_code_file_path)
115 |
116 |
117 | @pytest.mark.parametrize(
118 | "test_config",
119 | SINGLE_FILE_TESTS,
120 | ids=[test.name for test in SINGLE_FILE_TESTS],
121 | )
122 | def test_cli_no_file_should_use_current_dir(
123 | test_config: Union[BeforeAndAfterTest, UnchangedTest], tmpdir: py.path.local
124 | ) -> None:
125 | tmpdir.chdir()
126 | single_code_file_path = prepare_file(test_config, Path(tmpdir))
127 | runner.invoke(app)
128 | assert_code_processed_correctly(test_config, single_code_file_path)
129 |
130 |
131 | def test_cli_multi_file(tmpdir: py.path.local) -> None:
132 | test_with_paths = [
133 | (test_config, prepare_file(test_config, Path(tmpdir)))
134 | for test_config in SINGLE_FILE_TESTS
135 | ]
136 |
137 | runner.invoke(app, [str(path) for _, path in test_with_paths])
138 |
139 | for test_config, path in test_with_paths:
140 | assert_code_processed_correctly(test_config, path)
141 |
--------------------------------------------------------------------------------
/test/simple-tests.yaml:
--------------------------------------------------------------------------------
1 | tests:
2 | - name: test_simple_change
3 | before: |
4 | def bla(foo: str = None):
5 | ...
6 | after: |
7 | from typing import Optional
8 | def bla(foo: Optional[str] = None):
9 | ...
10 |
11 | - name: test_simple_change_already_imported
12 | before: |
13 | from typing import Optional
14 | def bla(foo:
15 | str = None):
16 | ...
17 | after: |
18 | from typing import Optional
19 | def bla(foo: Optional[str] = None):
20 | ...
21 |
22 | - name: test_simple_change_star_import
23 | before: |
24 | from typing import *
25 | def bla(foo:
26 | str = None):
27 | ...
28 | after: |
29 | from typing import *
30 | def bla(foo: Optional[str] = None):
31 | ...
32 |
33 | - name: test_simple_change_already_imported_optional_as
34 | before: |
35 | from typing import Optional as O
36 | def bla(foo: str = None):
37 | ...
38 | after: |
39 | from typing import Optional as O
40 | def bla(foo: O[str] = None):
41 | ...
42 |
43 | - name: test_nested_change
44 | before: |
45 | def bla(foo: Tuple[str] = None):
46 | ...
47 | after: |
48 | from typing import Optional
49 | def bla(foo: Optional[Tuple[str]] = None):
50 | ...
51 |
52 | - name: test_not_optional
53 | unchanged: |
54 | def bla(foo:
55 | str = 'a'):
56 | ...
57 |
58 | - name: test_already_optional
59 | unchanged: |
60 | from typing import Optional
61 | def bla(foo:
62 | Optional[str] = None):
63 | ...
64 |
65 | - name: test_legal_no_type
66 | unchanged: |
67 | class Bloep:
68 | def bla(self):
69 | ...
70 |
71 | - name: test_nochange_typing_import
72 | unchanged: |
73 | from typing import Optional
74 | def bla(foo:
75 | Optional[str] = None):
76 | ...
77 |
78 | - name: test_nochange_renamed_typing
79 | unchanged: |
80 | import typing
81 | import typing as t
82 | def bla(foo: t.Optional[str] = None):
83 | ...
84 |
85 | - name: test_prioritise_from_import
86 | before: |
87 | import typing
88 | from typing import Optional
89 | def bla(foo: str = None):
90 | ...
91 | after: |
92 | import typing
93 | from typing import Optional
94 | def bla(foo: Optional[str] = None):
95 | ...
96 |
97 | - name: test_with_module_docstring
98 | before: |
99 | """Something"""
100 | def f(s: str = None):
101 | ...
102 | after: |
103 | """Something"""
104 | from typing import Optional
105 | def f(s: Optional[str] = None):
106 | ...
107 |
108 | - name: test_with_future_import
109 | before: |
110 | from __future__ import annotations
111 | def f(s: str = None):
112 | ...
113 | after: |
114 | from __future__ import annotations
115 | from typing import Optional
116 | def f(s: Optional[str] = None):
117 | ...
118 |
119 | - name: test_docstring_with_future_import
120 | before: |
121 | """Something"""
122 | from __future__ import annotations
123 | def f(s: str = None):
124 | ...
125 | after: |
126 | """Something"""
127 | from __future__ import annotations
128 | from typing import Optional
129 | def f(s: Optional[str] = None):
130 | ...
131 |
132 | - name: test_nochange_typing_as_import
133 | unchanged: |
134 | import typing as t
135 | def bla(foo: t.Optional[str] = None):
136 | ...
137 |
138 | - name: test_accept_union_none_from_import
139 | unchanged: |
140 | import typing as t
141 | def bla(foo: t.Union[str, None] = None):
142 | ...
143 |
144 | - name: test_accept_union_none
145 | unchanged: |
146 | from typing import Union
147 | def bla(foo: Union[str, None] = None):
148 | ...
149 |
150 | - name: test_py10_syntax
151 | unchanged: |
152 | def bla(foo: str | None = None):
153 | ...
154 |
155 | - name: test_py10_syntax_extra_left
156 | unchanged: |
157 | def bla(foo: str | None | int = None):
158 | ...
159 |
160 | - name: test_py10_syntax_extra_right
161 | unchanged: |
162 | def bla(foo: str | int | None = None):
163 | ...
164 |
--------------------------------------------------------------------------------
/docs/assets/images/logo-with-text.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/auto_optional/code_processing.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | import libcst as cst
4 | import libcst.matchers as m
5 |
6 | from auto_optional.cst_helper import unwrap_commutative_binary_operator
7 | from auto_optional.data_structures import BestImportStatementFirstList
8 |
9 |
10 | class ImportStatementChecker:
11 | import_names: BestImportStatementFirstList
12 | imported_module: str
13 | imported_value: str
14 |
15 | def __init__(self, imported_module: str, imported_object: str) -> None:
16 | super().__init__()
17 | # Will be a list of all existing import statements
18 | # that references the desired type
19 | self.import_names = BestImportStatementFirstList()
20 | self.imported_module = imported_module
21 | self.imported_value = imported_object
22 |
23 | def get_import_name(self) -> Union[cst.Name, cst.Attribute]:
24 | return self.import_names[0]
25 |
26 | def check_import_from(self, node: cst.ImportFrom) -> None:
27 | assert node.module
28 | if node.module.value == self.imported_module:
29 | if isinstance(node.names, cst.ImportStar):
30 | # When ``from module import *`` is found the
31 | self.import_names.append(cst.Name(self.imported_value))
32 | else:
33 | for import_alias in node.names:
34 | if import_alias.name.value == self.imported_value:
35 | self.import_names.append(
36 | cst.ensure_type(import_alias.asname.name, cst.Name)
37 | if import_alias.asname
38 | else import_alias.name
39 | )
40 |
41 | def check_import(self, node: cst.Import) -> None:
42 | for import_alias in node.names:
43 | if import_alias.name.value == self.imported_module:
44 | typing_name = (
45 | cst.ensure_type(import_alias.asname.name, cst.Name)
46 | if import_alias.asname
47 | # ensure_type to satisfy mypy
48 | # it is a Name since its value equals the module (see if statement)
49 | else cst.ensure_type(import_alias.name, cst.Name)
50 | )
51 |
52 | self.import_names.append(
53 | cst.Attribute(
54 | value=cst.Name(typing_name.value),
55 | attr=cst.Name(self.imported_value),
56 | )
57 | )
58 |
59 |
60 | class AutoOptionalTransformer(cst.CSTTransformer):
61 | METADATA_DEPENDENCIES = (cst.metadata.QualifiedNameProvider,)
62 |
63 | def __init__(self) -> None:
64 | super().__init__()
65 | self.optional_import_checker = ImportStatementChecker("typing", "Optional")
66 | self.union_import_checker = ImportStatementChecker("typing", "Union")
67 |
68 | # Will be set to true if there if we find an non-optional param with None
69 | # as default i.e. ``def foo(bar: str = None)``.
70 | self.optional_import_needed = False
71 |
72 | def visit_ImportFrom_names(self, node: cst.ImportFrom) -> None:
73 | """Searches for imports of ``typing.Optional`` and stores for later use"""
74 | self.optional_import_checker.check_import_from(node)
75 | self.union_import_checker.check_import_from(node)
76 |
77 | def visit_Import_names(self, node: cst.Import) -> None:
78 | """Searches for imports of ``typing`` and stores for later use"""
79 | self.optional_import_checker.check_import(node)
80 | self.union_import_checker.check_import(node)
81 |
82 | def visit_Param(self, node: cst.Param) -> None:
83 | """
84 | Used to detect if there are any statements that need to be changed to Optional
85 | """
86 | if (
87 | node.default
88 | and m.matches(node.default, m.Name("None"))
89 | and not self.optional_import_checker.import_names
90 | ):
91 | # TODO add check for the ``Optional[None]`` alternative
92 | self.optional_import_needed = True
93 |
94 | def leave_Module(
95 | self, original_node: cst.Module, updated_node: cst.Module
96 | ) -> cst.Module:
97 | """
98 | The last call that is handled in the process of parsing and converting the code.
99 |
100 | Is only used to add the ``typing.Optional`` import statement when missing.
101 | """
102 | if (
103 | not self.optional_import_checker.import_names
104 | or not self.optional_import_needed
105 | ):
106 | return updated_node
107 |
108 | import_statement = self.__build_import_statement()
109 | import_statement_location = self.__find_line_for_optional_import_insertion(
110 | updated_node
111 | )
112 | return updated_node.with_changes(
113 | body=[
114 | *updated_node.body[:import_statement_location],
115 | import_statement,
116 | *updated_node.body[import_statement_location:],
117 | ]
118 | )
119 |
120 | def __build_import_statement(self) -> cst.SimpleStatementLine:
121 | return cst.SimpleStatementLine(
122 | body=[
123 | cst.ImportFrom(
124 | module=cst.Name(
125 | value="typing",
126 | ),
127 | names=[
128 | cst.ImportAlias(
129 | name=cst.Name(
130 | value="Optional",
131 | ),
132 | ),
133 | ],
134 | )
135 | ]
136 | )
137 |
138 | def __find_line_for_optional_import_insertion(
139 | self, updated_node: cst.Module
140 | ) -> int:
141 | insert_at = 0
142 | for index, body_part in enumerate(updated_node.body):
143 | if (
144 | isinstance(body_part, cst.SimpleStatementLine)
145 | and len(body_part.children) > 0
146 | and (
147 | ( # module level docstring
148 | index == 0
149 | and m.matches(body_part.children[0], m.Expr(m.SimpleString()))
150 | )
151 | or m.matches( # future import
152 | body_part.children[0],
153 | m.ImportFrom(module=m.Name("__future__")),
154 | )
155 | )
156 | ):
157 | # module docstring
158 | insert_at += 1
159 | elif index > 1:
160 | break
161 | return insert_at
162 |
163 | def __check_if__union_none(self, annotation: cst.BaseExpression) -> bool:
164 | # Return if it is a Union[..., None, ...] statement
165 | return bool(
166 | # Check if Union can even be imported
167 | self.union_import_checker.import_names
168 | # Check if it is a Union statement at all
169 | and (
170 | isinstance(annotation, cst.Subscript)
171 | and m.matches(
172 | annotation.value,
173 | self.union_import_checker.get_import_name(), # type: ignore
174 | )
175 | )
176 | # Check if any of the slice items is None
177 | and any(
178 | (
179 | isinstance(item.slice, cst.Index)
180 | and isinstance(item.slice.value, cst.Name)
181 | and item.slice.value.value == "None"
182 | )
183 | for item in annotation.slice
184 | )
185 | )
186 |
187 | def __check_if__or_none(self, annotation: cst.BaseExpression) -> bool:
188 | return (
189 | isinstance(annotation, cst.BinaryOperation)
190 | and isinstance(annotation.operator, cst.BitOr)
191 | and any(
192 | m.matches(option, m.Name(value="None"))
193 | for option in unwrap_commutative_binary_operator(annotation)
194 | )
195 | )
196 |
197 | def leave_Param(
198 | self, original_node: cst.Param, updated_node: cst.Param
199 | ) -> cst.Param:
200 | """
201 | Changes Parameters of type ``x`` to ``Optional[x]`` if their default is None.
202 | """
203 | if ( # Check if optional is required
204 | updated_node.annotation
205 | and updated_node.default
206 | and m.matches(updated_node.default, m.Name("None"))
207 | ):
208 | annotation = updated_node.annotation.annotation
209 |
210 | # TODO if ``Union[None]`` return None
211 |
212 | # Also allow Union
213 | if self.__check_if__union_none(annotation) or self.__check_if__or_none(
214 | annotation
215 | ):
216 | return updated_node
217 |
218 | if not self.optional_import_checker.import_names:
219 | self.optional_import_checker.import_names.append(cst.Name("Optional"))
220 |
221 | if not (
222 | isinstance(annotation, cst.Subscript)
223 | and any(
224 | m.matches(annotation.value, optional_import) # type: ignore
225 | for optional_import in self.optional_import_checker.import_names
226 | )
227 | ):
228 | return updated_node.with_changes(
229 | annotation=cst.Annotation(
230 | cst.Subscript(
231 | value=(self.optional_import_checker.get_import_name()),
232 | slice=[cst.SubscriptElement(cst.Index(annotation))],
233 | )
234 | )
235 | )
236 | return updated_node
237 |
--------------------------------------------------------------------------------
/poetry.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "atomicwrites"
3 | version = "1.4.0"
4 | description = "Atomic file writes."
5 | category = "dev"
6 | optional = false
7 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
8 |
9 | [[package]]
10 | name = "attrs"
11 | version = "21.2.0"
12 | description = "Classes Without Boilerplate"
13 | category = "dev"
14 | optional = false
15 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
16 |
17 | [package.extras]
18 | dev = ["coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"]
19 | docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
20 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"]
21 | tests-no-zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"]
22 |
23 | [[package]]
24 | name = "black"
25 | version = "21.8b0"
26 | description = "The uncompromising code formatter."
27 | category = "dev"
28 | optional = false
29 | python-versions = ">=3.6.2"
30 |
31 | [package.dependencies]
32 | click = ">=7.1.2"
33 | mypy-extensions = ">=0.4.3"
34 | pathspec = ">=0.9.0,<1"
35 | platformdirs = ">=2"
36 | regex = ">=2020.1.8"
37 | tomli = ">=0.2.6,<2.0.0"
38 | typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""}
39 | typing-extensions = [
40 | {version = ">=3.10.0.0", markers = "python_version < \"3.10\""},
41 | {version = ">=3.10.0.0,<3.10.0.1 || >3.10.0.1", markers = "python_version >= \"3.10\""},
42 | ]
43 |
44 | [package.extras]
45 | colorama = ["colorama (>=0.4.3)"]
46 | d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"]
47 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
48 | python2 = ["typed-ast (>=1.4.2)"]
49 | uvloop = ["uvloop (>=0.15.2)"]
50 |
51 | [[package]]
52 | name = "certifi"
53 | version = "2022.12.7"
54 | description = "Python package for providing Mozilla's CA Bundle."
55 | category = "dev"
56 | optional = false
57 | python-versions = ">=3.6"
58 |
59 | [[package]]
60 | name = "charset-normalizer"
61 | version = "2.0.4"
62 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
63 | category = "dev"
64 | optional = false
65 | python-versions = ">=3.5.0"
66 |
67 | [package.extras]
68 | unicode-backport = ["unicodedata2"]
69 |
70 | [[package]]
71 | name = "click"
72 | version = "8.0.1"
73 | description = "Composable command line interface toolkit"
74 | category = "main"
75 | optional = false
76 | python-versions = ">=3.6"
77 |
78 | [package.dependencies]
79 | colorama = {version = "*", markers = "platform_system == \"Windows\""}
80 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
81 |
82 | [[package]]
83 | name = "codecov"
84 | version = "2.1.12"
85 | description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab"
86 | category = "dev"
87 | optional = false
88 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
89 |
90 | [package.dependencies]
91 | coverage = "*"
92 | requests = ">=2.7.9"
93 |
94 | [[package]]
95 | name = "colorama"
96 | version = "0.4.4"
97 | description = "Cross-platform colored terminal text."
98 | category = "main"
99 | optional = false
100 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
101 |
102 | [[package]]
103 | name = "coverage"
104 | version = "5.5"
105 | description = "Code coverage measurement for Python"
106 | category = "dev"
107 | optional = false
108 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
109 |
110 | [package.extras]
111 | toml = ["toml"]
112 |
113 | [[package]]
114 | name = "flake8"
115 | version = "3.9.2"
116 | description = "the modular source code checker: pep8 pyflakes and co"
117 | category = "dev"
118 | optional = false
119 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
120 |
121 | [package.dependencies]
122 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
123 | mccabe = ">=0.6.0,<0.7.0"
124 | pycodestyle = ">=2.7.0,<2.8.0"
125 | pyflakes = ">=2.3.0,<2.4.0"
126 |
127 | [[package]]
128 | name = "flake8-annotations"
129 | version = "2.6.2"
130 | description = "Flake8 Type Annotation Checks"
131 | category = "dev"
132 | optional = false
133 | python-versions = ">=3.6.1,<4.0.0"
134 |
135 | [package.dependencies]
136 | flake8 = ">=3.7,<4.0"
137 | typed-ast = {version = ">=1.4,<2.0", markers = "python_version < \"3.8\""}
138 |
139 | [[package]]
140 | name = "flake8-black"
141 | version = "0.2.3"
142 | description = "flake8 plugin to call black as a code style validator"
143 | category = "dev"
144 | optional = false
145 | python-versions = "*"
146 |
147 | [package.dependencies]
148 | black = "*"
149 | flake8 = ">=3.0.0"
150 | toml = "*"
151 |
152 | [[package]]
153 | name = "flake8-isort"
154 | version = "4.0.0"
155 | description = "flake8 plugin that integrates isort ."
156 | category = "dev"
157 | optional = false
158 | python-versions = "*"
159 |
160 | [package.dependencies]
161 | flake8 = ">=3.2.1,<4"
162 | isort = ">=4.3.5,<6"
163 | testfixtures = ">=6.8.0,<7"
164 |
165 | [package.extras]
166 | test = ["pytest (>=4.0.2,<6)", "toml"]
167 |
168 | [[package]]
169 | name = "ghp-import"
170 | version = "2.0.1"
171 | description = "Copy your docs directly to the gh-pages branch."
172 | category = "dev"
173 | optional = false
174 | python-versions = "*"
175 |
176 | [package.dependencies]
177 | python-dateutil = ">=2.8.1"
178 |
179 | [package.extras]
180 | dev = ["flake8", "markdown", "twine", "wheel"]
181 |
182 | [[package]]
183 | name = "idna"
184 | version = "3.2"
185 | description = "Internationalized Domain Names in Applications (IDNA)"
186 | category = "dev"
187 | optional = false
188 | python-versions = ">=3.5"
189 |
190 | [[package]]
191 | name = "importlib-metadata"
192 | version = "4.8.1"
193 | description = "Read metadata from Python packages"
194 | category = "main"
195 | optional = false
196 | python-versions = ">=3.6"
197 |
198 | [package.dependencies]
199 | typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
200 | zipp = ">=0.5"
201 |
202 | [package.extras]
203 | docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"]
204 | perf = ["ipython"]
205 | testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-perf (>=0.9.2)"]
206 |
207 | [[package]]
208 | name = "iniconfig"
209 | version = "1.1.1"
210 | description = "iniconfig: brain-dead simple config-ini parsing"
211 | category = "dev"
212 | optional = false
213 | python-versions = "*"
214 |
215 | [[package]]
216 | name = "invoke"
217 | version = "1.6.0"
218 | description = "Pythonic task execution"
219 | category = "dev"
220 | optional = false
221 | python-versions = "*"
222 |
223 | [[package]]
224 | name = "isort"
225 | version = "5.9.3"
226 | description = "A Python utility / library to sort Python imports."
227 | category = "dev"
228 | optional = false
229 | python-versions = ">=3.6.1,<4.0"
230 |
231 | [package.extras]
232 | colors = ["colorama (>=0.4.3,<0.5.0)"]
233 | pipfile-deprecated-finder = ["pipreqs", "requirementslib"]
234 | plugins = ["setuptools"]
235 | requirements-deprecated-finder = ["pip-api", "pipreqs"]
236 |
237 | [[package]]
238 | name = "jinja2"
239 | version = "3.0.1"
240 | description = "A very fast and expressive template engine."
241 | category = "dev"
242 | optional = false
243 | python-versions = ">=3.6"
244 |
245 | [package.dependencies]
246 | MarkupSafe = ">=2.0"
247 |
248 | [package.extras]
249 | i18n = ["Babel (>=2.7)"]
250 |
251 | [[package]]
252 | name = "libcst"
253 | version = "0.3.23"
254 | description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7 and 3.8 programs."
255 | category = "main"
256 | optional = false
257 | python-versions = ">=3.6"
258 |
259 | [package.dependencies]
260 | pyyaml = ">=5.2"
261 | typing-extensions = ">=3.7.4.2"
262 | typing-inspect = ">=0.4.0"
263 |
264 | [package.extras]
265 | dev = ["black (==21.10b0)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jupyter (>=1.0.0)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.3)", "setuptools-scm (>=6.0.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.18.1)", "ufmt (==1.2)", "usort (==0.6.3)"]
266 |
267 | [[package]]
268 | name = "markdown"
269 | version = "3.3.4"
270 | description = "Python implementation of Markdown."
271 | category = "dev"
272 | optional = false
273 | python-versions = ">=3.6"
274 |
275 | [package.dependencies]
276 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
277 |
278 | [package.extras]
279 | testing = ["coverage", "pyyaml"]
280 |
281 | [[package]]
282 | name = "markupsafe"
283 | version = "2.0.1"
284 | description = "Safely add untrusted strings to HTML/XML markup."
285 | category = "dev"
286 | optional = false
287 | python-versions = ">=3.6"
288 |
289 | [[package]]
290 | name = "mccabe"
291 | version = "0.6.1"
292 | description = "McCabe checker, plugin for flake8"
293 | category = "dev"
294 | optional = false
295 | python-versions = "*"
296 |
297 | [[package]]
298 | name = "mergedeep"
299 | version = "1.3.4"
300 | description = "A deep merge function for 🐍."
301 | category = "dev"
302 | optional = false
303 | python-versions = ">=3.6"
304 |
305 | [[package]]
306 | name = "mkdocs"
307 | version = "1.2.3"
308 | description = "Project documentation with Markdown."
309 | category = "dev"
310 | optional = false
311 | python-versions = ">=3.6"
312 |
313 | [package.dependencies]
314 | click = ">=3.3"
315 | ghp-import = ">=1.0"
316 | importlib-metadata = ">=3.10"
317 | Jinja2 = ">=2.10.1"
318 | Markdown = ">=3.2.1"
319 | mergedeep = ">=1.3.4"
320 | packaging = ">=20.5"
321 | PyYAML = ">=3.10"
322 | pyyaml-env-tag = ">=0.1"
323 | watchdog = ">=2.0"
324 |
325 | [package.extras]
326 | i18n = ["babel (>=2.9.0)"]
327 |
328 | [[package]]
329 | name = "mkdocs-material"
330 | version = "7.2.6"
331 | description = "A Material Design theme for MkDocs"
332 | category = "dev"
333 | optional = false
334 | python-versions = "*"
335 |
336 | [package.dependencies]
337 | markdown = ">=3.2"
338 | mkdocs = ">=1.2.2"
339 | mkdocs-material-extensions = ">=1.0"
340 | Pygments = ">=2.4"
341 | pymdown-extensions = ">=7.0"
342 |
343 | [[package]]
344 | name = "mkdocs-material-extensions"
345 | version = "1.0.3"
346 | description = "Extension pack for Python Markdown."
347 | category = "dev"
348 | optional = false
349 | python-versions = ">=3.6"
350 |
351 | [[package]]
352 | name = "mypy"
353 | version = "0.910"
354 | description = "Optional static typing for Python"
355 | category = "dev"
356 | optional = false
357 | python-versions = ">=3.5"
358 |
359 | [package.dependencies]
360 | mypy-extensions = ">=0.4.3,<0.5.0"
361 | toml = "*"
362 | typed-ast = {version = ">=1.4.0,<1.5.0", markers = "python_version < \"3.8\""}
363 | typing-extensions = ">=3.7.4"
364 |
365 | [package.extras]
366 | dmypy = ["psutil (>=4.0)"]
367 | python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
368 |
369 | [[package]]
370 | name = "mypy-extensions"
371 | version = "0.4.3"
372 | description = "Experimental type system extensions for programs checked with the mypy typechecker."
373 | category = "main"
374 | optional = false
375 | python-versions = "*"
376 |
377 | [[package]]
378 | name = "packaging"
379 | version = "21.0"
380 | description = "Core utilities for Python packages"
381 | category = "dev"
382 | optional = false
383 | python-versions = ">=3.6"
384 |
385 | [package.dependencies]
386 | pyparsing = ">=2.0.2"
387 |
388 | [[package]]
389 | name = "pathspec"
390 | version = "0.9.0"
391 | description = "Utility library for gitignore style pattern matching of file paths."
392 | category = "dev"
393 | optional = false
394 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
395 |
396 | [[package]]
397 | name = "platformdirs"
398 | version = "2.3.0"
399 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
400 | category = "dev"
401 | optional = false
402 | python-versions = ">=3.6"
403 |
404 | [package.extras]
405 | docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
406 | test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
407 |
408 | [[package]]
409 | name = "pluggy"
410 | version = "0.13.1"
411 | description = "plugin and hook calling mechanisms for python"
412 | category = "dev"
413 | optional = false
414 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
415 |
416 | [package.dependencies]
417 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
418 |
419 | [package.extras]
420 | dev = ["pre-commit", "tox"]
421 |
422 | [[package]]
423 | name = "py"
424 | version = "1.10.0"
425 | description = "library with cross-python path, ini-parsing, io, code, log facilities"
426 | category = "dev"
427 | optional = false
428 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
429 |
430 | [[package]]
431 | name = "pycodestyle"
432 | version = "2.7.0"
433 | description = "Python style guide checker"
434 | category = "dev"
435 | optional = false
436 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
437 |
438 | [[package]]
439 | name = "pydantic"
440 | version = "1.8.2"
441 | description = "Data validation and settings management using python 3.6 type hinting"
442 | category = "dev"
443 | optional = false
444 | python-versions = ">=3.6.1"
445 |
446 | [package.dependencies]
447 | typing-extensions = ">=3.7.4.3"
448 |
449 | [package.extras]
450 | dotenv = ["python-dotenv (>=0.10.4)"]
451 | email = ["email-validator (>=1.0.3)"]
452 |
453 | [[package]]
454 | name = "pyflakes"
455 | version = "2.3.1"
456 | description = "passive checker of Python programs"
457 | category = "dev"
458 | optional = false
459 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
460 |
461 | [[package]]
462 | name = "pygments"
463 | version = "2.10.0"
464 | description = "Pygments is a syntax highlighting package written in Python."
465 | category = "dev"
466 | optional = false
467 | python-versions = ">=3.5"
468 |
469 | [[package]]
470 | name = "pymdown-extensions"
471 | version = "8.2"
472 | description = "Extension pack for Python Markdown."
473 | category = "dev"
474 | optional = false
475 | python-versions = ">=3.6"
476 |
477 | [package.dependencies]
478 | Markdown = ">=3.2"
479 |
480 | [[package]]
481 | name = "pyparsing"
482 | version = "2.4.7"
483 | description = "Python parsing module"
484 | category = "dev"
485 | optional = false
486 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
487 |
488 | [[package]]
489 | name = "pytest"
490 | version = "6.2.4"
491 | description = "pytest: simple powerful testing with Python"
492 | category = "dev"
493 | optional = false
494 | python-versions = ">=3.6"
495 |
496 | [package.dependencies]
497 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
498 | attrs = ">=19.2.0"
499 | colorama = {version = "*", markers = "sys_platform == \"win32\""}
500 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
501 | iniconfig = "*"
502 | packaging = "*"
503 | pluggy = ">=0.12,<1.0.0a1"
504 | py = ">=1.8.2"
505 | toml = "*"
506 |
507 | [package.extras]
508 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
509 |
510 | [[package]]
511 | name = "pytest-cov"
512 | version = "2.12.1"
513 | description = "Pytest plugin for measuring coverage."
514 | category = "dev"
515 | optional = false
516 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
517 |
518 | [package.dependencies]
519 | coverage = ">=5.2.1"
520 | pytest = ">=4.6"
521 | toml = "*"
522 |
523 | [package.extras]
524 | testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
525 |
526 | [[package]]
527 | name = "python-dateutil"
528 | version = "2.8.2"
529 | description = "Extensions to the standard Python datetime module"
530 | category = "dev"
531 | optional = false
532 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
533 |
534 | [package.dependencies]
535 | six = ">=1.5"
536 |
537 | [[package]]
538 | name = "pyyaml"
539 | version = "5.4.1"
540 | description = "YAML parser and emitter for Python"
541 | category = "main"
542 | optional = false
543 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
544 |
545 | [[package]]
546 | name = "pyyaml-env-tag"
547 | version = "0.1"
548 | description = "A custom YAML tag for referencing environment variables in YAML files. "
549 | category = "dev"
550 | optional = false
551 | python-versions = ">=3.6"
552 |
553 | [package.dependencies]
554 | pyyaml = "*"
555 |
556 | [[package]]
557 | name = "regex"
558 | version = "2021.8.28"
559 | description = "Alternative regular expression module, to replace re."
560 | category = "dev"
561 | optional = false
562 | python-versions = "*"
563 |
564 | [[package]]
565 | name = "requests"
566 | version = "2.26.0"
567 | description = "Python HTTP for Humans."
568 | category = "dev"
569 | optional = false
570 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
571 |
572 | [package.dependencies]
573 | certifi = ">=2017.4.17"
574 | charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
575 | idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
576 | urllib3 = ">=1.21.1,<1.27"
577 |
578 | [package.extras]
579 | socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
580 | use-chardet-on-py3 = ["chardet (>=3.0.2,<5)"]
581 |
582 | [[package]]
583 | name = "six"
584 | version = "1.16.0"
585 | description = "Python 2 and 3 compatibility utilities"
586 | category = "dev"
587 | optional = false
588 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
589 |
590 | [[package]]
591 | name = "testfixtures"
592 | version = "6.18.1"
593 | description = "A collection of helpers and mock objects for unit tests and doc tests."
594 | category = "dev"
595 | optional = false
596 | python-versions = "*"
597 |
598 | [package.extras]
599 | build = ["setuptools-git", "twine", "wheel"]
600 | docs = ["django", "django (<2)", "mock", "sphinx", "sybil", "twisted", "zope.component"]
601 | test = ["django", "django (<2)", "mock", "pytest (>=3.6)", "pytest-cov", "pytest-django", "sybil", "twisted", "zope.component"]
602 |
603 | [[package]]
604 | name = "toml"
605 | version = "0.10.2"
606 | description = "Python Library for Tom's Obvious, Minimal Language"
607 | category = "dev"
608 | optional = false
609 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
610 |
611 | [[package]]
612 | name = "tomli"
613 | version = "1.2.1"
614 | description = "A lil' TOML parser"
615 | category = "dev"
616 | optional = false
617 | python-versions = ">=3.6"
618 |
619 | [[package]]
620 | name = "typed-ast"
621 | version = "1.4.3"
622 | description = "a fork of Python 2 and 3 ast modules with type comment support"
623 | category = "dev"
624 | optional = false
625 | python-versions = "*"
626 |
627 | [[package]]
628 | name = "typer"
629 | version = "0.4.0"
630 | description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
631 | category = "main"
632 | optional = false
633 | python-versions = ">=3.6"
634 |
635 | [package.dependencies]
636 | click = ">=7.1.1,<9.0.0"
637 |
638 | [package.extras]
639 | all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"]
640 | dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)"]
641 | doc = ["markdown-include (>=0.5.1,<0.6.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)"]
642 | test = ["black (>=19.10b0,<20.0b0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
643 |
644 | [[package]]
645 | name = "types-pyyaml"
646 | version = "5.4.10"
647 | description = "Typing stubs for PyYAML"
648 | category = "dev"
649 | optional = false
650 | python-versions = "*"
651 |
652 | [[package]]
653 | name = "typing-extensions"
654 | version = "3.10.0.2"
655 | description = "Backported and Experimental Type Hints for Python 3.5+"
656 | category = "main"
657 | optional = false
658 | python-versions = "*"
659 |
660 | [[package]]
661 | name = "typing-inspect"
662 | version = "0.7.1"
663 | description = "Runtime inspection utilities for typing module."
664 | category = "main"
665 | optional = false
666 | python-versions = "*"
667 |
668 | [package.dependencies]
669 | mypy-extensions = ">=0.3.0"
670 | typing-extensions = ">=3.7.4"
671 |
672 | [[package]]
673 | name = "urllib3"
674 | version = "1.26.6"
675 | description = "HTTP library with thread-safe connection pooling, file post, and more."
676 | category = "dev"
677 | optional = false
678 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
679 |
680 | [package.extras]
681 | brotli = ["brotlipy (>=0.6.0)"]
682 | secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)"]
683 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
684 |
685 | [[package]]
686 | name = "watchdog"
687 | version = "2.1.5"
688 | description = "Filesystem events monitoring"
689 | category = "dev"
690 | optional = false
691 | python-versions = ">=3.6"
692 |
693 | [package.extras]
694 | watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"]
695 |
696 | [[package]]
697 | name = "zipp"
698 | version = "3.5.0"
699 | description = "Backport of pathlib-compatible object wrapper for zip files"
700 | category = "main"
701 | optional = false
702 | python-versions = ">=3.6"
703 |
704 | [package.extras]
705 | docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"]
706 | testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"]
707 |
708 | [metadata]
709 | lock-version = "1.1"
710 | python-versions = ">3.7, <4.0"
711 | content-hash = "3948069d851bb18d620b6a3e7aa98fe5bf7891ab77376034684aa834546fc8f1"
712 |
713 | [metadata.files]
714 | atomicwrites = [
715 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
716 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
717 | ]
718 | attrs = [
719 | {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
720 | {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
721 | ]
722 | black = [
723 | {file = "black-21.8b0-py3-none-any.whl", hash = "sha256:2a0f9a8c2b2a60dbcf1ccb058842fb22bdbbcb2f32c6cc02d9578f90b92ce8b7"},
724 | {file = "black-21.8b0.tar.gz", hash = "sha256:570608d28aa3af1792b98c4a337dbac6367877b47b12b88ab42095cfc1a627c2"},
725 | ]
726 | certifi = [
727 | {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
728 | {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
729 | ]
730 | charset-normalizer = [
731 | {file = "charset-normalizer-2.0.4.tar.gz", hash = "sha256:f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"},
732 | {file = "charset_normalizer-2.0.4-py3-none-any.whl", hash = "sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b"},
733 | ]
734 | click = [
735 | {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"},
736 | {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"},
737 | ]
738 | codecov = [
739 | {file = "codecov-2.1.12-py2.py3-none-any.whl", hash = "sha256:585dc217dc3d8185198ceb402f85d5cb5dbfa0c5f350a5abcdf9e347776a5b47"},
740 | {file = "codecov-2.1.12.tar.gz", hash = "sha256:a0da46bb5025426da895af90938def8ee12d37fcbcbbbc15b6dc64cf7ebc51c1"},
741 | ]
742 | colorama = [
743 | {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
744 | {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
745 | ]
746 | coverage = [
747 | {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"},
748 | {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"},
749 | {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"},
750 | {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"},
751 | {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"},
752 | {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"},
753 | {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"},
754 | {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"},
755 | {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"},
756 | {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"},
757 | {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"},
758 | {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"},
759 | {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"},
760 | {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"},
761 | {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"},
762 | {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"},
763 | {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"},
764 | {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"},
765 | {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"},
766 | {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"},
767 | {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"},
768 | {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"},
769 | {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"},
770 | {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"},
771 | {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"},
772 | {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"},
773 | {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"},
774 | {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"},
775 | {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"},
776 | {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"},
777 | {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"},
778 | {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"},
779 | {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"},
780 | {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"},
781 | {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"},
782 | {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"},
783 | {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"},
784 | {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"},
785 | {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"},
786 | {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"},
787 | {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"},
788 | {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"},
789 | {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"},
790 | {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"},
791 | {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"},
792 | {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"},
793 | {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"},
794 | {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"},
795 | {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"},
796 | {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"},
797 | {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
798 | {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
799 | ]
800 | flake8 = [
801 | {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
802 | {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
803 | ]
804 | flake8-annotations = [
805 | {file = "flake8-annotations-2.6.2.tar.gz", hash = "sha256:0d6cd2e770b5095f09689c9d84cc054c51b929c41a68969ea1beb4b825cac515"},
806 | {file = "flake8_annotations-2.6.2-py3-none-any.whl", hash = "sha256:d10c4638231f8a50c0a597c4efce42bd7b7d85df4f620a0ddaca526138936a4f"},
807 | ]
808 | flake8-black = [
809 | {file = "flake8-black-0.2.3.tar.gz", hash = "sha256:c199844bc1b559d91195ebe8620216f21ed67f2cc1ff6884294c91a0d2492684"},
810 | {file = "flake8_black-0.2.3-py3-none-any.whl", hash = "sha256:cc080ba5b3773b69ba102b6617a00cc4ecbad8914109690cfda4d565ea435d96"},
811 | ]
812 | flake8-isort = [
813 | {file = "flake8-isort-4.0.0.tar.gz", hash = "sha256:2b91300f4f1926b396c2c90185844eb1a3d5ec39ea6138832d119da0a208f4d9"},
814 | {file = "flake8_isort-4.0.0-py2.py3-none-any.whl", hash = "sha256:729cd6ef9ba3659512dee337687c05d79c78e1215fdf921ed67e5fe46cce2f3c"},
815 | ]
816 | ghp-import = [
817 | {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"},
818 | {file = "ghp_import-2.0.1-py3-none-any.whl", hash = "sha256:8241a8e9f8dd3c1fafe9696e6e081b57a208ef907e9939c44e7415e407ab40ea"},
819 | ]
820 | idna = [
821 | {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
822 | {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
823 | ]
824 | importlib-metadata = [
825 | {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"},
826 | {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"},
827 | ]
828 | iniconfig = [
829 | {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
830 | {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
831 | ]
832 | invoke = [
833 | {file = "invoke-1.6.0-py2-none-any.whl", hash = "sha256:e6c9917a1e3e73e7ea91fdf82d5f151ccfe85bf30cc65cdb892444c02dbb5f74"},
834 | {file = "invoke-1.6.0-py3-none-any.whl", hash = "sha256:769e90caeb1bd07d484821732f931f1ad8916a38e3f3e618644687fc09cb6317"},
835 | {file = "invoke-1.6.0.tar.gz", hash = "sha256:374d1e2ecf78981da94bfaf95366216aaec27c2d6a7b7d5818d92da55aa258d3"},
836 | ]
837 | isort = [
838 | {file = "isort-5.9.3-py3-none-any.whl", hash = "sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"},
839 | {file = "isort-5.9.3.tar.gz", hash = "sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899"},
840 | ]
841 | jinja2 = [
842 | {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"},
843 | {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"},
844 | ]
845 | libcst = [
846 | {file = "libcst-0.3.23-py3-none-any.whl", hash = "sha256:2e1f77fbaaff93b889376c92f588b718edbdc21f956abbe27d10dfd1ff2d76c3"},
847 | {file = "libcst-0.3.23.tar.gz", hash = "sha256:330f9082a309bad808e283e80845a843200303bb256690185b98ca458a62c4f8"},
848 | ]
849 | markdown = [
850 | {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"},
851 | {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"},
852 | ]
853 | markupsafe = [
854 | {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"},
855 | {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"},
856 | {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"},
857 | {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"},
858 | {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"},
859 | {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"},
860 | {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"},
861 | {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"},
862 | {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"},
863 | {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"},
864 | {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"},
865 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"},
866 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"},
867 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"},
868 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"},
869 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"},
870 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"},
871 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"},
872 | {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"},
873 | {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"},
874 | {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"},
875 | {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"},
876 | {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"},
877 | {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"},
878 | {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"},
879 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"},
880 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"},
881 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"},
882 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"},
883 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"},
884 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"},
885 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"},
886 | {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"},
887 | {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"},
888 | {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"},
889 | {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"},
890 | {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"},
891 | {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"},
892 | {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"},
893 | {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"},
894 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"},
895 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"},
896 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"},
897 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"},
898 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"},
899 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"},
900 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"},
901 | {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"},
902 | {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"},
903 | {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"},
904 | {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"},
905 | {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"},
906 | {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"},
907 | {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"},
908 | {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"},
909 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"},
910 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"},
911 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"},
912 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"},
913 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"},
914 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"},
915 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"},
916 | {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"},
917 | {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"},
918 | {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"},
919 | {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"},
920 | {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"},
921 | {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
922 | {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
923 | ]
924 | mccabe = [
925 | {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
926 | {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
927 | ]
928 | mergedeep = [
929 | {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"},
930 | {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"},
931 | ]
932 | mkdocs = [
933 | {file = "mkdocs-1.2.3-py3-none-any.whl", hash = "sha256:a1fa8c2d0c1305d7fc2b9d9f607c71778572a8b110fb26642aa00296c9e6d072"},
934 | {file = "mkdocs-1.2.3.tar.gz", hash = "sha256:89f5a094764381cda656af4298727c9f53dc3e602983087e1fe96ea1df24f4c1"},
935 | ]
936 | mkdocs-material = [
937 | {file = "mkdocs-material-7.2.6.tar.gz", hash = "sha256:4bdeff63904680865676ceb3193216934de0b33fa5b2446e0a84ade60929ee54"},
938 | {file = "mkdocs_material-7.2.6-py2.py3-none-any.whl", hash = "sha256:4c6939b9d7d5c6db948ab02df8525c64211828ddf33286acea8b9d2115cec369"},
939 | ]
940 | mkdocs-material-extensions = [
941 | {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"},
942 | {file = "mkdocs_material_extensions-1.0.3-py3-none-any.whl", hash = "sha256:a82b70e533ce060b2a5d9eb2bc2e1be201cf61f901f93704b4acf6e3d5983a44"},
943 | ]
944 | mypy = [
945 | {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
946 | {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
947 | {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"},
948 | {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"},
949 | {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"},
950 | {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"},
951 | {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"},
952 | {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"},
953 | {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"},
954 | {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"},
955 | {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"},
956 | {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"},
957 | {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"},
958 | {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"},
959 | {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"},
960 | {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"},
961 | {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"},
962 | {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"},
963 | {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"},
964 | {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"},
965 | {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"},
966 | {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"},
967 | {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"},
968 | ]
969 | mypy-extensions = [
970 | {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
971 | {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
972 | ]
973 | packaging = [
974 | {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"},
975 | {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"},
976 | ]
977 | pathspec = [
978 | {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
979 | {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
980 | ]
981 | platformdirs = [
982 | {file = "platformdirs-2.3.0-py3-none-any.whl", hash = "sha256:8003ac87717ae2c7ee1ea5a84a1a61e87f3fbd16eb5aadba194ea30a9019f648"},
983 | {file = "platformdirs-2.3.0.tar.gz", hash = "sha256:15b056538719b1c94bdaccb29e5f81879c7f7f0f4a153f46086d155dffcd4f0f"},
984 | ]
985 | pluggy = [
986 | {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
987 | {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
988 | ]
989 | py = [
990 | {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"},
991 | {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"},
992 | ]
993 | pycodestyle = [
994 | {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
995 | {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
996 | ]
997 | pydantic = [
998 | {file = "pydantic-1.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739"},
999 | {file = "pydantic-1.8.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a7c6002203fe2c5a1b5cbb141bb85060cbff88c2d78eccbc72d97eb7022c43e4"},
1000 | {file = "pydantic-1.8.2-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:589eb6cd6361e8ac341db97602eb7f354551482368a37f4fd086c0733548308e"},
1001 | {file = "pydantic-1.8.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:10e5622224245941efc193ad1d159887872776df7a8fd592ed746aa25d071840"},
1002 | {file = "pydantic-1.8.2-cp36-cp36m-win_amd64.whl", hash = "sha256:99a9fc39470010c45c161a1dc584997f1feb13f689ecf645f59bb4ba623e586b"},
1003 | {file = "pydantic-1.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a83db7205f60c6a86f2c44a61791d993dff4b73135df1973ecd9eed5ea0bda20"},
1004 | {file = "pydantic-1.8.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:41b542c0b3c42dc17da70554bc6f38cbc30d7066d2c2815a94499b5684582ecb"},
1005 | {file = "pydantic-1.8.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:ea5cb40a3b23b3265f6325727ddfc45141b08ed665458be8c6285e7b85bd73a1"},
1006 | {file = "pydantic-1.8.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:18b5ea242dd3e62dbf89b2b0ec9ba6c7b5abaf6af85b95a97b00279f65845a23"},
1007 | {file = "pydantic-1.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:234a6c19f1c14e25e362cb05c68afb7f183eb931dd3cd4605eafff055ebbf287"},
1008 | {file = "pydantic-1.8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:021ea0e4133e8c824775a0cfe098677acf6fa5a3cbf9206a376eed3fc09302cd"},
1009 | {file = "pydantic-1.8.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e710876437bc07bd414ff453ac8ec63d219e7690128d925c6e82889d674bb505"},
1010 | {file = "pydantic-1.8.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:ac8eed4ca3bd3aadc58a13c2aa93cd8a884bcf21cb019f8cfecaae3b6ce3746e"},
1011 | {file = "pydantic-1.8.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:4a03cbbe743e9c7247ceae6f0d8898f7a64bb65800a45cbdc52d65e370570820"},
1012 | {file = "pydantic-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:8621559dcf5afacf0069ed194278f35c255dc1a1385c28b32dd6c110fd6531b3"},
1013 | {file = "pydantic-1.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8b223557f9510cf0bfd8b01316bf6dd281cf41826607eada99662f5e4963f316"},
1014 | {file = "pydantic-1.8.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:244ad78eeb388a43b0c927e74d3af78008e944074b7d0f4f696ddd5b2af43c62"},
1015 | {file = "pydantic-1.8.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:05ef5246a7ffd2ce12a619cbb29f3307b7c4509307b1b49f456657b43529dc6f"},
1016 | {file = "pydantic-1.8.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:54cd5121383f4a461ff7644c7ca20c0419d58052db70d8791eacbbe31528916b"},
1017 | {file = "pydantic-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:4be75bebf676a5f0f87937c6ddb061fa39cbea067240d98e298508c1bda6f3f3"},
1018 | {file = "pydantic-1.8.2-py3-none-any.whl", hash = "sha256:fec866a0b59f372b7e776f2d7308511784dace622e0992a0b59ea3ccee0ae833"},
1019 | {file = "pydantic-1.8.2.tar.gz", hash = "sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b"},
1020 | ]
1021 | pyflakes = [
1022 | {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
1023 | {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
1024 | ]
1025 | pygments = [
1026 | {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"},
1027 | {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"},
1028 | ]
1029 | pymdown-extensions = [
1030 | {file = "pymdown-extensions-8.2.tar.gz", hash = "sha256:b6daa94aad9e1310f9c64c8b1f01e4ce82937ab7eb53bfc92876a97aca02a6f4"},
1031 | {file = "pymdown_extensions-8.2-py3-none-any.whl", hash = "sha256:141452d8ed61165518f2c923454bf054866b85cf466feedb0eb68f04acdc2560"},
1032 | ]
1033 | pyparsing = [
1034 | {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
1035 | {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
1036 | ]
1037 | pytest = [
1038 | {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"},
1039 | {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"},
1040 | ]
1041 | pytest-cov = [
1042 | {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"},
1043 | {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"},
1044 | ]
1045 | python-dateutil = [
1046 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
1047 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
1048 | ]
1049 | pyyaml = [
1050 | {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
1051 | {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"},
1052 | {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"},
1053 | {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
1054 | {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
1055 | {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
1056 | {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"},
1057 | {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"},
1058 | {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
1059 | {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
1060 | {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
1061 | {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
1062 | {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"},
1063 | {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"},
1064 | {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
1065 | {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
1066 | {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
1067 | {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
1068 | {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"},
1069 | {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"},
1070 | {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
1071 | {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
1072 | {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
1073 | {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
1074 | {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"},
1075 | {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"},
1076 | {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
1077 | {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
1078 | {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
1079 | ]
1080 | pyyaml-env-tag = [
1081 | {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"},
1082 | {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
1083 | ]
1084 | regex = [
1085 | {file = "regex-2021.8.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2"},
1086 | {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a"},
1087 | {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f6a808044faae658f546dd5f525e921de9fa409de7a5570865467f03a626fc0"},
1088 | {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb"},
1089 | {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79aef6b5cd41feff359acaf98e040844613ff5298d0d19c455b3d9ae0bc8c35a"},
1090 | {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308"},
1091 | {file = "regex-2021.8.28-cp310-cp310-win32.whl", hash = "sha256:6eebf512aa90751d5ef6a7c2ac9d60113f32e86e5687326a50d7686e309f66ed"},
1092 | {file = "regex-2021.8.28-cp310-cp310-win_amd64.whl", hash = "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8"},
1093 | {file = "regex-2021.8.28-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c"},
1094 | {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c"},
1095 | {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328a1fad67445550b982caa2a2a850da5989fd6595e858f02d04636e7f8b0b13"},
1096 | {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0"},
1097 | {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66256b6391c057305e5ae9209941ef63c33a476b73772ca967d4a2df70520ec1"},
1098 | {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f"},
1099 | {file = "regex-2021.8.28-cp36-cp36m-win32.whl", hash = "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354"},
1100 | {file = "regex-2021.8.28-cp36-cp36m-win_amd64.whl", hash = "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645"},
1101 | {file = "regex-2021.8.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a"},
1102 | {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e"},
1103 | {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892"},
1104 | {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791"},
1105 | {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60667673ff9c249709160529ab39667d1ae9fd38634e006bec95611f632e759"},
1106 | {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906"},
1107 | {file = "regex-2021.8.28-cp37-cp37m-win32.whl", hash = "sha256:4cde065ab33bcaab774d84096fae266d9301d1a2f5519d7bd58fc55274afbf7a"},
1108 | {file = "regex-2021.8.28-cp37-cp37m-win_amd64.whl", hash = "sha256:1413b5022ed6ac0d504ba425ef02549a57d0f4276de58e3ab7e82437892704fc"},
1109 | {file = "regex-2021.8.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd"},
1110 | {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28fc475f560d8f67cc8767b94db4c9440210f6958495aeae70fac8faec631797"},
1111 | {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f"},
1112 | {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256"},
1113 | {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:808ee5834e06f57978da3e003ad9d6292de69d2bf6263662a1a8ae30788e080b"},
1114 | {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d5111d4c843d80202e62b4fdbb4920db1dcee4f9366d6b03294f45ed7b18b42e"},
1115 | {file = "regex-2021.8.28-cp38-cp38-win32.whl", hash = "sha256:473858730ef6d6ff7f7d5f19452184cd0caa062a20047f6d6f3e135a4648865d"},
1116 | {file = "regex-2021.8.28-cp38-cp38-win_amd64.whl", hash = "sha256:31a99a4796bf5aefc8351e98507b09e1b09115574f7c9dbb9cf2111f7220d2e2"},
1117 | {file = "regex-2021.8.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468"},
1118 | {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb"},
1119 | {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d"},
1120 | {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983"},
1121 | {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1743345e30917e8c574f273f51679c294effba6ad372db1967852f12c76759d8"},
1122 | {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed"},
1123 | {file = "regex-2021.8.28-cp39-cp39-win32.whl", hash = "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374"},
1124 | {file = "regex-2021.8.28-cp39-cp39-win_amd64.whl", hash = "sha256:610b690b406653c84b7cb6091facb3033500ee81089867ee7d59e675f9ca2b73"},
1125 | {file = "regex-2021.8.28.tar.gz", hash = "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1"},
1126 | ]
1127 | requests = [
1128 | {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"},
1129 | {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"},
1130 | ]
1131 | six = [
1132 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
1133 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
1134 | ]
1135 | testfixtures = [
1136 | {file = "testfixtures-6.18.1-py2.py3-none-any.whl", hash = "sha256:486be7b01eb71326029811878a3317b7e7994324621c0ec633c8e24499d8d5b3"},
1137 | {file = "testfixtures-6.18.1.tar.gz", hash = "sha256:0a6422737f6d89b45cdef1e2df5576f52ad0f507956002ce1020daa9f44211d6"},
1138 | ]
1139 | toml = [
1140 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
1141 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
1142 | ]
1143 | tomli = [
1144 | {file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"},
1145 | {file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"},
1146 | ]
1147 | typed-ast = [
1148 | {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
1149 | {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
1150 | {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"},
1151 | {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"},
1152 | {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"},
1153 | {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"},
1154 | {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"},
1155 | {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"},
1156 | {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"},
1157 | {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"},
1158 | {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"},
1159 | {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"},
1160 | {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"},
1161 | {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"},
1162 | {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"},
1163 | {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"},
1164 | {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"},
1165 | {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"},
1166 | {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"},
1167 | {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"},
1168 | {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"},
1169 | {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"},
1170 | {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"},
1171 | {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"},
1172 | {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"},
1173 | {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"},
1174 | {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"},
1175 | {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"},
1176 | {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"},
1177 | {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"},
1178 | ]
1179 | typer = [
1180 | {file = "typer-0.4.0-py3-none-any.whl", hash = "sha256:d81169725140423d072df464cad1ff25ee154ef381aaf5b8225352ea187ca338"},
1181 | {file = "typer-0.4.0.tar.gz", hash = "sha256:63c3aeab0549750ffe40da79a1b524f60e08a2cbc3126c520ebf2eeaf507f5dd"},
1182 | ]
1183 | types-pyyaml = [
1184 | {file = "types-PyYAML-5.4.10.tar.gz", hash = "sha256:1d9e431e9f1f78a65ea957c558535a3b15ad67ea4912bce48a6c1b613dcf81ad"},
1185 | {file = "types_PyYAML-5.4.10-py3-none-any.whl", hash = "sha256:f1d1357168988e45fa20c65aecb3911462246a84809015dd889ebf8b1db74124"},
1186 | ]
1187 | typing-extensions = [
1188 | {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"},
1189 | {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"},
1190 | {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
1191 | ]
1192 | typing-inspect = [
1193 | {file = "typing_inspect-0.7.1-py2-none-any.whl", hash = "sha256:b1f56c0783ef0f25fb064a01be6e5407e54cf4a4bf4f3ba3fe51e0bd6dcea9e5"},
1194 | {file = "typing_inspect-0.7.1-py3-none-any.whl", hash = "sha256:3cd7d4563e997719a710a3bfe7ffb544c6b72069b6812a02e9b414a8fa3aaa6b"},
1195 | {file = "typing_inspect-0.7.1.tar.gz", hash = "sha256:047d4097d9b17f46531bf6f014356111a1b6fb821a24fe7ac909853ca2a782aa"},
1196 | ]
1197 | urllib3 = [
1198 | {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
1199 | {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
1200 | ]
1201 | watchdog = [
1202 | {file = "watchdog-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5f57ce4f7e498278fb2a091f39359930144a0f2f90ea8cbf4523c4e25de34028"},
1203 | {file = "watchdog-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b74d0d92a69a7ab5f101f9fe74e44ba017be269efa824337366ccbb4effde85"},
1204 | {file = "watchdog-2.1.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59767f476cd1f48531bf378f0300565d879688c82da8369ca8c52f633299523c"},
1205 | {file = "watchdog-2.1.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:814d396859c95598f7576d15bc257c3bd3ba61fa4bc1db7dfc18f09070ded7da"},
1206 | {file = "watchdog-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28777dbed3bbd95f9c70f461443990a36c07dbf49ae7cd69932cdd1b8fb2850c"},
1207 | {file = "watchdog-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5cf78f794c9d7bc64a626ef4f71aff88f57a7ae288e0b359a9c6ea711a41395f"},
1208 | {file = "watchdog-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:43bf728eb7830559f329864ab5da2302c15b2efbac24ad84ccc09949ba753c40"},
1209 | {file = "watchdog-2.1.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a7053d4d22dc95c5e0c90aeeae1e4ed5269d2f04001798eec43a654a03008d22"},
1210 | {file = "watchdog-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6f3ad1d973fe8fc8fe64ba38f6a934b74346342fa98ef08ad5da361a05d46044"},
1211 | {file = "watchdog-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41d44ef21a77a32b55ce9bf59b75777063751f688de51098859b7c7f6466589a"},
1212 | {file = "watchdog-2.1.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed4ca4351cd2bb0d863ee737a2011ca44d8d8be19b43509bd4507f8a449b376b"},
1213 | {file = "watchdog-2.1.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8874d5ad6b7f43b18935d9b0183e29727a623a216693d6938d07dfd411ba462f"},
1214 | {file = "watchdog-2.1.5-py3-none-manylinux2014_aarch64.whl", hash = "sha256:50a7f81f99d238f72185f481b493f9de80096e046935b60ea78e1276f3d76960"},
1215 | {file = "watchdog-2.1.5-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e40e33a4889382824846b4baa05634e1365b47c6fa40071dc2d06b4d7c715fc1"},
1216 | {file = "watchdog-2.1.5-py3-none-manylinux2014_i686.whl", hash = "sha256:78b1514067ff4089f4dac930b043a142997a5b98553120919005e97fbaba6546"},
1217 | {file = "watchdog-2.1.5-py3-none-manylinux2014_ppc64.whl", hash = "sha256:58ae842300cbfe5e62fb068c83901abe76e4f413234b7bec5446e4275eb1f9cb"},
1218 | {file = "watchdog-2.1.5-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:b0cc7d8b7d60da6c313779d85903ce39a63d89d866014b085f720a083d5f3e9a"},
1219 | {file = "watchdog-2.1.5-py3-none-manylinux2014_s390x.whl", hash = "sha256:e60d3bb7166b7cb830b86938d1eb0e6cfe23dfd634cce05c128f8f9967895193"},
1220 | {file = "watchdog-2.1.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:51af09ae937ada0e9a10cc16988ec03c649754a91526170b6839b89fc56d6acb"},
1221 | {file = "watchdog-2.1.5-py3-none-win32.whl", hash = "sha256:9391003635aa783957b9b11175d9802d3272ed67e69ef2e3394c0b6d9d24fa9a"},
1222 | {file = "watchdog-2.1.5-py3-none-win_amd64.whl", hash = "sha256:eab14adfc417c2c983fbcb2c73ef3f28ba6990d1fff45d1180bf7e38bda0d98d"},
1223 | {file = "watchdog-2.1.5-py3-none-win_ia64.whl", hash = "sha256:a2888a788893c4ef7e562861ec5433875b7915f930a5a7ed3d32c048158f1be5"},
1224 | {file = "watchdog-2.1.5.tar.gz", hash = "sha256:5563b005907613430ef3d4aaac9c78600dd5704e84764cb6deda4b3d72807f09"},
1225 | ]
1226 | zipp = [
1227 | {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"},
1228 | {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"},
1229 | ]
1230 |
--------------------------------------------------------------------------------