From 7ea8421a6dc08a90d416a816e73c138c5931106b Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 8 Dec 2020 15:47:17 -0800 Subject: [PATCH 01/50] feat: Add allOf support for model definitions BNCH-18722 (#12) Collapses the child elements into one, without class heirarchy, mixins, etc This is a replaying of 2670d11 (first implementation) and 9f5b95a (a bugfix) onto the new `main-v.0.7.0`, modified for the refactored upstream. This should bring `main-v.0.7.1` up to par with `main` for the features we implemented in our fork (dropping our `Unset` implementation for theirs) --- .../parser/properties/__init__.py | 28 +++++++- .../parser/properties/model_property.py | 55 +++++++++++++++- .../test_parser/test_properties/test_init.py | 23 +++++-- .../test_properties/test_model_property.py | 66 +++++++++++++++++++ 4 files changed, 163 insertions(+), 9 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 427276692..487f5b464 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -250,14 +250,27 @@ def build_model_property( required_properties: List[Property] = [] optional_properties: List[Property] = [] relative_imports: Set[str] = set() + references: List[oai.Reference] = [] class_name = data.title or name if parent_name: class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}" ref = Reference.from_ref(class_name) - for key, value in (data.properties or {}).items(): + all_props = data.properties or {} + if not isinstance(data, oai.Reference) and data.allOf: + for sub_prop in data.allOf: + if isinstance(sub_prop, oai.Reference): + references += [sub_prop] + else: + all_props.update(sub_prop.properties or {}) + required_set.update(sub_prop.required or []) + + for key, value in all_props.items(): prop_required = key in required_set + if not isinstance(value, oai.Reference) and value.allOf: + # resolved later + continue prop, schemas = property_from_data( name=key, required=prop_required, data=value, schemas=schemas, parent_name=class_name ) @@ -292,6 +305,7 @@ def build_model_property( prop = ModelProperty( reference=ref, + references=references, required_properties=required_properties, optional_properties=optional_properties, relative_imports=relative_imports, @@ -544,6 +558,16 @@ def build_schemas(*, components: Dict[str, Union[oai.Reference, oai.Schema]]) -> schemas = schemas_or_err processing = True # We made some progress this round, do another after it's done to_process = next_round - schemas.errors.extend(errors) + resolve_errors: List[PropertyError] = [] + models = list(schemas.models.values()) + for model in models: + schemas_or_err = model.resolve_references(components=components, schemas=schemas) + if isinstance(schemas_or_err, PropertyError): + resolve_errors.append(schemas_or_err) + else: + schemas = schemas_or_err + + schemas.errors.extend(errors) + schemas.errors.extend(resolve_errors) return schemas diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 084017a41..40d1f930b 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -1,17 +1,25 @@ -from typing import ClassVar, List, Set, Union +from __future__ import annotations + +from collections.abc import Iterable +from typing import TYPE_CHECKING, ClassVar, Dict, List, Set, Union import attr +from ... import schema as oai +from ..errors import PropertyError from ..reference import Reference from .property import Property +if TYPE_CHECKING: + from .schemas import Schemas + @attr.s(auto_attribs=True, frozen=True) class ModelProperty(Property): """ A property which refers to another Schema """ reference: Reference - + references: List[oai.Reference] required_properties: List[Property] optional_properties: List[Property] description: str @@ -20,6 +28,49 @@ class ModelProperty(Property): template: ClassVar[str] = "model_property.pyi" + def resolve_references( + self, components: Dict[str, Union[oai.Reference, oai.Schema]], schemas: Schemas + ) -> Union[Schemas, PropertyError]: + from ..properties import property_from_data + + required_set = set() + props = {} + while self.references: + reference = self.references.pop() + source_name = Reference.from_ref(reference.ref).class_name + referenced_prop = components[source_name] + assert isinstance(referenced_prop, oai.Schema) + for p, val in (referenced_prop.properties or {}).items(): + props[p] = (val, source_name) + for sub_prop in referenced_prop.allOf or []: + if isinstance(sub_prop, oai.Reference): + self.references.append(sub_prop) + else: + for p, val in (sub_prop.properties or {}).items(): + props[p] = (val, source_name) + if isinstance(referenced_prop.required, Iterable): + for sub_prop_name in referenced_prop.required: + required_set.add(sub_prop_name) + + for key, (value, source_name) in (props or {}).items(): + required = key in required_set + prop, schemas = property_from_data( + name=key, required=required, data=value, schemas=schemas, parent_name=source_name + ) + if isinstance(prop, PropertyError): + return prop + if required: + self.required_properties.append(prop) + # Remove the optional version + new_optional_props = [op for op in self.optional_properties if op.name != prop.name] + self.optional_properties.clear() + self.optional_properties.extend(new_optional_props) + elif not any(ep for ep in (self.optional_properties + self.required_properties) if ep.name == prop.name): + self.optional_properties.append(prop) + self.relative_imports.update(prop.get_imports(prefix="..")) + + return schemas + def get_type_string(self, no_optional: bool = False) -> str: """ Get a string representation of type that should be used when declaring this property """ type_string = self.reference.class_name diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index a7ea05881..2f3c13676 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -586,6 +586,7 @@ def test_property_from_data_ref_model(self): nullable=False, default=None, reference=Reference(class_name=class_name, module_name="my_model"), + references=[], required_properties=[], optional_properties=[], description="", @@ -602,6 +603,7 @@ def test_property_from_data_ref_model(self): nullable=False, default=None, reference=Reference(class_name=class_name, module_name="my_model"), + references=[], required_properties=[], optional_properties=[], description="", @@ -988,19 +990,25 @@ def test__string_based_property_unsupported_format(self, mocker): def test_build_schemas(mocker): build_model_property = mocker.patch(f"{MODULE_NAME}.build_model_property") in_data = {"1": mocker.MagicMock(enum=None), "2": mocker.MagicMock(enum=None), "3": mocker.MagicMock(enum=None)} + model_1 = mocker.MagicMock() schemas_1 = mocker.MagicMock() model_2 = mocker.MagicMock() schemas_2 = mocker.MagicMock(errors=[]) - error = PropertyError() + schemas_2.models = {"1": model_1, "2": model_2} + error_1 = PropertyError() schemas_3 = mocker.MagicMock() + schemas_4 = mocker.MagicMock(errors=[]) + model_1.resolve_references.return_value = schemas_4 + error_2 = PropertyError() + model_2.resolve_references.return_value = error_2 # This loops through one for each, then again to retry the error build_model_property.side_effect = [ (model_1, schemas_1), (model_2, schemas_2), - (error, schemas_3), - (error, schemas_3), + (error_1, schemas_3), + (error_1, schemas_3), ] from openapi_python_client.parser.properties import Schemas, build_schemas @@ -1016,8 +1024,12 @@ def test_build_schemas(mocker): ] ) # schemas_3 was the last to come back from build_model_property, but it should be ignored because it's an error - assert result == schemas_2 - assert result.errors == [error] + model_1.resolve_references.assert_called_once_with(components=in_data, schemas=schemas_2) + # schemas_4 came from resolving model_1 + model_2.resolve_references.assert_called_once_with(components=in_data, schemas=schemas_4) + # resolving model_2 resulted in err, so no schemas_5 + assert result == schemas_4 + assert result.errors == [error_1, error_2] def test_build_parse_error_on_reference(): @@ -1091,6 +1103,7 @@ def test_build_model_property(additional_properties_schema, expected_additional_ nullable=False, default=None, reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), + references=[], required_properties=[StringProperty(name="req", required=True, nullable=False, default=None)], optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None)], description=data.description, diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 1024ef179..97458c322 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -23,6 +23,7 @@ def test_get_type_string(no_optional, nullable, required, expected): nullable=nullable, default=None, reference=Reference(class_name="MyClass", module_name="my_module"), + references=[], description="", optional_properties=[], required_properties=[], @@ -42,6 +43,7 @@ def test_get_imports(): nullable=True, default=None, reference=Reference(class_name="MyClass", module_name="my_module"), + references=[], description="", optional_properties=[], required_properties=[], @@ -57,3 +59,67 @@ def test_get_imports(): "from typing import Dict", "from typing import cast", } + + +def test_resolve_references(mocker): + import openapi_python_client.schema as oai + from openapi_python_client.parser.properties import build_model_property + + schemas = { + "RefA": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["String"], + properties={ + "String": oai.Schema.construct(type="string"), + "Enum": oai.Schema.construct(type="string", enum=["aValue"]), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + }, + ), + "RefB": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["DateTime"], + properties={ + "Int": oai.Schema.construct(type="integer"), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + # Intentionally no properties defined + "RefC": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + ), + } + + model_schema = oai.Schema.construct( + allOf=[ + oai.Reference.construct(ref="#/components/schemas/RefA"), + oai.Reference.construct(ref="#/components/schemas/RefB"), + oai.Reference.construct(ref="#/components/schemas/RefC"), + oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["Float"], + properties={ + "String": oai.Schema.construct(type="string"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + ] + ) + + components = {**schemas, "Model": model_schema} + + from openapi_python_client.parser.properties import Schemas + + schemas_holder = Schemas() + model, schemas_holder = build_model_property( + data=model_schema, name="Model", required=True, schemas=schemas_holder, parent_name=None + ) + model.resolve_references(components, schemas_holder) + assert sorted(p.name for p in model.required_properties) == ["DateTime", "Float", "String"] + assert all(p.required for p in model.required_properties) + assert sorted(p.name for p in model.optional_properties) == ["Enum", "Int"] + assert all(not p.required for p in model.optional_properties) From 70cb4bb2c8bc5c118ebfa8278b13219aa4e9b1b5 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Fri, 4 Dec 2020 14:04:12 -0800 Subject: [PATCH 02/50] feat: Add setup.py support BNCH-18722 (#11) Add support for generating setup.py and the initially generated one --- pyproject.toml | 6 ++++++ setup.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml index a1de2316c..3c6f98df0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,12 @@ task regen\ && task regen_custom\ && task e2e\ """ +gen-setuppy = """ +poetry build \ +&& tar --strip-components=1 -xvf "$(ls -1 dist/*tar.gz | tail -1)" '*/setup.py' \ +&& isort setup.py \ +&& black setup.py +""" [tool.black] line-length = 120 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..c38ef4ea0 --- /dev/null +++ b/setup.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +from setuptools import setup + +packages = [ + "openapi_python_client", + "openapi_python_client.parser", + "openapi_python_client.parser.properties", + "openapi_python_client.schema", + "openapi_python_client.templates", +] + +package_data = {"": ["*"], "openapi_python_client.templates": ["property_templates/*"]} + +install_requires = [ + "attrs>=20.1.0,<21.0.0", + "autoflake>=1.4,<2.0", + "black>=20.8b1", + "httpx>=0.15.4,<0.17.0", + "isort>=5.0.5,<6.0.0", + "jinja2>=2.11.1,<3.0.0", + "pydantic>=1.6.1,<2.0.0", + "python-dateutil>=2.8.1,<3.0.0", + "pyyaml>=5.3.1,<6.0.0", + "shellingham>=1.3.2,<2.0.0", + "stringcase>=1.2.0,<2.0.0", + "typer>=0.3,<0.4", +] + +extras_require = { + ':python_version < "3.8"': ["importlib_metadata>=2.0.0,<3.0.0"], + ':sys_platform == "win32"': ["colorama>=0.4.3,<0.5.0"], +} + +entry_points = {"console_scripts": ["openapi-python-client = openapi_python_client.cli:app"]} + +setup_kwargs = { + "name": "openapi-python-client", + "version": "0.7.0", + "description": "Generate modern Python clients from OpenAPI", + "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', + "author": "Dylan Anthony", + "author_email": "danthony@triaxtec.com", + "maintainer": None, + "maintainer_email": None, + "url": "https://github.com/triaxtec/openapi-python-client", + "packages": packages, + "package_data": package_data, + "install_requires": install_requires, + "extras_require": extras_require, + "entry_points": entry_points, + "python_requires": ">=3.6,<4.0", +} + + +setup(**setup_kwargs) From ce30b4c5018e790deceb95d9fa8be1d1713d2fed Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 8 Dec 2020 18:17:01 -0800 Subject: [PATCH 03/50] fix: require setuptools >50 in pyproject.toml --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3c6f98df0..222b69561 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,5 +98,8 @@ skip = [".venv", "tests/test_templates"] omit = ["openapi_python_client/templates/*"] [build-system] -requires = ["poetry>=1.0"] +requires = [ + "setuptools>=30.3.0,<50", + "poetry>=1.0" +] build-backend = "poetry.masonry.api" From 0b9a99aa40cbf0df340a9a93de6c8f36991ec096 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Thu, 14 Jan 2021 18:53:44 -0500 Subject: [PATCH 04/50] fix: Fix bug parsing `allOf` in nested keys BNCH-20174 (#29) --- .../parser/properties/__init__.py | 10 +-- .../test_properties/test_model_property.py | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 487f5b464..f6289ce7c 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -268,9 +268,6 @@ def build_model_property( for key, value in all_props.items(): prop_required = key in required_set - if not isinstance(value, oai.Reference) and value.allOf: - # resolved later - continue prop, schemas = property_from_data( name=key, required=prop_required, data=value, schemas=schemas, parent_name=class_name ) @@ -463,9 +460,6 @@ def _property_from_data( ) if data.anyOf or data.oneOf: return build_union_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) - if not data.type: - return NoneProperty(name=name, required=required, nullable=False, default=None), schemas - if data.type == "string": return _string_based_property(name=name, required=required, data=data), schemas elif data.type == "number": @@ -500,8 +494,10 @@ def _property_from_data( ) elif data.type == "array": return build_list_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) - elif data.type == "object": + elif data.type == "object" or data.allOf: return build_model_property(data=data, name=name, schemas=schemas, required=required, parent_name=parent_name) + elif not data.type: + return NoneProperty(name=name, required=required, nullable=False, default=None), schemas return PropertyError(data=data, detail=f"unknown type {data.type}"), schemas diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 97458c322..5a40f9e74 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -123,3 +123,79 @@ def test_resolve_references(mocker): assert all(p.required for p in model.required_properties) assert sorted(p.name for p in model.optional_properties) == ["Enum", "Int"] assert all(not p.required for p in model.optional_properties) + + +def test_resolve_references_nested_allof(mocker): + import openapi_python_client.schema as oai + from openapi_python_client.parser.properties import build_model_property + + schemas = { + "RefA": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["String"], + properties={ + "String": oai.Schema.construct(type="string"), + "Enum": oai.Schema.construct(type="string", enum=["aValue"]), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + }, + ), + "RefB": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["DateTime"], + properties={ + "Int": oai.Schema.construct(type="integer"), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + # Intentionally no properties defined + "RefC": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + ), + } + + model_schema = oai.Schema.construct( + type="object", + properties={ + "Key": oai.Schema.construct( + allOf=[ + oai.Reference.construct(ref="#/components/schemas/RefA"), + oai.Reference.construct(ref="#/components/schemas/RefB"), + oai.Reference.construct(ref="#/components/schemas/RefC"), + oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["Float"], + properties={ + "String": oai.Schema.construct(type="string"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + ] + ), + } + ) + + components = {**schemas, "Model": model_schema} + + from openapi_python_client.parser.properties import ModelProperty, Schemas + + schemas_holder = Schemas() + model, schemas_holder = build_model_property( + data=model_schema, name="Model", required=True, schemas=schemas_holder, parent_name=None + ) + model.resolve_references(components, schemas_holder) + assert sorted(p.name for p in model.required_properties) == [] + assert sorted(p.name for p in model.optional_properties) == ["Key"] + assert all(not p.required for p in model.optional_properties) + + key_property = model.optional_properties[0] + assert isinstance(key_property, ModelProperty) + key_property.resolve_references(components, schemas_holder) + assert sorted(p.name for p in key_property.required_properties) == ["DateTime", "Float", "String"] + assert all(p.required for p in key_property.required_properties) + assert sorted(p.name for p in key_property.optional_properties) == ["Enum", "Int"] + assert all(not p.required for p in key_property.optional_properties) \ No newline at end of file From f49d0bc188e85920bb4968fa4ee8c9c72cb93900 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 09:35:41 -0500 Subject: [PATCH 05/50] fix: Fix optional model properties BNCH-20284 (#35) --- .../custom_e2e/models/__init__.py | 4 + .../custom_e2e/models/a_model.py | 50 +++++++++++ .../custom_e2e/models/a_model_model.py | 85 +++++++++++++++++++ .../models/a_model_not_required_model.py | 85 +++++++++++++++++++ .../a_model_not_required_nullable_model.py | 85 +++++++++++++++++++ .../models/a_model_nullable_model.py | 85 +++++++++++++++++++ ...el_with_primitive_additional_properties.py | 2 +- .../my_test_api_client/models/__init__.py | 4 + .../my_test_api_client/models/a_model.py | 50 +++++++++++ .../models/a_model_model.py | 85 +++++++++++++++++++ .../models/a_model_not_required_model.py | 85 +++++++++++++++++++ .../a_model_not_required_nullable_model.py | 85 +++++++++++++++++++ .../models/a_model_nullable_model.py | 85 +++++++++++++++++++ ...el_with_primitive_additional_properties.py | 2 +- end_to_end_tests/openapi.json | 38 ++++++++- .../property_templates/model_property.pyi | 4 +- .../test_properties/test_model_property.py | 4 +- 17 files changed, 831 insertions(+), 7 deletions(-) create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py index d3ca924b3..6f5ac7423 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py @@ -1,6 +1,10 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel +from .a_model_model import AModelModel +from .a_model_not_required_model import AModelNotRequiredModel +from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 2bf3e140d..15a7cc68c 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -4,6 +4,10 @@ import attr from dateutil.parser import isoparse +from ..models.a_model_model import AModelModel +from ..models.a_model_not_required_model import AModelNotRequiredModel +from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..types import UNSET, Unset @@ -17,12 +21,16 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str + model: AModelModel a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] + nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, Optional[str]] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET + not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET + not_required_nullable_model: Union[Optional[AModelNotRequiredNullableModel], Unset] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -35,6 +43,8 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable + model = self.model.to_dict() + nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -52,6 +62,17 @@ def to_dict(self) -> Dict[str, Any]: required_nullable = self.required_nullable not_required_nullable = self.not_required_nullable not_required_not_nullable = self.not_required_not_nullable + nullable_model = self.nullable_model.to_dict() if self.nullable_model else None + + not_required_model: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_model, Unset): + not_required_model = self.not_required_model.to_dict() + + not_required_nullable_model: Union[None, Unset, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_nullable_model, Unset): + not_required_nullable_model = ( + self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None + ) field_dict: Dict[str, Any] = {} field_dict.update( @@ -60,8 +81,10 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, + "model": model, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, + "nullable_model": nullable_model, } ) if nested_list_of_enums is not UNSET: @@ -72,6 +95,10 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_nullable"] = not_required_nullable if not_required_not_nullable is not UNSET: field_dict["not_required_not_nullable"] = not_required_not_nullable + if not_required_model is not UNSET: + field_dict["not_required_model"] = not_required_model + if not_required_nullable_model is not UNSET: + field_dict["not_required_nullable_model"] = not_required_nullable_model return field_dict @@ -99,6 +126,8 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat required_not_nullable = d.pop("required_not_nullable") + model = AModelModel.from_dict(d.pop("model")) + nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -124,17 +153,38 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) + nullable_model = None + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) + + not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET + _not_required_model = d.pop("not_required_model", UNSET) + if not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) + + not_required_nullable_model = None + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( + cast(Dict[str, Any], _not_required_nullable_model) + ) + a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, + model=model, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, required_nullable=required_nullable, not_required_nullable=not_required_nullable, not_required_not_nullable=not_required_not_nullable, + nullable_model=nullable_model, + not_required_model=not_required_model, + not_required_nullable_model=not_required_nullable_model, ) return a_model diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py new file mode 100644 index 000000000..c1a00c152 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_model = AModelModel( + a_property=a_property, + ) + + a_model_model.additional_properties = d + return a_model_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py new file mode 100644 index 000000000..adecb4225 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_model = AModelNotRequiredModel( + a_property=a_property, + ) + + a_model_not_required_model.additional_properties = d + return a_model_not_required_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py new file mode 100644 index 000000000..9de2e3798 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_nullable_model = AModelNotRequiredNullableModel( + a_property=a_property, + ) + + a_model_not_required_nullable_model.additional_properties = d + return a_model_not_required_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py new file mode 100644 index 000000000..cbcf120f8 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_nullable_model = AModelNullableModel( + a_property=a_property, + ) + + a_model_nullable_model.additional_properties = d + return a_model_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 47d65d90b..797c1ce31 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -33,7 +33,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): + if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( cast(Dict[str, Any], _a_date_holder) ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index d3ca924b3..6f5ac7423 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,6 +1,10 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel +from .a_model_model import AModelModel +from .a_model_not_required_model import AModelNotRequiredModel +from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 2bf3e140d..15a7cc68c 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -4,6 +4,10 @@ import attr from dateutil.parser import isoparse +from ..models.a_model_model import AModelModel +from ..models.a_model_not_required_model import AModelNotRequiredModel +from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..types import UNSET, Unset @@ -17,12 +21,16 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str + model: AModelModel a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] + nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, Optional[str]] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET + not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET + not_required_nullable_model: Union[Optional[AModelNotRequiredNullableModel], Unset] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -35,6 +43,8 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable + model = self.model.to_dict() + nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -52,6 +62,17 @@ def to_dict(self) -> Dict[str, Any]: required_nullable = self.required_nullable not_required_nullable = self.not_required_nullable not_required_not_nullable = self.not_required_not_nullable + nullable_model = self.nullable_model.to_dict() if self.nullable_model else None + + not_required_model: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_model, Unset): + not_required_model = self.not_required_model.to_dict() + + not_required_nullable_model: Union[None, Unset, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_nullable_model, Unset): + not_required_nullable_model = ( + self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None + ) field_dict: Dict[str, Any] = {} field_dict.update( @@ -60,8 +81,10 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, + "model": model, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, + "nullable_model": nullable_model, } ) if nested_list_of_enums is not UNSET: @@ -72,6 +95,10 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_nullable"] = not_required_nullable if not_required_not_nullable is not UNSET: field_dict["not_required_not_nullable"] = not_required_not_nullable + if not_required_model is not UNSET: + field_dict["not_required_model"] = not_required_model + if not_required_nullable_model is not UNSET: + field_dict["not_required_nullable_model"] = not_required_nullable_model return field_dict @@ -99,6 +126,8 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat required_not_nullable = d.pop("required_not_nullable") + model = AModelModel.from_dict(d.pop("model")) + nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -124,17 +153,38 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) + nullable_model = None + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) + + not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET + _not_required_model = d.pop("not_required_model", UNSET) + if not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) + + not_required_nullable_model = None + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( + cast(Dict[str, Any], _not_required_nullable_model) + ) + a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, + model=model, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, required_nullable=required_nullable, not_required_nullable=not_required_nullable, not_required_not_nullable=not_required_not_nullable, + nullable_model=nullable_model, + not_required_model=not_required_model, + not_required_nullable_model=not_required_nullable_model, ) return a_model diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py new file mode 100644 index 000000000..c1a00c152 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_model = AModelModel( + a_property=a_property, + ) + + a_model_model.additional_properties = d + return a_model_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py new file mode 100644 index 000000000..adecb4225 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_model = AModelNotRequiredModel( + a_property=a_property, + ) + + a_model_not_required_model.additional_properties = d + return a_model_not_required_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py new file mode 100644 index 000000000..9de2e3798 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_nullable_model = AModelNotRequiredNullableModel( + a_property=a_property, + ) + + a_model_not_required_nullable_model.additional_properties = d + return a_model_not_required_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py new file mode 100644 index 000000000..cbcf120f8 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_nullable_model = AModelNullableModel( + a_property=a_property, + ) + + a_model_nullable_model.additional_properties = d + return a_model_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 47d65d90b..797c1ce31 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -33,7 +33,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): + if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( cast(Dict[str, Any], _a_date_holder) ) diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 9e3d78908..196538f19 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -622,7 +622,7 @@ "schemas": { "AModel": { "title": "AModel", - "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable"], + "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable", "model", "nullable_model"], "type": "object", "properties": { "an_enum_value": { @@ -686,6 +686,42 @@ "title": "NOT Required AND NOT Nullable", "type": "string", "nullable": false + }, + "model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": false + }, + "nullable_model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": true + }, + "not_required_model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": false + }, + "not_required_nullable_model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": true } }, "description": "A Model for testing all the ways custom objects can be used ", diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index e6746cb24..b41289409 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,5 +1,5 @@ {% macro construct(property, source, initial_value=None) %} -{% if property.required %} +{% if property.required and not property.nullable %} {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) {% else %} {% if initial_value != None %} @@ -10,7 +10,7 @@ {{ property.python_name }}: {{ property.get_type_string() }} = UNSET {% endif %} _{{ property.python_name }} = {{source}} -if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): +if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{% if property.nullable and not property.required %} and {% endif %}{% if not property.required %}not isinstance(_{{ property.python_name }}, Unset){% endif %}: {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(cast(Dict[str, Any], _{{ property.python_name }})) {% endif %} {% endmacro %} diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 5a40f9e74..421f40d48 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -176,7 +176,7 @@ def test_resolve_references_nested_allof(mocker): ), ] ), - } + }, ) components = {**schemas, "Model": model_schema} @@ -198,4 +198,4 @@ def test_resolve_references_nested_allof(mocker): assert sorted(p.name for p in key_property.required_properties) == ["DateTime", "Float", "String"] assert all(p.required for p in key_property.required_properties) assert sorted(p.name for p in key_property.optional_properties) == ["Enum", "Int"] - assert all(not p.required for p in key_property.optional_properties) \ No newline at end of file + assert all(not p.required for p in key_property.optional_properties) From b0109cdb816fab310c741a0214283219d5124e05 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 17:39:51 -0500 Subject: [PATCH 06/50] feat: Serialize model query parameters with `style=form, explode=true` BNCH-18023 (#39) --- .../api/tests/defaults_tests_defaults_post.py | 28 +++++++++------ ...tional_value_tests_optional_query_param.py | 2 +- .../api/tests/defaults_tests_defaults_post.py | 36 +++++++++++++------ ...tional_value_tests_optional_query_param.py | 2 +- end_to_end_tests/openapi.json | 8 +++++ .../parser/properties/model_property.py | 1 + .../parser/properties/property.py | 1 + .../templates/endpoint_macros.pyi | 9 ++--- 8 files changed, 61 insertions(+), 26 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index 574d5018b..f87ad3e1b 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -13,6 +13,7 @@ from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError +from ...models.model_with_union_property import ModelWithUnionProperty from ...types import UNSET, Unset @@ -50,6 +51,7 @@ def httpx_request( union_prop: Union[Unset, float, str] = "not a float", union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, enum_prop: Union[Unset, AnEnum] = UNSET, + model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: json_datetime_prop: Union[Unset, str] = UNSET @@ -89,27 +91,33 @@ def httpx_request( if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop + json_model_prop: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(model_prop, Unset): + json_model_prop = model_prop.to_dict() + params: Dict[str, Any] = {} - if string_prop is not UNSET: + if not isinstance(string_prop, Unset) and string_prop is not None: params["string_prop"] = string_prop - if datetime_prop is not UNSET: + if not isinstance(json_datetime_prop, Unset) and json_datetime_prop is not None: params["datetime_prop"] = json_datetime_prop - if date_prop is not UNSET: + if not isinstance(json_date_prop, Unset) and json_date_prop is not None: params["date_prop"] = json_date_prop - if float_prop is not UNSET: + if not isinstance(float_prop, Unset) and float_prop is not None: params["float_prop"] = float_prop - if int_prop is not UNSET: + if not isinstance(int_prop, Unset) and int_prop is not None: params["int_prop"] = int_prop - if boolean_prop is not UNSET: + if not isinstance(boolean_prop, Unset) and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if list_prop is not UNSET: + if not isinstance(json_list_prop, Unset) and json_list_prop is not None: params["list_prop"] = json_list_prop - if union_prop is not UNSET: + if not isinstance(json_union_prop, Unset) and json_union_prop is not None: params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET: + if not isinstance(json_union_prop_with_ref, Unset) and json_union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET: + if not isinstance(json_enum_prop, Unset) and json_enum_prop is not None: params["enum_prop"] = json_enum_prop + if not isinstance(json_model_prop, Unset) and json_model_prop is not None: + params.update(json_model_prop) response = client.request( "post", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index bff43cc10..616dc4252 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -44,7 +44,7 @@ def httpx_request( json_query_param = query_param params: Dict[str, Any] = {} - if query_param is not UNSET: + if not isinstance(json_query_param, Unset) and json_query_param is not None: params["query_param"] = json_query_param response = client.request( diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index 9242cddaa..ff6ef2409 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -7,6 +7,7 @@ from ...client import Client from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError +from ...models.model_with_union_property import ModelWithUnionProperty from ...types import UNSET, Response, Unset @@ -23,6 +24,7 @@ def _get_kwargs( union_prop: Union[Unset, float, str] = "not a float", union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, enum_prop: Union[Unset, AnEnum] = UNSET, + model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, ) -> Dict[str, Any]: url = "{}/tests/defaults".format(client.base_url) @@ -65,27 +67,33 @@ def _get_kwargs( if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop + json_model_prop: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(model_prop, Unset): + json_model_prop = model_prop.to_dict() + params: Dict[str, Any] = {} - if string_prop is not UNSET: + if not isinstance(string_prop, Unset) and string_prop is not None: params["string_prop"] = string_prop - if datetime_prop is not UNSET: + if not isinstance(json_datetime_prop, Unset) and json_datetime_prop is not None: params["datetime_prop"] = json_datetime_prop - if date_prop is not UNSET: + if not isinstance(json_date_prop, Unset) and json_date_prop is not None: params["date_prop"] = json_date_prop - if float_prop is not UNSET: + if not isinstance(float_prop, Unset) and float_prop is not None: params["float_prop"] = float_prop - if int_prop is not UNSET: + if not isinstance(int_prop, Unset) and int_prop is not None: params["int_prop"] = int_prop - if boolean_prop is not UNSET: + if not isinstance(boolean_prop, Unset) and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if list_prop is not UNSET: + if not isinstance(json_list_prop, Unset) and json_list_prop is not None: params["list_prop"] = json_list_prop - if union_prop is not UNSET: + if not isinstance(json_union_prop, Unset) and json_union_prop is not None: params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET: + if not isinstance(json_union_prop_with_ref, Unset) and json_union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET: + if not isinstance(json_enum_prop, Unset) and json_enum_prop is not None: params["enum_prop"] = json_enum_prop + if not isinstance(json_model_prop, Unset) and json_model_prop is not None: + params.update(json_model_prop) return { "url": url, @@ -130,6 +138,7 @@ def sync_detailed( union_prop: Union[Unset, float, str] = "not a float", union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, enum_prop: Union[Unset, AnEnum] = UNSET, + model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -143,6 +152,7 @@ def sync_detailed( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ) response = httpx.post( @@ -165,6 +175,7 @@ def sync( union_prop: Union[Unset, float, str] = "not a float", union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, enum_prop: Union[Unset, AnEnum] = UNSET, + model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -180,6 +191,7 @@ def sync( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ).parsed @@ -196,6 +208,7 @@ async def asyncio_detailed( union_prop: Union[Unset, float, str] = "not a float", union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, enum_prop: Union[Unset, AnEnum] = UNSET, + model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -209,6 +222,7 @@ async def asyncio_detailed( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ) async with httpx.AsyncClient() as _client: @@ -230,6 +244,7 @@ async def asyncio( union_prop: Union[Unset, float, str] = "not a float", union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, enum_prop: Union[Unset, AnEnum] = UNSET, + model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -246,5 +261,6 @@ async def asyncio( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ) ).parsed diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 751f48e03..576a770fe 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -21,7 +21,7 @@ def _get_kwargs( json_query_param = query_param params: Dict[str, Any] = {} - if query_param is not UNSET: + if not isinstance(json_query_param, Unset) and json_query_param is not None: params["query_param"] = json_query_param return { diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 196538f19..8562f6796 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -396,6 +396,14 @@ }, "name": "enum_prop", "in": "query" + }, + { + "required": false, + "schema": { + "$ref": "#/components/schemas/ModelWithUnionProperty" + }, + "name": "model_prop", + "in": "query" } ], "responses": { diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 40d1f930b..4bcbe4695 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -27,6 +27,7 @@ class ModelProperty(Property): additional_properties: Union[bool, Property] template: ClassVar[str] = "model_property.pyi" + json_is_dict: ClassVar[bool] = True def resolve_references( self, components: Dict[str, Union[oai.Reference, oai.Schema]], schemas: Schemas diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index 0b7047551..a94af72ba 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -28,6 +28,7 @@ class Property: python_name: str = attr.ib(init=False) template: ClassVar[Optional[str]] = None + json_is_dict: ClassVar[bool] = False def __attrs_post_init__(self) -> None: object.__setattr__(self, "python_name", utils.to_valid_python_identifier(utils.snake_case(self.name))) diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 5819714d8..8d3d464c3 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -33,11 +33,12 @@ params: Dict[str, Any] = { } {% for property in endpoint.query_parameters %} {% if not property.required %} -if {{ property.python_name }} is not UNSET: - {% if property.template %} - params["{{ property.name }}"] = {{ "json_" + property.python_name }} + {% set property_name = "json_" + property.python_name if property.template else property.python_name %} +if {% if not property.required %}not isinstance({{ property_name }}, Unset) and {% endif %}{{ property_name }} is not None: + {% if property.json_is_dict %} + params.update({{ property_name }}) {% else %} - params["{{ property.name }}"] = {{ property.python_name }} + params["{{ property.name }}"] = {{ property_name }} {% endif %} {% endif %} {% endfor %} From f469553d42eb1d977064af60343c88737f09d3f8 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 18:09:24 -0500 Subject: [PATCH 07/50] Cherry-pick optional params --- end_to_end_tests/openapi.json | 87 +++++----- .../parser/properties/__init__.py | 94 +++++----- .../parser/properties/enum_property.py | 14 +- .../parser/properties/model_property.py | 69 +------- .../parser/properties/property.py | 49 ++++-- .../templates/endpoint_macros.pyi | 17 +- .../property_templates/date_property.pyi | 6 +- .../property_templates/datetime_property.pyi | 6 +- .../property_templates/enum_property.pyi | 10 +- .../property_templates/file_property.pyi | 6 +- .../property_templates/list_property.pyi | 8 +- .../property_templates/model_property.pyi | 10 +- .../property_templates/union_property.pyi | 10 +- openapi_python_client/templates/types.py | 5 +- pyproject.toml | 16 +- .../test_parser/test_properties/test_init.py | 163 ++++++++---------- .../test_properties/test_model_property.py | 146 +--------------- .../test_date_property/optional_nullable.py | 2 +- 18 files changed, 254 insertions(+), 464 deletions(-) diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 8562f6796..931fc481e 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -290,12 +290,49 @@ { "required": false, "schema": { - "title": "Datetime Prop", + "title": "Not Required, Not Nullable Datetime Prop", + "nullable": false, "type": "string", "format": "date-time", "default": "1010-10-10T00:00:00" }, - "name": "datetime_prop", + "name": "not_required_not_nullable_datetime_prop", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Not Required, Nullable Datetime Prop", + "nullable": true, + "type": "string", + "format": "date-time", + "default": "1010-10-10T00:00:00" + }, + "name": "not_required_nullable_datetime_prop", + "in": "query" + }, + { + "required": true, + "schema": { + "title": "Required, Not Nullable Datetime Prop", + "nullable": false, + "type": "string", + "format": "date-time", + "default": "1010-10-10T00:00:00" + }, + "name": "required_not_nullable_datetime_prop", + "in": "query" + }, + { + "required": true, + "schema": { + "title": "Required, Nullable Datetime Prop", + "nullable": true, + "type": "string", + "format": "date-time", + "default": "1010-10-10T00:00:00" + }, + "name": "required_nullable_datetime_prop", "in": "query" }, { @@ -396,14 +433,6 @@ }, "name": "enum_prop", "in": "query" - }, - { - "required": false, - "schema": { - "$ref": "#/components/schemas/ModelWithUnionProperty" - }, - "name": "model_prop", - "in": "query" } ], "responses": { @@ -630,7 +659,7 @@ "schemas": { "AModel": { "title": "AModel", - "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable", "model", "nullable_model"], + "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable"], "type": "object", "properties": { "an_enum_value": { @@ -694,42 +723,6 @@ "title": "NOT Required AND NOT Nullable", "type": "string", "nullable": false - }, - "model": { - "type": "object", - "allOf": [ - { - "ref": "#/components/schemas/ModelWithUnionProperty" - } - ], - "nullable": false - }, - "nullable_model": { - "type": "object", - "allOf": [ - { - "ref": "#/components/schemas/ModelWithUnionProperty" - } - ], - "nullable": true - }, - "not_required_model": { - "type": "object", - "allOf": [ - { - "ref": "#/components/schemas/ModelWithUnionProperty" - } - ], - "nullable": false - }, - "not_required_nullable_model": { - "type": "object", - "allOf": [ - { - "ref": "#/components/schemas/ModelWithUnionProperty" - } - ], - "nullable": true } }, "description": "A Model for testing all the ways custom objects can be used ", diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index f6289ce7c..e3a3f69b7 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -19,6 +19,7 @@ class NoneProperty(Property): """ A property that is always None (used for empty schemas) """ _type_string: ClassVar[str] = "None" + _json_type_string: ClassVar[str] = "None" template: ClassVar[Optional[str]] = "none_property.pyi" @@ -29,6 +30,7 @@ class StringProperty(Property): max_length: Optional[int] = None pattern: Optional[str] = None _type_string: ClassVar[str] = "str" + _json_type_string: ClassVar[str] = "str" @attr.s(auto_attribs=True, frozen=True) @@ -38,6 +40,7 @@ class DateTimeProperty(Property): """ _type_string: ClassVar[str] = "datetime.datetime" + _json_type_string: ClassVar[str] = "str" template: ClassVar[str] = "datetime_property.pyi" def get_imports(self, *, prefix: str) -> Set[str]: @@ -58,6 +61,7 @@ class DateProperty(Property): """ A property of type datetime.date """ _type_string: ClassVar[str] = "datetime.date" + _json_type_string: ClassVar[str] = "str" template: ClassVar[str] = "date_property.pyi" def get_imports(self, *, prefix: str) -> Set[str]: @@ -78,6 +82,8 @@ class FileProperty(Property): """ A property used for uploading files """ _type_string: ClassVar[str] = "File" + # Return type of File.to_tuple() + _json_type_string: ClassVar[str] = "Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]" template: ClassVar[str] = "file_property.pyi" def get_imports(self, *, prefix: str) -> Set[str]: @@ -98,6 +104,7 @@ class FloatProperty(Property): """ A property of type float """ _type_string: ClassVar[str] = "float" + _json_type_string: ClassVar[str] = "float" @attr.s(auto_attribs=True, frozen=True) @@ -105,6 +112,7 @@ class IntProperty(Property): """ A property of type int """ _type_string: ClassVar[str] = "int" + _json_type_string: ClassVar[str] = "int" @attr.s(auto_attribs=True, frozen=True) @@ -112,6 +120,7 @@ class BooleanProperty(Property): """ Property for bool """ _type_string: ClassVar[str] = "bool" + _json_type_string: ClassVar[str] = "bool" InnerProp = TypeVar("InnerProp", bound=Property) @@ -122,18 +131,11 @@ class ListProperty(Property, Generic[InnerProp]): """ A property representing a list (array) of other properties """ inner_property: InnerProp + _json_type_string: ClassVar[str] = "List[Any]" template: ClassVar[str] = "list_property.pyi" - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - type_string = f"List[{self.inner_property.get_type_string()}]" - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + def get_base_type_string(self) -> str: + return f"List[{self.inner_property.get_type_string()}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" @@ -167,18 +169,38 @@ def __attrs_post_init__(self) -> None: self, "has_properties_without_templates", any(prop.template is None for prop in self.inner_properties) ) - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - inner_types = [p.get_type_string(no_optional=True) for p in self.inner_properties] - inner_prop_string = ", ".join(inner_types) - type_string = f"Union[{inner_prop_string}]" + def _get_inner_prop_string(self, json: bool = False) -> str: + inner_types = [p.get_type_string(no_optional=True, json=json) for p in self.inner_properties] + unique_inner_types = list(dict.fromkeys(inner_types)) + return ", ".join(unique_inner_types) + + def get_base_type_string(self, json: bool = False) -> str: + return f"Union[{self._get_inner_prop_string(json=json)}]" + + def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str: + """ + Get a string representation of type that should be used when declaring this property. + + This implementation differs slightly from `Property.get_type_string` in order to collapse + nested union types. + """ + type_string = self.get_base_type_string(json=json) if no_optional: return type_string - if not self.required: - type_string = f"Union[Unset, {inner_prop_string}]" - if self.nullable: - type_string = f"Optional[{type_string}]" - return type_string + if self.required: + if self.nullable: + return f"Union[None, {self._get_inner_prop_string(json=json)}]" + else: + return type_string + else: + if self.nullable: + return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]" + else: + if query_parameter: + # For query parameters, None has the same meaning as Unset + return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]" + else: + return f"Union[Unset, {self._get_inner_prop_string(json=json)}]" def get_imports(self, *, prefix: str) -> Set[str]: """ @@ -250,23 +272,13 @@ def build_model_property( required_properties: List[Property] = [] optional_properties: List[Property] = [] relative_imports: Set[str] = set() - references: List[oai.Reference] = [] class_name = data.title or name if parent_name: class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}" ref = Reference.from_ref(class_name) - all_props = data.properties or {} - if not isinstance(data, oai.Reference) and data.allOf: - for sub_prop in data.allOf: - if isinstance(sub_prop, oai.Reference): - references += [sub_prop] - else: - all_props.update(sub_prop.properties or {}) - required_set.update(sub_prop.required or []) - - for key, value in all_props.items(): + for key, value in (data.properties or {}).items(): prop_required = key in required_set prop, schemas = property_from_data( name=key, required=prop_required, data=value, schemas=schemas, parent_name=class_name @@ -302,7 +314,6 @@ def build_model_property( prop = ModelProperty( reference=ref, - references=references, required_properties=required_properties, optional_properties=optional_properties, relative_imports=relative_imports, @@ -460,6 +471,9 @@ def _property_from_data( ) if data.anyOf or data.oneOf: return build_union_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) + if not data.type: + return NoneProperty(name=name, required=required, nullable=False, default=None), schemas + if data.type == "string": return _string_based_property(name=name, required=required, data=data), schemas elif data.type == "number": @@ -494,10 +508,8 @@ def _property_from_data( ) elif data.type == "array": return build_list_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) - elif data.type == "object" or data.allOf: + elif data.type == "object": return build_model_property(data=data, name=name, schemas=schemas, required=required, parent_name=parent_name) - elif not data.type: - return NoneProperty(name=name, required=required, nullable=False, default=None), schemas return PropertyError(data=data, detail=f"unknown type {data.type}"), schemas @@ -554,16 +566,6 @@ def build_schemas(*, components: Dict[str, Union[oai.Reference, oai.Schema]]) -> schemas = schemas_or_err processing = True # We made some progress this round, do another after it's done to_process = next_round - - resolve_errors: List[PropertyError] = [] - models = list(schemas.models.values()) - for model in models: - schemas_or_err = model.resolve_references(components=components, schemas=schemas) - if isinstance(schemas_or_err, PropertyError): - resolve_errors.append(schemas_or_err) - else: - schemas = schemas_or_err - schemas.errors.extend(errors) - schemas.errors.extend(resolve_errors) + return schemas diff --git a/openapi_python_client/parser/properties/enum_property.py b/openapi_python_client/parser/properties/enum_property.py index 1217f23ee..6938dd716 100644 --- a/openapi_python_client/parser/properties/enum_property.py +++ b/openapi_python_client/parser/properties/enum_property.py @@ -18,21 +18,13 @@ class EnumProperty(Property): values: Dict[str, ValueType] reference: Reference value_type: Type[ValueType] + _json_type_string: ClassVar[str] = "int" default: Optional[Any] = attr.ib() template: ClassVar[str] = "enum_property.pyi" - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - - type_string = self.reference.class_name - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + def get_base_type_string(self) -> str: + return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 4bcbe4695..3ab145af4 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -1,87 +1,28 @@ -from __future__ import annotations - -from collections.abc import Iterable -from typing import TYPE_CHECKING, ClassVar, Dict, List, Set, Union +from typing import ClassVar, List, Set, Union import attr -from ... import schema as oai -from ..errors import PropertyError from ..reference import Reference from .property import Property -if TYPE_CHECKING: - from .schemas import Schemas - @attr.s(auto_attribs=True, frozen=True) class ModelProperty(Property): """ A property which refers to another Schema """ reference: Reference - references: List[oai.Reference] + required_properties: List[Property] optional_properties: List[Property] description: str relative_imports: Set[str] additional_properties: Union[bool, Property] + _json_type_string: ClassVar[str] = "Dict[str, Any]" template: ClassVar[str] = "model_property.pyi" - json_is_dict: ClassVar[bool] = True - - def resolve_references( - self, components: Dict[str, Union[oai.Reference, oai.Schema]], schemas: Schemas - ) -> Union[Schemas, PropertyError]: - from ..properties import property_from_data - - required_set = set() - props = {} - while self.references: - reference = self.references.pop() - source_name = Reference.from_ref(reference.ref).class_name - referenced_prop = components[source_name] - assert isinstance(referenced_prop, oai.Schema) - for p, val in (referenced_prop.properties or {}).items(): - props[p] = (val, source_name) - for sub_prop in referenced_prop.allOf or []: - if isinstance(sub_prop, oai.Reference): - self.references.append(sub_prop) - else: - for p, val in (sub_prop.properties or {}).items(): - props[p] = (val, source_name) - if isinstance(referenced_prop.required, Iterable): - for sub_prop_name in referenced_prop.required: - required_set.add(sub_prop_name) - - for key, (value, source_name) in (props or {}).items(): - required = key in required_set - prop, schemas = property_from_data( - name=key, required=required, data=value, schemas=schemas, parent_name=source_name - ) - if isinstance(prop, PropertyError): - return prop - if required: - self.required_properties.append(prop) - # Remove the optional version - new_optional_props = [op for op in self.optional_properties if op.name != prop.name] - self.optional_properties.clear() - self.optional_properties.extend(new_optional_props) - elif not any(ep for ep in (self.optional_properties + self.required_properties) if ep.name == prop.name): - self.optional_properties.append(prop) - self.relative_imports.update(prop.get_imports(prefix="..")) - - return schemas - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - type_string = self.reference.class_name - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[{type_string}, Unset]" - return type_string + def get_base_type_string(self) -> str: + return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index a94af72ba..651370ae2 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -24,30 +24,48 @@ class Property: required: bool nullable: bool _type_string: ClassVar[str] = "" + _json_type_string: ClassVar[str] = "" # Type of the property after JSON serialization default: Optional[str] = attr.ib() python_name: str = attr.ib(init=False) template: ClassVar[Optional[str]] = None - json_is_dict: ClassVar[bool] = False def __attrs_post_init__(self) -> None: object.__setattr__(self, "python_name", utils.to_valid_python_identifier(utils.snake_case(self.name))) - def get_type_string(self, no_optional: bool = False) -> str: + def get_base_type_string(self) -> str: + return self._type_string + + def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str: """ Get a string representation of type that should be used when declaring this property Args: no_optional: Do not include Optional or Unset even if the value is optional (needed for isinstance checks) + query_parameter: True if the property's type is being used for a query parameter + json: True if the type refers to the property after JSON serialization """ - type_string = self._type_string + if json: + type_string = self._json_type_string + else: + type_string = self.get_base_type_string() + if no_optional: - return self._type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + return type_string + if self.required: + if self.nullable: + return f"Optional[{type_string}]" + else: + return type_string + else: + if self.nullable: + return f"Union[Unset, None, {type_string}]" + else: + if query_parameter: + # For query parameters, None has the same meaning as Unset + return f"Union[Unset, None, {type_string}]" + else: + return f"Union[Unset, {type_string}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" @@ -70,8 +88,13 @@ def get_imports(self, *, prefix: str) -> Set[str]: imports.add(f"from {prefix}types import UNSET, Unset") return imports - def to_string(self) -> str: - """ How this should be declared in a dataclass """ + def to_string(self, query_parameter: bool = False) -> str: + """ + How this should be declared in a dataclass + + Args: + query_parameter: True if the property's type is being used for a query parameter + """ default: Optional[str] if self.default is not None: default = self.default @@ -81,6 +104,6 @@ def to_string(self) -> str: default = None if default is not None: - return f"{self.python_name}: {self.get_type_string()} = {default}" + return f"{self.python_name}: {self.get_type_string(query_parameter=query_parameter)} = {default}" else: - return f"{self.python_name}: {self.get_type_string()}" + return f"{self.python_name}: {self.get_type_string(query_parameter=query_parameter)}" diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 8d3d464c3..7a1862be3 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -17,12 +17,12 @@ if {{ parameter.python_name }} is not UNSET: {% set destination = "json_" + property.python_name %} {% if property.template %} {% from "property_templates/" + property.template import transform %} -{{ transform(property, property.python_name, destination) }} +{{ transform(property, property.python_name, destination, query_parameter=True) }} {% endif %} {% endfor %} params: Dict[str, Any] = { {% for property in endpoint.query_parameters %} - {% if property.required %} + {% if property.required and not property.nullable %} {% if property.template %} "{{ property.name }}": {{ "json_" + property.python_name }}, {% else %} @@ -32,13 +32,12 @@ params: Dict[str, Any] = { {% endfor %} } {% for property in endpoint.query_parameters %} - {% if not property.required %} - {% set property_name = "json_" + property.python_name if property.template else property.python_name %} -if {% if not property.required %}not isinstance({{ property_name }}, Unset) and {% endif %}{{ property_name }} is not None: - {% if property.json_is_dict %} - params.update({{ property_name }}) + {% if not property.required or property.nullable %} +if {% if not property.required %}{{ property.python_name }} is not UNSET and {% endif %}{{ property.python_name }} is not None: + {% if property.template %} + params["{{ property.name }}"] = {{ "json_" + property.python_name }} {% else %} - params["{{ property.name }}"] = {{ property_name }} + params["{{ property.name }}"] = {{ property.python_name }} {% endif %} {% endif %} {% endfor %} @@ -97,7 +96,7 @@ json_body: {{ endpoint.json_body.get_type_string() }}, {% endif %} {# query parameters #} {% for parameter in endpoint.query_parameters %} -{{ parameter.to_string() }}, +{{ parameter.to_string(query_parameter=True) }}, {% endfor %} {% for parameter in endpoint.header_parameters %} {{ parameter.to_string() }}, diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index a3a980c8f..bc2cae912 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -9,13 +9,13 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {{ destination }} = {{ source }}.isoformat() {% if property.nullable %}if {{ source }} else None {%endif%} {% else %} -{{ destination }}{% if declare_type %}: Union[Unset, str]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.isoformat() diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index b8e1b8ff0..91ce0cacc 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -14,7 +14,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None @@ -22,9 +22,9 @@ if _{{ property.python_name }} is not None: {{ destination }} = {{ source }}.isoformat() {% endif %} {% else %} -{{ destination }}{% if declare_type %}: Union[Unset, str]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.isoformat() diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 4765a6fd5..831f633d5 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -9,7 +9,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.value if {{ source }} else None @@ -17,12 +17,12 @@ if _{{ property.python_name }} is not None: {{ destination }} = {{ source }}.value {% endif %} {% else %} -{{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} - {{ destination }} = {{ source }} if {{ source }} else None +{% if property.nullable or query_parameter %} + {{ destination }} = {{ source }}.value if {{ source }} else None {% else %} - {{ destination }} = {{ source }} + {{ destination }} = {{ source }}.value {% endif %} {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/file_property.pyi b/openapi_python_client/templates/property_templates/file_property.pyi index ffa3c20d9..50a331851 100644 --- a/openapi_python_client/templates/property_templates/file_property.pyi +++ b/openapi_python_client/templates/property_templates/file_property.pyi @@ -4,7 +4,7 @@ ) {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None @@ -12,9 +12,9 @@ {{ destination }} = {{ source }}.to_tuple() {% endif %} {% else %} -{{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.to_tuple() diff --git a/openapi_python_client/templates/property_templates/list_property.pyi b/openapi_python_client/templates/property_templates/list_property.pyi index d05a13960..5f58bcd30 100644 --- a/openapi_python_client/templates/property_templates/list_property.pyi +++ b/openapi_python_client/templates/property_templates/list_property.pyi @@ -32,7 +32,7 @@ for {{ inner_source }} in {{ source }}: {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% set inner_property = property.inner_property %} {% if property.required %} {% if property.nullable %} @@ -44,13 +44,13 @@ else: {{ _transform(property, source, destination) }} {% endif %} {% else %} -{{ destination }}{% if declare_type %}: Union[Unset, List[Any]]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} if {{ source }} is None: {{ destination }} = None else: - {{ _transform(property, source, destination) | indent(4)}} + {{ _transform(property, source, destination) | indent(8)}} {% else %} {{ _transform(property, source, destination) | indent(4)}} {% endif %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index b41289409..dfda61d97 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,5 +1,5 @@ {% macro construct(property, source, initial_value=None) %} -{% if property.required and not property.nullable %} +{% if property.required %} {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) {% else %} {% if initial_value != None %} @@ -10,12 +10,12 @@ {{ property.python_name }}: {{ property.get_type_string() }} = UNSET {% endif %} _{{ property.python_name }} = {{source}} -if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{% if property.nullable and not property.required %} and {% endif %}{% if not property.required %}not isinstance(_{{ property.python_name }}, Unset){% endif %}: +if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(cast(Dict[str, Any], _{{ property.python_name }})) {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None @@ -23,9 +23,9 @@ if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{ {{ destination }} = {{ source }}.to_dict() {% endif %} {% else %} -{{ destination }}{% if declare_type %}: Union[{% if property.nullable %}None, {% endif %}Unset, Dict[str, Any]]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.to_dict() diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 4c632c60a..509c7f34e 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -24,20 +24,20 @@ def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string( {{ property.python_name }} = _parse_{{ property.python_name }}({{ source }}) {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} -{% if not property.required %} -{{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} +{% if not property.required or property.nullable %} +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} if isinstance({{ source }}, Unset): {{ destination }} = UNSET {% endif %} -{% if property.nullable %} +{% if property.nullable or (query_parameter and not property.required) %} {% if property.required %} if {{ source }} is None: {% else %}{# There's an if UNSET statement before this #} elif {{ source }} is None: {% endif %} - {{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = None + {{ destination }} = None {% endif %} {% for inner_property in property.inner_properties_with_template() %} {% if loop.first and property.required and not property.nullable %}{# No if UNSET or if None statement before this #} diff --git a/openapi_python_client/templates/types.py b/openapi_python_client/templates/types.py index 2061b9f08..a354a2192 100644 --- a/openapi_python_client/templates/types.py +++ b/openapi_python_client/templates/types.py @@ -11,6 +11,9 @@ def __bool__(self) -> bool: UNSET: Unset = Unset() +# Used as `FileProperty._json_type_string` +FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]] + @attr.s(auto_attribs=True) class File: @@ -20,7 +23,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]: + def to_tuple(self) -> FileJsonType: """ Return a tuple representation that httpx will accept for multipart/form-data """ return self.file_name, self.payload, self.mime_type diff --git a/pyproject.toml b/pyproject.toml index 222b69561..4be8d93db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ safety = "*" pytest-cov = "*" python-multipart = "*" flake8 = "*" +typer-cli = "^0.0.11" [tool.taskipy.tasks] check = """ @@ -55,8 +56,9 @@ isort .\ && flake8 openapi_python_client\ && safety check --bare\ && mypy openapi_python_client\ - && pytest --cov openapi_python_client tests --cov-report=term-missing\ + && task unit\ """ +unit = "pytest --cov openapi_python_client tests --cov-report=term-missing" regen = "python -m end_to_end_tests.regen_golden_record" regen_custom = "python -m end_to_end_tests.regen_golden_record custom" e2e = "pytest openapi_python_client end_to_end_tests/test_end_to_end.py" @@ -65,12 +67,7 @@ task regen\ && task regen_custom\ && task e2e\ """ -gen-setuppy = """ -poetry build \ -&& tar --strip-components=1 -xvf "$(ls -1 dist/*tar.gz | tail -1)" '*/setup.py' \ -&& isort setup.py \ -&& black setup.py -""" +docs = "typer openapi_python_client/cli.py utils docs > usage.md" [tool.black] line-length = 120 @@ -98,8 +95,5 @@ skip = [".venv", "tests/test_templates"] omit = ["openapi_python_client/templates/*"] [build-system] -requires = [ - "setuptools>=30.3.0,<50", - "poetry>=1.0" -] +requires = ["poetry>=1.0"] build-backend = "poetry.masonry.api" diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 2f3c13676..2f1c71cc5 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -16,45 +16,55 @@ class TestProperty: - def test_get_type_string(self, mocker): + @pytest.mark.parametrize( + "query_parameter,nullable,required,no_optional,expected", + [ + (False, False, False, False, "Union[Unset, TestType]"), + (False, False, False, True, "TestType"), + (False, False, True, False, "TestType"), + (False, False, True, True, "TestType"), + (False, True, False, False, "Union[Unset, None, TestType]"), + (False, True, False, True, "TestType"), + (False, True, True, False, "Optional[TestType]"), + (False, True, True, True, "TestType"), + (True, False, False, False, "Union[Unset, None, TestType]"), + (True, False, False, True, "TestType"), + (True, False, True, False, "TestType"), + (True, False, True, True, "TestType"), + (True, True, False, False, "Union[Unset, None, TestType]"), + (True, True, False, True, "TestType"), + (True, True, True, False, "Optional[TestType]"), + (True, True, True, True, "TestType"), + ], + ) + def test_get_type_string(self, mocker, query_parameter, nullable, required, no_optional, expected): from openapi_python_client.parser.properties import Property mocker.patch.object(Property, "_type_string", "TestType") - p = Property(name="test", required=True, default=None, nullable=False) - - base_type_string = f"TestType" - - assert p.get_type_string() == base_type_string + p = Property(name="test", required=required, default=None, nullable=nullable) + assert p.get_type_string(no_optional=no_optional, query_parameter=query_parameter) == expected - p = Property(name="test", required=True, default=None, nullable=True) - assert p.get_type_string() == f"Optional[{base_type_string}]" - assert p.get_type_string(no_optional=True) == base_type_string - - p = Property(name="test", required=False, default=None, nullable=True) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" - assert p.get_type_string(no_optional=True) == base_type_string - - p = Property(name="test", required=False, default=None, nullable=False) - assert p.get_type_string() == f"Union[Unset, {base_type_string}]" - assert p.get_type_string(no_optional=True) == base_type_string - - def test_to_string(self, mocker): + @pytest.mark.parametrize( + "query_parameter,default,required,expected", + [ + (False, None, False, "test: Union[Unset, TestType] = UNSET"), + (False, None, True, "test: TestType"), + (False, "Test", False, "test: Union[Unset, TestType] = Test"), + (False, "Test", True, "test: TestType = Test"), + (True, None, False, "test: Union[Unset, None, TestType] = UNSET"), + (True, None, True, "test: TestType"), + (True, "Test", False, "test: Union[Unset, None, TestType] = Test"), + (True, "Test", True, "test: TestType = Test"), + ], + ) + def test_to_string(self, mocker, query_parameter, default, required, expected): from openapi_python_client.parser.properties import Property name = "test" - get_type_string = mocker.patch.object(Property, "get_type_string") - p = Property(name=name, required=True, default=None, nullable=False) - - assert p.to_string() == f"{name}: {get_type_string()}" - - p = Property(name=name, required=False, default=None, nullable=False) - assert p.to_string() == f"{name}: {get_type_string()} = UNSET" - - p = Property(name=name, required=True, default=None, nullable=False) - assert p.to_string() == f"{name}: {get_type_string()}" + mocker.patch.object(Property, "_type_string", "TestType") + p = Property(name=name, required=required, default=default, nullable=False) - p = Property(name=name, required=True, default="TEST", nullable=False) - assert p.to_string() == f"{name}: {get_type_string()} = TEST" + assert p.to_string(query_parameter=query_parameter) == expected def test_get_imports(self): from openapi_python_client.parser.properties import Property @@ -87,7 +97,7 @@ def test_get_type_string(self): assert p.get_type_string() == f"Optional[{base_type_string}]" p = StringProperty(name="test", required=False, default=None, nullable=True) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" + assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" p = StringProperty(name="test", required=False, default=None, nullable=False) assert p.get_type_string() == f"Union[Unset, {base_type_string}]" @@ -202,7 +212,7 @@ def test_get_type_string(self, mocker): assert p.get_type_string(no_optional=True) == base_type_string p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" + assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False) @@ -242,7 +252,28 @@ def test_get_type_imports(self, mocker): class TestUnionProperty: - def test_get_type_string(self, mocker): + @pytest.mark.parametrize( + "query_parameter,nullable,required,no_optional,expected", + [ + (False, False, False, False, "Union[Unset, inner_type_string_1, inner_type_string_2]"), + (False, False, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, False, True, False, "Union[inner_type_string_1, inner_type_string_2]"), + (False, False, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), + (False, True, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2]"), + (False, True, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, False, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), + (True, False, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, False, True, False, "Union[inner_type_string_1, inner_type_string_2]"), + (True, False, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), + (True, True, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2]"), + (True, True, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + ], + ) + def test_get_type_string(self, mocker, query_parameter, nullable, required, no_optional, expected): from openapi_python_client.parser.properties import UnionProperty inner_property_1 = mocker.MagicMock() @@ -251,46 +282,13 @@ def test_get_type_string(self, mocker): inner_property_2.get_type_string.return_value = "inner_type_string_2" p = UnionProperty( name="test", - required=True, - default=None, - inner_properties=[inner_property_1, inner_property_2], - nullable=False, - ) - - base_type_string = f"Union[inner_type_string_1, inner_type_string_2]" - - assert p.get_type_string() == base_type_string - - p = UnionProperty( - name="test", - required=True, - default=None, - inner_properties=[inner_property_1, inner_property_2], - nullable=True, - ) - assert p.get_type_string() == f"Optional[{base_type_string}]" - assert p.get_type_string(no_optional=True) == base_type_string - - base_type_string_with_unset = f"Union[Unset, inner_type_string_1, inner_type_string_2]" - p = UnionProperty( - name="test", - required=False, + required=required, default=None, inner_properties=[inner_property_1, inner_property_2], - nullable=True, + nullable=nullable, ) - assert p.get_type_string() == f"Optional[{base_type_string_with_unset}]" - assert p.get_type_string(no_optional=True) == base_type_string - p = UnionProperty( - name="test", - required=False, - default=None, - inner_properties=[inner_property_1, inner_property_2], - nullable=False, - ) - assert p.get_type_string() == base_type_string_with_unset - assert p.get_type_string(no_optional=True) == base_type_string + assert p.get_type_string(query_parameter=query_parameter, no_optional=no_optional) == expected def test_get_imports(self, mocker): from openapi_python_client.parser.properties import UnionProperty @@ -389,7 +387,7 @@ def test_get_type_string(self, mocker): reference=fake_reference, value_type=str, ) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" + assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string p = properties.EnumProperty( @@ -586,7 +584,6 @@ def test_property_from_data_ref_model(self): nullable=False, default=None, reference=Reference(class_name=class_name, module_name="my_model"), - references=[], required_properties=[], optional_properties=[], description="", @@ -603,7 +600,6 @@ def test_property_from_data_ref_model(self): nullable=False, default=None, reference=Reference(class_name=class_name, module_name="my_model"), - references=[], required_properties=[], optional_properties=[], description="", @@ -990,25 +986,19 @@ def test__string_based_property_unsupported_format(self, mocker): def test_build_schemas(mocker): build_model_property = mocker.patch(f"{MODULE_NAME}.build_model_property") in_data = {"1": mocker.MagicMock(enum=None), "2": mocker.MagicMock(enum=None), "3": mocker.MagicMock(enum=None)} - model_1 = mocker.MagicMock() schemas_1 = mocker.MagicMock() model_2 = mocker.MagicMock() schemas_2 = mocker.MagicMock(errors=[]) - schemas_2.models = {"1": model_1, "2": model_2} - error_1 = PropertyError() + error = PropertyError() schemas_3 = mocker.MagicMock() - schemas_4 = mocker.MagicMock(errors=[]) - model_1.resolve_references.return_value = schemas_4 - error_2 = PropertyError() - model_2.resolve_references.return_value = error_2 # This loops through one for each, then again to retry the error build_model_property.side_effect = [ (model_1, schemas_1), (model_2, schemas_2), - (error_1, schemas_3), - (error_1, schemas_3), + (error, schemas_3), + (error, schemas_3), ] from openapi_python_client.parser.properties import Schemas, build_schemas @@ -1024,12 +1014,8 @@ def test_build_schemas(mocker): ] ) # schemas_3 was the last to come back from build_model_property, but it should be ignored because it's an error - model_1.resolve_references.assert_called_once_with(components=in_data, schemas=schemas_2) - # schemas_4 came from resolving model_1 - model_2.resolve_references.assert_called_once_with(components=in_data, schemas=schemas_4) - # resolving model_2 resulted in err, so no schemas_5 - assert result == schemas_4 - assert result.errors == [error_1, error_2] + assert result == schemas_2 + assert result.errors == [error] def test_build_parse_error_on_reference(): @@ -1103,7 +1089,6 @@ def test_build_model_property(additional_properties_schema, expected_additional_ nullable=False, default=None, reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), - references=[], required_properties=[StringProperty(name="req", required=True, nullable=False, default=None)], optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None)], description=data.description, diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 421f40d48..410112666 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -4,9 +4,9 @@ @pytest.mark.parametrize( "no_optional,nullable,required,expected", [ - (False, False, False, "Union[MyClass, Unset]"), + (False, False, False, "Union[Unset, MyClass]"), (False, False, True, "MyClass"), - (False, True, False, "Union[Optional[MyClass], Unset]"), + (False, True, False, "Union[Unset, None, MyClass]"), (False, True, True, "Optional[MyClass]"), (True, False, False, "MyClass"), (True, False, True, "MyClass"), @@ -23,7 +23,6 @@ def test_get_type_string(no_optional, nullable, required, expected): nullable=nullable, default=None, reference=Reference(class_name="MyClass", module_name="my_module"), - references=[], description="", optional_properties=[], required_properties=[], @@ -43,7 +42,6 @@ def test_get_imports(): nullable=True, default=None, reference=Reference(class_name="MyClass", module_name="my_module"), - references=[], description="", optional_properties=[], required_properties=[], @@ -59,143 +57,3 @@ def test_get_imports(): "from typing import Dict", "from typing import cast", } - - -def test_resolve_references(mocker): - import openapi_python_client.schema as oai - from openapi_python_client.parser.properties import build_model_property - - schemas = { - "RefA": oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - required=["String"], - properties={ - "String": oai.Schema.construct(type="string"), - "Enum": oai.Schema.construct(type="string", enum=["aValue"]), - "DateTime": oai.Schema.construct(type="string", format="date-time"), - }, - ), - "RefB": oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - required=["DateTime"], - properties={ - "Int": oai.Schema.construct(type="integer"), - "DateTime": oai.Schema.construct(type="string", format="date-time"), - "Float": oai.Schema.construct(type="number", format="float"), - }, - ), - # Intentionally no properties defined - "RefC": oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - ), - } - - model_schema = oai.Schema.construct( - allOf=[ - oai.Reference.construct(ref="#/components/schemas/RefA"), - oai.Reference.construct(ref="#/components/schemas/RefB"), - oai.Reference.construct(ref="#/components/schemas/RefC"), - oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - required=["Float"], - properties={ - "String": oai.Schema.construct(type="string"), - "Float": oai.Schema.construct(type="number", format="float"), - }, - ), - ] - ) - - components = {**schemas, "Model": model_schema} - - from openapi_python_client.parser.properties import Schemas - - schemas_holder = Schemas() - model, schemas_holder = build_model_property( - data=model_schema, name="Model", required=True, schemas=schemas_holder, parent_name=None - ) - model.resolve_references(components, schemas_holder) - assert sorted(p.name for p in model.required_properties) == ["DateTime", "Float", "String"] - assert all(p.required for p in model.required_properties) - assert sorted(p.name for p in model.optional_properties) == ["Enum", "Int"] - assert all(not p.required for p in model.optional_properties) - - -def test_resolve_references_nested_allof(mocker): - import openapi_python_client.schema as oai - from openapi_python_client.parser.properties import build_model_property - - schemas = { - "RefA": oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - required=["String"], - properties={ - "String": oai.Schema.construct(type="string"), - "Enum": oai.Schema.construct(type="string", enum=["aValue"]), - "DateTime": oai.Schema.construct(type="string", format="date-time"), - }, - ), - "RefB": oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - required=["DateTime"], - properties={ - "Int": oai.Schema.construct(type="integer"), - "DateTime": oai.Schema.construct(type="string", format="date-time"), - "Float": oai.Schema.construct(type="number", format="float"), - }, - ), - # Intentionally no properties defined - "RefC": oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - ), - } - - model_schema = oai.Schema.construct( - type="object", - properties={ - "Key": oai.Schema.construct( - allOf=[ - oai.Reference.construct(ref="#/components/schemas/RefA"), - oai.Reference.construct(ref="#/components/schemas/RefB"), - oai.Reference.construct(ref="#/components/schemas/RefC"), - oai.Schema.construct( - title=mocker.MagicMock(), - description=mocker.MagicMock(), - required=["Float"], - properties={ - "String": oai.Schema.construct(type="string"), - "Float": oai.Schema.construct(type="number", format="float"), - }, - ), - ] - ), - }, - ) - - components = {**schemas, "Model": model_schema} - - from openapi_python_client.parser.properties import ModelProperty, Schemas - - schemas_holder = Schemas() - model, schemas_holder = build_model_property( - data=model_schema, name="Model", required=True, schemas=schemas_holder, parent_name=None - ) - model.resolve_references(components, schemas_holder) - assert sorted(p.name for p in model.required_properties) == [] - assert sorted(p.name for p in model.optional_properties) == ["Key"] - assert all(not p.required for p in model.optional_properties) - - key_property = model.optional_properties[0] - assert isinstance(key_property, ModelProperty) - key_property.resolve_references(components, schemas_holder) - assert sorted(p.name for p in key_property.required_properties) == ["DateTime", "Float", "String"] - assert all(p.required for p in key_property.required_properties) - assert sorted(p.name for p in key_property.optional_properties) == ["Enum", "Int"] - assert all(not p.required for p in key_property.optional_properties) diff --git a/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py b/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py index cf8780024..be32cfbd3 100644 --- a/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py +++ b/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py @@ -6,7 +6,7 @@ some_source = date(2020, 10, 12) -some_destination: Union[Unset, str] = UNSET +some_destination: Union[Unset, None, str] = UNSET if not isinstance(some_source, Unset): some_destination = some_source.isoformat() if some_source else None From a5d09f412a7520040efd763bb3d3c4b08f0d9975 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 18:11:39 -0500 Subject: [PATCH 08/50] Regenerate tests --- .../api/tests/defaults_tests_defaults_post.py | 114 +++++---- ...tional_value_tests_optional_query_param.py | 11 +- .../custom_e2e/models/__init__.py | 4 - .../custom_e2e/models/a_model.py | 52 +--- .../custom_e2e/models/a_model_model.py | 85 ------- .../models/a_model_not_required_model.py | 85 ------- .../a_model_not_required_nullable_model.py | 85 ------- .../models/a_model_nullable_model.py | 85 ------- ...el_with_primitive_additional_properties.py | 6 +- .../models/model_with_union_property.py | 6 +- .../golden-record-custom/custom_e2e/types.py | 5 +- .../api/tests/defaults_tests_defaults_post.py | 232 ++++++++++-------- ...tional_value_tests_optional_query_param.py | 19 +- .../my_test_api_client/models/__init__.py | 4 - .../my_test_api_client/models/a_model.py | 52 +--- .../models/a_model_model.py | 85 ------- .../models/a_model_not_required_model.py | 85 ------- .../a_model_not_required_nullable_model.py | 85 ------- .../models/a_model_nullable_model.py | 85 ------- ...el_with_primitive_additional_properties.py | 6 +- .../models/model_with_union_property.py | 6 +- .../golden-record/my_test_api_client/types.py | 5 +- 22 files changed, 243 insertions(+), 959 deletions(-) delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index f87ad3e1b..4a2c9074b 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -7,13 +7,12 @@ Client = httpx.Client import datetime -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union from dateutil.parser import isoparse from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError -from ...models.model_with_union_property import ModelWithUnionProperty from ...types import UNSET, Unset @@ -41,83 +40,106 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def httpx_request( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: - json_datetime_prop: Union[Unset, str] = UNSET - if not isinstance(datetime_prop, Unset): - json_datetime_prop = datetime_prop.isoformat() + json_not_required_not_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_not_nullable_datetime_prop, Unset): + json_not_required_not_nullable_datetime_prop = ( + not_required_not_nullable_datetime_prop.isoformat() if not_required_not_nullable_datetime_prop else None + ) - json_date_prop: Union[Unset, str] = UNSET + json_not_required_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_nullable_datetime_prop, Unset): + json_not_required_nullable_datetime_prop = ( + not_required_nullable_datetime_prop.isoformat() if not_required_nullable_datetime_prop else None + ) + + json_required_not_nullable_datetime_prop = required_not_nullable_datetime_prop.isoformat() + + json_required_nullable_datetime_prop = ( + required_nullable_datetime_prop.isoformat() if required_nullable_datetime_prop else None + ) + + json_date_prop: Union[Unset, None, str] = UNSET if not isinstance(date_prop, Unset): - json_date_prop = date_prop.isoformat() + json_date_prop = date_prop.isoformat() if date_prop else None - json_list_prop: Union[Unset, List[Any]] = UNSET + json_list_prop: Union[Unset, None, List[Any]] = UNSET if not isinstance(list_prop, Unset): - json_list_prop = [] - for list_prop_item_data in list_prop: - list_prop_item = list_prop_item_data.value + if list_prop is None: + json_list_prop = None + else: + json_list_prop = [] + for list_prop_item_data in list_prop: + list_prop_item = list_prop_item_data.value - json_list_prop.append(list_prop_item) + json_list_prop.append(list_prop_item) - json_union_prop: Union[Unset, float, str] + json_union_prop: Union[Unset, None, float, str] if isinstance(union_prop, Unset): json_union_prop = UNSET + elif union_prop is None: + json_union_prop = None else: json_union_prop = union_prop - json_union_prop_with_ref: Union[Unset, float, AnEnum] + json_union_prop_with_ref: Union[Unset, None, float, int] if isinstance(union_prop_with_ref, Unset): json_union_prop_with_ref = UNSET + elif union_prop_with_ref is None: + json_union_prop_with_ref = None elif isinstance(union_prop_with_ref, AnEnum): json_union_prop_with_ref = UNSET if not isinstance(union_prop_with_ref, Unset): - json_union_prop_with_ref = union_prop_with_ref + json_union_prop_with_ref = union_prop_with_ref.value else: json_union_prop_with_ref = union_prop_with_ref - json_enum_prop: Union[Unset, AnEnum] = UNSET + json_enum_prop: Union[Unset, None, int] = UNSET if not isinstance(enum_prop, Unset): - json_enum_prop = enum_prop - - json_model_prop: Union[Unset, Dict[str, Any]] = UNSET - if not isinstance(model_prop, Unset): - json_model_prop = model_prop.to_dict() + json_enum_prop = enum_prop.value if enum_prop else None - params: Dict[str, Any] = {} - if not isinstance(string_prop, Unset) and string_prop is not None: + params: Dict[str, Any] = { + "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, + } + if string_prop is not UNSET and string_prop is not None: params["string_prop"] = string_prop - if not isinstance(json_datetime_prop, Unset) and json_datetime_prop is not None: - params["datetime_prop"] = json_datetime_prop - if not isinstance(json_date_prop, Unset) and json_date_prop is not None: + if not_required_not_nullable_datetime_prop is not UNSET and not_required_not_nullable_datetime_prop is not None: + params["not_required_not_nullable_datetime_prop"] = json_not_required_not_nullable_datetime_prop + if not_required_nullable_datetime_prop is not UNSET and not_required_nullable_datetime_prop is not None: + params["not_required_nullable_datetime_prop"] = json_not_required_nullable_datetime_prop + if required_nullable_datetime_prop is not None: + params["required_nullable_datetime_prop"] = json_required_nullable_datetime_prop + if date_prop is not UNSET and date_prop is not None: params["date_prop"] = json_date_prop - if not isinstance(float_prop, Unset) and float_prop is not None: + if float_prop is not UNSET and float_prop is not None: params["float_prop"] = float_prop - if not isinstance(int_prop, Unset) and int_prop is not None: + if int_prop is not UNSET and int_prop is not None: params["int_prop"] = int_prop - if not isinstance(boolean_prop, Unset) and boolean_prop is not None: + if boolean_prop is not UNSET and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if not isinstance(json_list_prop, Unset) and json_list_prop is not None: + if list_prop is not UNSET and list_prop is not None: params["list_prop"] = json_list_prop - if not isinstance(json_union_prop, Unset) and json_union_prop is not None: + if union_prop is not UNSET and union_prop is not None: params["union_prop"] = json_union_prop - if not isinstance(json_union_prop_with_ref, Unset) and json_union_prop_with_ref is not None: + if union_prop_with_ref is not UNSET and union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if not isinstance(json_enum_prop, Unset) and json_enum_prop is not None: + if enum_prop is not UNSET and enum_prop is not None: params["enum_prop"] = json_enum_prop - if not isinstance(json_model_prop, Unset) and json_model_prop is not None: - params.update(json_model_prop) response = client.request( "post", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index 616dc4252..8ff5a52a3 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -36,15 +36,18 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def httpx_request( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: - json_query_param: Union[Unset, List[Any]] = UNSET + json_query_param: Union[Unset, None, List[Any]] = UNSET if not isinstance(query_param, Unset): - json_query_param = query_param + if query_param is None: + json_query_param = None + else: + json_query_param = query_param params: Dict[str, Any] = {} - if not isinstance(json_query_param, Unset) and json_query_param is not None: + if query_param is not UNSET and query_param is not None: params["query_param"] = json_query_param response = client.request( diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py index 6f5ac7423..d3ca924b3 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py @@ -1,10 +1,6 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel -from .a_model_model import AModelModel -from .a_model_not_required_model import AModelNotRequiredModel -from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 15a7cc68c..f811d4712 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -4,10 +4,6 @@ import attr from dateutil.parser import isoparse -from ..models.a_model_model import AModelModel -from ..models.a_model_not_required_model import AModelNotRequiredModel -from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..types import UNSET, Unset @@ -21,16 +17,12 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str - model: AModelModel a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] - nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET - not_required_nullable: Union[Unset, Optional[str]] = UNSET + not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET - not_required_nullable_model: Union[Optional[AModelNotRequiredNullableModel], Unset] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -43,8 +35,6 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable - model = self.model.to_dict() - nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -62,17 +52,6 @@ def to_dict(self) -> Dict[str, Any]: required_nullable = self.required_nullable not_required_nullable = self.not_required_nullable not_required_not_nullable = self.not_required_not_nullable - nullable_model = self.nullable_model.to_dict() if self.nullable_model else None - - not_required_model: Union[Unset, Dict[str, Any]] = UNSET - if not isinstance(self.not_required_model, Unset): - not_required_model = self.not_required_model.to_dict() - - not_required_nullable_model: Union[None, Unset, Dict[str, Any]] = UNSET - if not isinstance(self.not_required_nullable_model, Unset): - not_required_nullable_model = ( - self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None - ) field_dict: Dict[str, Any] = {} field_dict.update( @@ -81,10 +60,8 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, - "model": model, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, - "nullable_model": nullable_model, } ) if nested_list_of_enums is not UNSET: @@ -95,10 +72,6 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_nullable"] = not_required_nullable if not_required_not_nullable is not UNSET: field_dict["not_required_not_nullable"] = not_required_not_nullable - if not_required_model is not UNSET: - field_dict["not_required_model"] = not_required_model - if not_required_nullable_model is not UNSET: - field_dict["not_required_nullable_model"] = not_required_nullable_model return field_dict @@ -126,8 +99,6 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat required_not_nullable = d.pop("required_not_nullable") - model = AModelModel.from_dict(d.pop("model")) - nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -153,38 +124,17 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) - nullable_model = None - _nullable_model = d.pop("nullable_model") - if _nullable_model is not None: - nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) - - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET - _not_required_model = d.pop("not_required_model", UNSET) - if not isinstance(_not_required_model, Unset): - not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) - - not_required_nullable_model = None - _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) - if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( - cast(Dict[str, Any], _not_required_nullable_model) - ) - a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, - model=model, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, required_nullable=required_nullable, not_required_nullable=not_required_nullable, not_required_not_nullable=not_required_not_nullable, - nullable_model=nullable_model, - not_required_model=not_required_model, - not_required_nullable_model=not_required_nullable_model, ) return a_model diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py deleted file mode 100644 index c1a00c152..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_model = AModelModel( - a_property=a_property, - ) - - a_model_model.additional_properties = d - return a_model_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py deleted file mode 100644 index adecb4225..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_model = AModelNotRequiredModel( - a_property=a_property, - ) - - a_model_not_required_model.additional_properties = d - return a_model_not_required_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py deleted file mode 100644 index 9de2e3798..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_nullable_model = AModelNotRequiredNullableModel( - a_property=a_property, - ) - - a_model_not_required_nullable_model.additional_properties = d - return a_model_not_required_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py deleted file mode 100644 index cbcf120f8..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_nullable_model = AModelNullableModel( - a_property=a_property, - ) - - a_model_nullable_model.additional_properties = d - return a_model_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 797c1ce31..feb30878d 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -12,7 +12,7 @@ class ModelWithPrimitiveAdditionalProperties: """ """ - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -31,9 +31,9 @@ def to_dict(self) -> Dict[str, Any]: @staticmethod def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if not isinstance(_a_date_holder, Unset): + if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( cast(Dict[str, Any], _a_date_holder) ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index cbecc7c90..35bc2a853 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -14,18 +14,18 @@ class ModelWithUnionProperty: a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update({}) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/types.py b/end_to_end_tests/golden-record-custom/custom_e2e/types.py index 2061b9f08..a354a2192 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/types.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/types.py @@ -11,6 +11,9 @@ def __bool__(self) -> bool: UNSET: Unset = Unset() +# Used as `FileProperty._json_type_string` +FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]] + @attr.s(auto_attribs=True) class File: @@ -20,7 +23,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]: + def to_tuple(self) -> FileJsonType: """ Return a tuple representation that httpx will accept for multipart/form-data """ return self.file_name, self.payload, self.mime_type diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index ff6ef2409..1f865570d 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -7,93 +7,115 @@ from ...client import Client from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError -from ...models.model_with_union_property import ModelWithUnionProperty from ...types import UNSET, Response, Unset def _get_kwargs( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, ) -> Dict[str, Any]: url = "{}/tests/defaults".format(client.base_url) headers: Dict[str, Any] = client.get_headers() - json_datetime_prop: Union[Unset, str] = UNSET - if not isinstance(datetime_prop, Unset): - json_datetime_prop = datetime_prop.isoformat() + json_not_required_not_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_not_nullable_datetime_prop, Unset): + json_not_required_not_nullable_datetime_prop = ( + not_required_not_nullable_datetime_prop.isoformat() if not_required_not_nullable_datetime_prop else None + ) + + json_not_required_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_nullable_datetime_prop, Unset): + json_not_required_nullable_datetime_prop = ( + not_required_nullable_datetime_prop.isoformat() if not_required_nullable_datetime_prop else None + ) + + json_required_not_nullable_datetime_prop = required_not_nullable_datetime_prop.isoformat() - json_date_prop: Union[Unset, str] = UNSET + json_required_nullable_datetime_prop = ( + required_nullable_datetime_prop.isoformat() if required_nullable_datetime_prop else None + ) + + json_date_prop: Union[Unset, None, str] = UNSET if not isinstance(date_prop, Unset): - json_date_prop = date_prop.isoformat() + json_date_prop = date_prop.isoformat() if date_prop else None - json_list_prop: Union[Unset, List[Any]] = UNSET + json_list_prop: Union[Unset, None, List[Any]] = UNSET if not isinstance(list_prop, Unset): - json_list_prop = [] - for list_prop_item_data in list_prop: - list_prop_item = list_prop_item_data.value + if list_prop is None: + json_list_prop = None + else: + json_list_prop = [] + for list_prop_item_data in list_prop: + list_prop_item = list_prop_item_data.value - json_list_prop.append(list_prop_item) + json_list_prop.append(list_prop_item) - json_union_prop: Union[Unset, float, str] + json_union_prop: Union[Unset, None, float, str] if isinstance(union_prop, Unset): json_union_prop = UNSET + elif union_prop is None: + json_union_prop = None else: json_union_prop = union_prop - json_union_prop_with_ref: Union[Unset, float, AnEnum] + json_union_prop_with_ref: Union[Unset, None, float, int] if isinstance(union_prop_with_ref, Unset): json_union_prop_with_ref = UNSET + elif union_prop_with_ref is None: + json_union_prop_with_ref = None elif isinstance(union_prop_with_ref, AnEnum): json_union_prop_with_ref = UNSET if not isinstance(union_prop_with_ref, Unset): - json_union_prop_with_ref = union_prop_with_ref + json_union_prop_with_ref = union_prop_with_ref.value else: json_union_prop_with_ref = union_prop_with_ref - json_enum_prop: Union[Unset, AnEnum] = UNSET + json_enum_prop: Union[Unset, None, int] = UNSET if not isinstance(enum_prop, Unset): - json_enum_prop = enum_prop + json_enum_prop = enum_prop.value if enum_prop else None - json_model_prop: Union[Unset, Dict[str, Any]] = UNSET - if not isinstance(model_prop, Unset): - json_model_prop = model_prop.to_dict() - - params: Dict[str, Any] = {} - if not isinstance(string_prop, Unset) and string_prop is not None: + params: Dict[str, Any] = { + "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, + } + if string_prop is not UNSET and string_prop is not None: params["string_prop"] = string_prop - if not isinstance(json_datetime_prop, Unset) and json_datetime_prop is not None: - params["datetime_prop"] = json_datetime_prop - if not isinstance(json_date_prop, Unset) and json_date_prop is not None: + if not_required_not_nullable_datetime_prop is not UNSET and not_required_not_nullable_datetime_prop is not None: + params["not_required_not_nullable_datetime_prop"] = json_not_required_not_nullable_datetime_prop + if not_required_nullable_datetime_prop is not UNSET and not_required_nullable_datetime_prop is not None: + params["not_required_nullable_datetime_prop"] = json_not_required_nullable_datetime_prop + if required_nullable_datetime_prop is not None: + params["required_nullable_datetime_prop"] = json_required_nullable_datetime_prop + if date_prop is not UNSET and date_prop is not None: params["date_prop"] = json_date_prop - if not isinstance(float_prop, Unset) and float_prop is not None: + if float_prop is not UNSET and float_prop is not None: params["float_prop"] = float_prop - if not isinstance(int_prop, Unset) and int_prop is not None: + if int_prop is not UNSET and int_prop is not None: params["int_prop"] = int_prop - if not isinstance(boolean_prop, Unset) and boolean_prop is not None: + if boolean_prop is not UNSET and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if not isinstance(json_list_prop, Unset) and json_list_prop is not None: + if list_prop is not UNSET and list_prop is not None: params["list_prop"] = json_list_prop - if not isinstance(json_union_prop, Unset) and json_union_prop is not None: + if union_prop is not UNSET and union_prop is not None: params["union_prop"] = json_union_prop - if not isinstance(json_union_prop_with_ref, Unset) and json_union_prop_with_ref is not None: + if union_prop_with_ref is not UNSET and union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if not isinstance(json_enum_prop, Unset) and json_enum_prop is not None: + if enum_prop is not UNSET and enum_prop is not None: params["enum_prop"] = json_enum_prop - if not isinstance(json_model_prop, Unset) and json_model_prop is not None: - params.update(json_model_prop) return { "url": url, @@ -128,22 +150,27 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def sync_detailed( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -152,7 +179,6 @@ def sync_detailed( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, - model_prop=model_prop, ) response = httpx.post( @@ -165,24 +191,29 @@ def sync_detailed( def sync( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ return sync_detailed( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -191,29 +222,33 @@ def sync( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, - model_prop=model_prop, ).parsed async def asyncio_detailed( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -222,7 +257,6 @@ async def asyncio_detailed( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, - model_prop=model_prop, ) async with httpx.AsyncClient() as _client: @@ -234,17 +268,19 @@ async def asyncio_detailed( async def asyncio( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -252,7 +288,10 @@ async def asyncio( await asyncio_detailed( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -261,6 +300,5 @@ async def asyncio( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, - model_prop=model_prop, ) ).parsed diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 576a770fe..2c14c2949 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -10,18 +10,21 @@ def _get_kwargs( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Dict[str, Any]: url = "{}/tests/optional_query_param/".format(client.base_url) headers: Dict[str, Any] = client.get_headers() - json_query_param: Union[Unset, List[Any]] = UNSET + json_query_param: Union[Unset, None, List[Any]] = UNSET if not isinstance(query_param, Unset): - json_query_param = query_param + if query_param is None: + json_query_param = None + else: + json_query_param = query_param params: Dict[str, Any] = {} - if not isinstance(json_query_param, Unset) and json_query_param is not None: + if query_param is not UNSET and query_param is not None: params["query_param"] = json_query_param return { @@ -57,7 +60,7 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def sync_detailed( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -74,7 +77,7 @@ def sync_detailed( def sync( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ Test optional query parameters """ @@ -87,7 +90,7 @@ def sync( async def asyncio_detailed( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -103,7 +106,7 @@ async def asyncio_detailed( async def asyncio( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ Test optional query parameters """ diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index 6f5ac7423..d3ca924b3 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,10 +1,6 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel -from .a_model_model import AModelModel -from .a_model_not_required_model import AModelNotRequiredModel -from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 15a7cc68c..f811d4712 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -4,10 +4,6 @@ import attr from dateutil.parser import isoparse -from ..models.a_model_model import AModelModel -from ..models.a_model_not_required_model import AModelNotRequiredModel -from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..types import UNSET, Unset @@ -21,16 +17,12 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str - model: AModelModel a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] - nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET - not_required_nullable: Union[Unset, Optional[str]] = UNSET + not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET - not_required_nullable_model: Union[Optional[AModelNotRequiredNullableModel], Unset] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -43,8 +35,6 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable - model = self.model.to_dict() - nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -62,17 +52,6 @@ def to_dict(self) -> Dict[str, Any]: required_nullable = self.required_nullable not_required_nullable = self.not_required_nullable not_required_not_nullable = self.not_required_not_nullable - nullable_model = self.nullable_model.to_dict() if self.nullable_model else None - - not_required_model: Union[Unset, Dict[str, Any]] = UNSET - if not isinstance(self.not_required_model, Unset): - not_required_model = self.not_required_model.to_dict() - - not_required_nullable_model: Union[None, Unset, Dict[str, Any]] = UNSET - if not isinstance(self.not_required_nullable_model, Unset): - not_required_nullable_model = ( - self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None - ) field_dict: Dict[str, Any] = {} field_dict.update( @@ -81,10 +60,8 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, - "model": model, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, - "nullable_model": nullable_model, } ) if nested_list_of_enums is not UNSET: @@ -95,10 +72,6 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_nullable"] = not_required_nullable if not_required_not_nullable is not UNSET: field_dict["not_required_not_nullable"] = not_required_not_nullable - if not_required_model is not UNSET: - field_dict["not_required_model"] = not_required_model - if not_required_nullable_model is not UNSET: - field_dict["not_required_nullable_model"] = not_required_nullable_model return field_dict @@ -126,8 +99,6 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat required_not_nullable = d.pop("required_not_nullable") - model = AModelModel.from_dict(d.pop("model")) - nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -153,38 +124,17 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) - nullable_model = None - _nullable_model = d.pop("nullable_model") - if _nullable_model is not None: - nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) - - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET - _not_required_model = d.pop("not_required_model", UNSET) - if not isinstance(_not_required_model, Unset): - not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) - - not_required_nullable_model = None - _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) - if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( - cast(Dict[str, Any], _not_required_nullable_model) - ) - a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, - model=model, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, required_nullable=required_nullable, not_required_nullable=not_required_nullable, not_required_not_nullable=not_required_not_nullable, - nullable_model=nullable_model, - not_required_model=not_required_model, - not_required_nullable_model=not_required_nullable_model, ) return a_model diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py deleted file mode 100644 index c1a00c152..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_model = AModelModel( - a_property=a_property, - ) - - a_model_model.additional_properties = d - return a_model_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py deleted file mode 100644 index adecb4225..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_model = AModelNotRequiredModel( - a_property=a_property, - ) - - a_model_not_required_model.additional_properties = d - return a_model_not_required_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py deleted file mode 100644 index 9de2e3798..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_nullable_model = AModelNotRequiredNullableModel( - a_property=a_property, - ) - - a_model_not_required_nullable_model.additional_properties = d - return a_model_not_required_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py deleted file mode 100644 index cbcf120f8..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ /dev/null @@ -1,85 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data - a_property: Union[Unset, AnEnum, AnIntEnum] - try: - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_nullable_model = AModelNullableModel( - a_property=a_property, - ) - - a_model_nullable_model.additional_properties = d - return a_model_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 797c1ce31..feb30878d 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -12,7 +12,7 @@ class ModelWithPrimitiveAdditionalProperties: """ """ - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -31,9 +31,9 @@ def to_dict(self) -> Dict[str, Any]: @staticmethod def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if not isinstance(_a_date_holder, Unset): + if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( cast(Dict[str, Any], _a_date_holder) ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index cbecc7c90..35bc2a853 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -14,18 +14,18 @@ class ModelWithUnionProperty: a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update({}) diff --git a/end_to_end_tests/golden-record/my_test_api_client/types.py b/end_to_end_tests/golden-record/my_test_api_client/types.py index 2061b9f08..a354a2192 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/types.py +++ b/end_to_end_tests/golden-record/my_test_api_client/types.py @@ -11,6 +11,9 @@ def __bool__(self) -> bool: UNSET: Unset = Unset() +# Used as `FileProperty._json_type_string` +FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]] + @attr.s(auto_attribs=True) class File: @@ -20,7 +23,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]: + def to_tuple(self) -> FileJsonType: """ Return a tuple representation that httpx will accept for multipart/form-data """ return self.file_name, self.payload, self.mime_type From b33df4d67af350dc710bd9aa59f35561b7e5c4a9 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 18:19:49 -0500 Subject: [PATCH 09/50] Undo diffs --- .../api/tests/defaults_tests_defaults_post.py | 8 ++ .../custom_e2e/models/__init__.py | 4 + .../custom_e2e/models/a_model.py | 47 ++++++++++ .../custom_e2e/models/a_model_model.py | 85 +++++++++++++++++++ .../models/a_model_not_required_model.py | 85 +++++++++++++++++++ .../a_model_not_required_nullable_model.py | 85 +++++++++++++++++++ .../models/a_model_nullable_model.py | 85 +++++++++++++++++++ .../api/tests/defaults_tests_defaults_post.py | 16 ++++ .../my_test_api_client/models/__init__.py | 4 + .../my_test_api_client/models/a_model.py | 47 ++++++++++ .../models/a_model_model.py | 85 +++++++++++++++++++ .../models/a_model_not_required_model.py | 85 +++++++++++++++++++ .../a_model_not_required_nullable_model.py | 85 +++++++++++++++++++ .../models/a_model_nullable_model.py | 85 +++++++++++++++++++ end_to_end_tests/openapi.json | 46 +++++++++- .../parser/properties/__init__.py | 32 +++++-- .../parser/properties/model_property.py | 55 +++++++++++- .../parser/properties/property.py | 1 + pyproject.toml | 13 ++- 19 files changed, 942 insertions(+), 11 deletions(-) create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index 4a2c9074b..e4b71e321 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -13,6 +13,7 @@ from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError +from ...models.model_with_union_property import ModelWithUnionProperty from ...types import UNSET, Unset @@ -53,6 +54,7 @@ def httpx_request( union_prop: Union[Unset, None, float, str] = "not a float", union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: json_not_required_not_nullable_datetime_prop: Union[Unset, None, str] = UNSET @@ -113,6 +115,10 @@ def httpx_request( if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop.value if enum_prop else None + json_model_prop: Union[Unset, None, Dict[str, Any]] = UNSET + if not isinstance(model_prop, Unset): + json_model_prop = model_prop.to_dict() if model_prop else None + params: Dict[str, Any] = { "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, } @@ -140,6 +146,8 @@ def httpx_request( params["union_prop_with_ref"] = json_union_prop_with_ref if enum_prop is not UNSET and enum_prop is not None: params["enum_prop"] = json_enum_prop + if model_prop is not UNSET and model_prop is not None: + params["model_prop"] = json_model_prop response = client.request( "post", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py index d3ca924b3..6f5ac7423 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py @@ -1,6 +1,10 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel +from .a_model_model import AModelModel +from .a_model_not_required_model import AModelNotRequiredModel +from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index f811d4712..3e46992a4 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -4,6 +4,10 @@ import attr from dateutil.parser import isoparse +from ..models.a_model_model import AModelModel +from ..models.a_model_not_required_model import AModelNotRequiredModel +from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..types import UNSET, Unset @@ -17,12 +21,16 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str + model: AModelModel a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] + nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -35,6 +43,8 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable + model = self.model.to_dict() + nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -52,6 +62,17 @@ def to_dict(self) -> Dict[str, Any]: required_nullable = self.required_nullable not_required_nullable = self.not_required_nullable not_required_not_nullable = self.not_required_not_nullable + nullable_model = self.nullable_model.to_dict() if self.nullable_model else None + + not_required_model: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_model, Unset): + not_required_model = self.not_required_model.to_dict() + + not_required_nullable_model: Union[Unset, None, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_nullable_model, Unset): + not_required_nullable_model = ( + self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None + ) field_dict: Dict[str, Any] = {} field_dict.update( @@ -60,8 +81,10 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, + "model": model, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, + "nullable_model": nullable_model, } ) if nested_list_of_enums is not UNSET: @@ -72,6 +95,10 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_nullable"] = not_required_nullable if not_required_not_nullable is not UNSET: field_dict["not_required_not_nullable"] = not_required_not_nullable + if not_required_model is not UNSET: + field_dict["not_required_model"] = not_required_model + if not_required_nullable_model is not UNSET: + field_dict["not_required_nullable_model"] = not_required_nullable_model return field_dict @@ -99,6 +126,8 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat required_not_nullable = d.pop("required_not_nullable") + model = AModelModel.from_dict(d.pop("model")) + nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -124,17 +153,35 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) + nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) + + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + _not_required_model = d.pop("not_required_model", UNSET) + if _not_required_model is not None and not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) + + not_required_nullable_model = None + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( + cast(Dict[str, Any], _not_required_nullable_model) + ) + a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, + model=model, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, required_nullable=required_nullable, not_required_nullable=not_required_nullable, not_required_not_nullable=not_required_not_nullable, + nullable_model=nullable_model, + not_required_model=not_required_model, + not_required_nullable_model=not_required_nullable_model, ) return a_model diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py new file mode 100644 index 000000000..0700798c8 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_model = AModelModel( + a_property=a_property, + ) + + a_model_model.additional_properties = d + return a_model_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py new file mode 100644 index 000000000..a08f547aa --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_model = AModelNotRequiredModel( + a_property=a_property, + ) + + a_model_not_required_model.additional_properties = d + return a_model_not_required_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py new file mode 100644 index 000000000..52ee2ddc3 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_nullable_model = AModelNotRequiredNullableModel( + a_property=a_property, + ) + + a_model_not_required_nullable_model.additional_properties = d + return a_model_not_required_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py new file mode 100644 index 000000000..2f21cc5ac --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_nullable_model = AModelNullableModel( + a_property=a_property, + ) + + a_model_nullable_model.additional_properties = d + return a_model_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index 1f865570d..540f68b44 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -7,6 +7,7 @@ from ...client import Client from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError +from ...models.model_with_union_property import ModelWithUnionProperty from ...types import UNSET, Response, Unset @@ -26,6 +27,7 @@ def _get_kwargs( union_prop: Union[Unset, None, float, str] = "not a float", union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Dict[str, Any]: url = "{}/tests/defaults".format(client.base_url) @@ -89,6 +91,10 @@ def _get_kwargs( if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop.value if enum_prop else None + json_model_prop: Union[Unset, None, Dict[str, Any]] = UNSET + if not isinstance(model_prop, Unset): + json_model_prop = model_prop.to_dict() if model_prop else None + params: Dict[str, Any] = { "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, } @@ -116,6 +122,8 @@ def _get_kwargs( params["union_prop_with_ref"] = json_union_prop_with_ref if enum_prop is not UNSET and enum_prop is not None: params["enum_prop"] = json_enum_prop + if model_prop is not UNSET and model_prop is not None: + params["model_prop"] = json_model_prop return { "url": url, @@ -163,6 +171,7 @@ def sync_detailed( union_prop: Union[Unset, None, float, str] = "not a float", union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -179,6 +188,7 @@ def sync_detailed( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ) response = httpx.post( @@ -204,6 +214,7 @@ def sync( union_prop: Union[Unset, None, float, str] = "not a float", union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -222,6 +233,7 @@ def sync( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ).parsed @@ -241,6 +253,7 @@ async def asyncio_detailed( union_prop: Union[Unset, None, float, str] = "not a float", union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -257,6 +270,7 @@ async def asyncio_detailed( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ) async with httpx.AsyncClient() as _client: @@ -281,6 +295,7 @@ async def asyncio( union_prop: Union[Unset, None, float, str] = "not a float", union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -300,5 +315,6 @@ async def asyncio( union_prop=union_prop, union_prop_with_ref=union_prop_with_ref, enum_prop=enum_prop, + model_prop=model_prop, ) ).parsed diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index d3ca924b3..6f5ac7423 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,6 +1,10 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel +from .a_model_model import AModelModel +from .a_model_not_required_model import AModelNotRequiredModel +from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index f811d4712..3e46992a4 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -4,6 +4,10 @@ import attr from dateutil.parser import isoparse +from ..models.a_model_model import AModelModel +from ..models.a_model_not_required_model import AModelNotRequiredModel +from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel +from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..types import UNSET, Unset @@ -17,12 +21,16 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str + model: AModelModel a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] + nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -35,6 +43,8 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable + model = self.model.to_dict() + nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -52,6 +62,17 @@ def to_dict(self) -> Dict[str, Any]: required_nullable = self.required_nullable not_required_nullable = self.not_required_nullable not_required_not_nullable = self.not_required_not_nullable + nullable_model = self.nullable_model.to_dict() if self.nullable_model else None + + not_required_model: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_model, Unset): + not_required_model = self.not_required_model.to_dict() + + not_required_nullable_model: Union[Unset, None, Dict[str, Any]] = UNSET + if not isinstance(self.not_required_nullable_model, Unset): + not_required_nullable_model = ( + self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None + ) field_dict: Dict[str, Any] = {} field_dict.update( @@ -60,8 +81,10 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, + "model": model, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, + "nullable_model": nullable_model, } ) if nested_list_of_enums is not UNSET: @@ -72,6 +95,10 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_nullable"] = not_required_nullable if not_required_not_nullable is not UNSET: field_dict["not_required_not_nullable"] = not_required_not_nullable + if not_required_model is not UNSET: + field_dict["not_required_model"] = not_required_model + if not_required_nullable_model is not UNSET: + field_dict["not_required_nullable_model"] = not_required_nullable_model return field_dict @@ -99,6 +126,8 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat required_not_nullable = d.pop("required_not_nullable") + model = AModelModel.from_dict(d.pop("model")) + nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -124,17 +153,35 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) + nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) + + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + _not_required_model = d.pop("not_required_model", UNSET) + if _not_required_model is not None and not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) + + not_required_nullable_model = None + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( + cast(Dict[str, Any], _not_required_nullable_model) + ) + a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, + model=model, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, required_nullable=required_nullable, not_required_nullable=not_required_nullable, not_required_not_nullable=not_required_not_nullable, + nullable_model=nullable_model, + not_required_model=not_required_model, + not_required_nullable_model=not_required_nullable_model, ) return a_model diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py new file mode 100644 index 000000000..0700798c8 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_model = AModelModel( + a_property=a_property, + ) + + a_model_model.additional_properties = d + return a_model_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py new file mode 100644 index 000000000..a08f547aa --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_model = AModelNotRequiredModel( + a_property=a_property, + ) + + a_model_not_required_model.additional_properties = d + return a_model_not_required_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py new file mode 100644 index 000000000..52ee2ddc3 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNotRequiredNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_not_required_nullable_model = AModelNotRequiredNullableModel( + a_property=a_property, + ) + + a_model_not_required_nullable_model.additional_properties = d + return a_model_not_required_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py new file mode 100644 index 000000000..2f21cc5ac --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, List, Union + +import attr + +from ..models.an_enum import AnEnum +from ..models.an_int_enum import AnIntEnum +from ..types import UNSET, Unset + + +@attr.s(auto_attribs=True) +class AModelNullableModel: + """ """ + + a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + a_property: Union[Unset, int] + if isinstance(self.a_property, Unset): + a_property = UNSET + elif isinstance(self.a_property, AnEnum): + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + else: + a_property = UNSET + if not isinstance(self.a_property, Unset): + a_property = self.a_property.value + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if a_property is not UNSET: + field_dict["a_property"] = a_property + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": + d = src_dict.copy() + + def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: + data = None if isinstance(data, Unset) else data + a_property: Union[Unset, AnEnum, AnIntEnum] + try: + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnEnum(_a_property) + + return a_property + except: # noqa: E722 + pass + a_property = UNSET + _a_property = data + if _a_property is not None: + a_property = AnIntEnum(_a_property) + + return a_property + + a_property = _parse_a_property(d.pop("a_property", UNSET)) + + a_model_nullable_model = AModelNullableModel( + a_property=a_property, + ) + + a_model_nullable_model.additional_properties = d + return a_model_nullable_model + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 931fc481e..6d7d15c6c 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -433,6 +433,14 @@ }, "name": "enum_prop", "in": "query" + }, + { + "required": false, + "schema": { + "$ref": "#/components/schemas/ModelWithUnionProperty" + }, + "name": "model_prop", + "in": "query" } ], "responses": { @@ -659,7 +667,7 @@ "schemas": { "AModel": { "title": "AModel", - "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable"], + "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable", "model", "nullable_model"], "type": "object", "properties": { "an_enum_value": { @@ -723,6 +731,42 @@ "title": "NOT Required AND NOT Nullable", "type": "string", "nullable": false + }, + "model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": false + }, + "nullable_model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": true + }, + "not_required_model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": false + }, + "not_required_nullable_model": { + "type": "object", + "allOf": [ + { + "ref": "#/components/schemas/ModelWithUnionProperty" + } + ], + "nullable": true } }, "description": "A Model for testing all the ways custom objects can be used ", diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index e3a3f69b7..a5ebf00d4 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -272,13 +272,23 @@ def build_model_property( required_properties: List[Property] = [] optional_properties: List[Property] = [] relative_imports: Set[str] = set() + references: List[oai.Reference] = [] class_name = data.title or name if parent_name: class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}" ref = Reference.from_ref(class_name) - for key, value in (data.properties or {}).items(): + all_props = data.properties or {} + if not isinstance(data, oai.Reference) and data.allOf: + for sub_prop in data.allOf: + if isinstance(sub_prop, oai.Reference): + references += [sub_prop] + else: + all_props.update(sub_prop.properties or {}) + required_set.update(sub_prop.required or []) + + for key, value in all_props.items(): prop_required = key in required_set prop, schemas = property_from_data( name=key, required=prop_required, data=value, schemas=schemas, parent_name=class_name @@ -314,6 +324,7 @@ def build_model_property( prop = ModelProperty( reference=ref, + references=references, required_properties=required_properties, optional_properties=optional_properties, relative_imports=relative_imports, @@ -471,9 +482,7 @@ def _property_from_data( ) if data.anyOf or data.oneOf: return build_union_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) - if not data.type: - return NoneProperty(name=name, required=required, nullable=False, default=None), schemas - + if data.type == "string": return _string_based_property(name=name, required=required, data=data), schemas elif data.type == "number": @@ -508,8 +517,10 @@ def _property_from_data( ) elif data.type == "array": return build_list_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) - elif data.type == "object": + elif data.type == "object" or data.allOf: return build_model_property(data=data, name=name, schemas=schemas, required=required, parent_name=parent_name) + elif not data.type: + return NoneProperty(name=name, required=required, nullable=False, default=None), schemas return PropertyError(data=data, detail=f"unknown type {data.type}"), schemas @@ -566,6 +577,15 @@ def build_schemas(*, components: Dict[str, Union[oai.Reference, oai.Schema]]) -> schemas = schemas_or_err processing = True # We made some progress this round, do another after it's done to_process = next_round - schemas.errors.extend(errors) + resolve_errors: List[PropertyError] = [] + models = list(schemas.models.values()) + for model in models: + schemas_or_err = model.resolve_references(components=components, schemas=schemas) + if isinstance(schemas_or_err, PropertyError): + resolve_errors.append(schemas_or_err) + else: + schemas = schemas_or_err + + schemas.errors.extend(resolve_errors) return schemas diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 3ab145af4..421259b9d 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -1,16 +1,25 @@ -from typing import ClassVar, List, Set, Union +from __future__ import annotations + +from collections.abc import Iterable +from typing import TYPE_CHECKING, ClassVar, Dict, List, Set, Union import attr +from ... import schema as oai +from ..errors import PropertyError from ..reference import Reference from .property import Property +if TYPE_CHECKING: + from .schemas import Schemas + @attr.s(auto_attribs=True, frozen=True) class ModelProperty(Property): """ A property which refers to another Schema """ reference: Reference + references: List[oai.Reference] required_properties: List[Property] optional_properties: List[Property] @@ -20,6 +29,50 @@ class ModelProperty(Property): _json_type_string: ClassVar[str] = "Dict[str, Any]" template: ClassVar[str] = "model_property.pyi" + json_is_dict: ClassVar[bool] = True + + def resolve_references( + self, components: Dict[str, Union[oai.Reference, oai.Schema]], schemas: Schemas + ) -> Union[Schemas, PropertyError]: + from ..properties import property_from_data + + required_set = set() + props = {} + while self.references: + reference = self.references.pop() + source_name = Reference.from_ref(reference.ref).class_name + referenced_prop = components[source_name] + assert isinstance(referenced_prop, oai.Schema) + for p, val in (referenced_prop.properties or {}).items(): + props[p] = (val, source_name) + for sub_prop in referenced_prop.allOf or []: + if isinstance(sub_prop, oai.Reference): + self.references.append(sub_prop) + else: + for p, val in (sub_prop.properties or {}).items(): + props[p] = (val, source_name) + if isinstance(referenced_prop.required, Iterable): + for sub_prop_name in referenced_prop.required: + required_set.add(sub_prop_name) + + for key, (value, source_name) in (props or {}).items(): + required = key in required_set + prop, schemas = property_from_data( + name=key, required=required, data=value, schemas=schemas, parent_name=source_name + ) + if isinstance(prop, PropertyError): + return prop + if required: + self.required_properties.append(prop) + # Remove the optional version + new_optional_props = [op for op in self.optional_properties if op.name != prop.name] + self.optional_properties.clear() + self.optional_properties.extend(new_optional_props) + elif not any(ep for ep in (self.optional_properties + self.required_properties) if ep.name == prop.name): + self.optional_properties.append(prop) + self.relative_imports.update(prop.get_imports(prefix="..")) + + return schemas def get_base_type_string(self) -> str: return self.reference.class_name diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index 651370ae2..c0ec0d56e 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -29,6 +29,7 @@ class Property: python_name: str = attr.ib(init=False) template: ClassVar[Optional[str]] = None + json_is_dict: ClassVar[bool] = False def __attrs_post_init__(self) -> None: object.__setattr__(self, "python_name", utils.to_valid_python_identifier(utils.snake_case(self.name))) diff --git a/pyproject.toml b/pyproject.toml index 4be8d93db..4d74fea82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,6 @@ safety = "*" pytest-cov = "*" python-multipart = "*" flake8 = "*" -typer-cli = "^0.0.11" [tool.taskipy.tasks] check = """ @@ -67,7 +66,12 @@ task regen\ && task regen_custom\ && task e2e\ """ -docs = "typer openapi_python_client/cli.py utils docs > usage.md" +gen-setuppy = """ +poetry build \ +&& tar --strip-components=1 -xvf "$(ls -1 dist/*tar.gz | tail -1)" '*/setup.py' \ +&& isort setup.py \ +&& black setup.py +""" [tool.black] line-length = 120 @@ -95,5 +99,8 @@ skip = [".venv", "tests/test_templates"] omit = ["openapi_python_client/templates/*"] [build-system] -requires = ["poetry>=1.0"] +requires = [ + "setuptools>=30.3.0,<50", + "poetry>=1.0" +] build-backend = "poetry.masonry.api" From 97063d576e6f1cf4a2772c3e11659122def9d2a2 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 18:33:57 -0500 Subject: [PATCH 10/50] Fix tests --- .../parser/properties/__init__.py | 2 +- .../parser/properties/model_property.py | 1 - .../templates/endpoint_macros.pyi | 9 +- .../property_templates/model_property.pyi | 4 +- .../test_parser/test_properties/test_init.py | 22 ++- .../test_properties/test_model_property.py | 142 ++++++++++++++++++ 6 files changed, 167 insertions(+), 13 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index a5ebf00d4..b84166f23 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -482,7 +482,6 @@ def _property_from_data( ) if data.anyOf or data.oneOf: return build_union_property(data=data, name=name, required=required, schemas=schemas, parent_name=parent_name) - if data.type == "string": return _string_based_property(name=name, required=required, data=data), schemas elif data.type == "number": @@ -587,5 +586,6 @@ def build_schemas(*, components: Dict[str, Union[oai.Reference, oai.Schema]]) -> else: schemas = schemas_or_err + schemas.errors.extend(errors) schemas.errors.extend(resolve_errors) return schemas diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 421259b9d..c4c203a5d 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -20,7 +20,6 @@ class ModelProperty(Property): reference: Reference references: List[oai.Reference] - required_properties: List[Property] optional_properties: List[Property] description: str diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 7a1862be3..6586ecd70 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -33,11 +33,12 @@ params: Dict[str, Any] = { } {% for property in endpoint.query_parameters %} {% if not property.required or property.nullable %} -if {% if not property.required %}{{ property.python_name }} is not UNSET and {% endif %}{{ property.python_name }} is not None: - {% if property.template %} - params["{{ property.name }}"] = {{ "json_" + property.python_name }} + {% set property_name = "json_" + property.python_name if property.template else property.python_name %} +if {% if not property.required %}not isinstance({{ property_name }}, Unset) and {% endif %}{{ property_name }} is not None: + {% if property.json_is_dict %} + params.update({{ property_name }}) {% else %} - params["{{ property.name }}"] = {{ property.python_name }} + params["{{ property.name }}"] = {{ property_name }} {% endif %} {% endif %} {% endfor %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index dfda61d97..6aef71d0f 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,5 +1,5 @@ {% macro construct(property, source, initial_value=None) %} -{% if property.required %} +{% if property.required and not property.nullable %} {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) {% else %} {% if initial_value != None %} @@ -10,7 +10,7 @@ {{ property.python_name }}: {{ property.get_type_string() }} = UNSET {% endif %} _{{ property.python_name }} = {{source}} -if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): +if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{% if property.nullable and not property.required %} and {% endif %}{% if not property.required %}not isinstance(_{{ property.python_name }}, Unset){% endif %}: {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(cast(Dict[str, Any], _{{ property.python_name }})) {% endif %} {% endmacro %} diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 2f1c71cc5..604b1bd1d 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -584,6 +584,7 @@ def test_property_from_data_ref_model(self): nullable=False, default=None, reference=Reference(class_name=class_name, module_name="my_model"), + references=[], required_properties=[], optional_properties=[], description="", @@ -600,6 +601,7 @@ def test_property_from_data_ref_model(self): nullable=False, default=None, reference=Reference(class_name=class_name, module_name="my_model"), + references=[], required_properties=[], optional_properties=[], description="", @@ -990,15 +992,20 @@ def test_build_schemas(mocker): schemas_1 = mocker.MagicMock() model_2 = mocker.MagicMock() schemas_2 = mocker.MagicMock(errors=[]) - error = PropertyError() + schemas_2.models = {"1": model_1, "2": model_2} + error_1 = PropertyError() schemas_3 = mocker.MagicMock() + schemas_4 = mocker.MagicMock(errors=[]) + model_1.resolve_references.return_value = schemas_4 + error_2 = PropertyError() + model_2.resolve_references.return_value = error_2 # This loops through one for each, then again to retry the error build_model_property.side_effect = [ (model_1, schemas_1), (model_2, schemas_2), - (error, schemas_3), - (error, schemas_3), + (error_1, schemas_3), + (error_1, schemas_3), ] from openapi_python_client.parser.properties import Schemas, build_schemas @@ -1014,8 +1021,12 @@ def test_build_schemas(mocker): ] ) # schemas_3 was the last to come back from build_model_property, but it should be ignored because it's an error - assert result == schemas_2 - assert result.errors == [error] + model_1.resolve_references.assert_called_once_with(components=in_data, schemas=schemas_2) + # schemas_4 came from resolving model_1 + model_2.resolve_references.assert_called_once_with(components=in_data, schemas=schemas_4) + # resolving model_2 resulted in err, so no schemas_5 + assert result == schemas_4 + assert result.errors == [error_1, error_2] def test_build_parse_error_on_reference(): @@ -1089,6 +1100,7 @@ def test_build_model_property(additional_properties_schema, expected_additional_ nullable=False, default=None, reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), + references=[], required_properties=[StringProperty(name="req", required=True, nullable=False, default=None)], optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None)], description=data.description, diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 410112666..83d521ab1 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -23,6 +23,7 @@ def test_get_type_string(no_optional, nullable, required, expected): nullable=nullable, default=None, reference=Reference(class_name="MyClass", module_name="my_module"), + references=[], description="", optional_properties=[], required_properties=[], @@ -42,6 +43,7 @@ def test_get_imports(): nullable=True, default=None, reference=Reference(class_name="MyClass", module_name="my_module"), + references=[], description="", optional_properties=[], required_properties=[], @@ -57,3 +59,143 @@ def test_get_imports(): "from typing import Dict", "from typing import cast", } + + +def test_resolve_references(mocker): + import openapi_python_client.schema as oai + from openapi_python_client.parser.properties import build_model_property + + schemas = { + "RefA": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["String"], + properties={ + "String": oai.Schema.construct(type="string"), + "Enum": oai.Schema.construct(type="string", enum=["aValue"]), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + }, + ), + "RefB": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["DateTime"], + properties={ + "Int": oai.Schema.construct(type="integer"), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + # Intentionally no properties defined + "RefC": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + ), + } + + model_schema = oai.Schema.construct( + allOf=[ + oai.Reference.construct(ref="#/components/schemas/RefA"), + oai.Reference.construct(ref="#/components/schemas/RefB"), + oai.Reference.construct(ref="#/components/schemas/RefC"), + oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["Float"], + properties={ + "String": oai.Schema.construct(type="string"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + ] + ) + + components = {**schemas, "Model": model_schema} + + from openapi_python_client.parser.properties import Schemas + + schemas_holder = Schemas() + model, schemas_holder = build_model_property( + data=model_schema, name="Model", required=True, schemas=schemas_holder, parent_name=None + ) + model.resolve_references(components, schemas_holder) + assert sorted(p.name for p in model.required_properties) == ["DateTime", "Float", "String"] + assert all(p.required for p in model.required_properties) + assert sorted(p.name for p in model.optional_properties) == ["Enum", "Int"] + assert all(not p.required for p in model.optional_properties) + + +def test_resolve_references_nested_allof(mocker): + import openapi_python_client.schema as oai + from openapi_python_client.parser.properties import build_model_property + + schemas = { + "RefA": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["String"], + properties={ + "String": oai.Schema.construct(type="string"), + "Enum": oai.Schema.construct(type="string", enum=["aValue"]), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + }, + ), + "RefB": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["DateTime"], + properties={ + "Int": oai.Schema.construct(type="integer"), + "DateTime": oai.Schema.construct(type="string", format="date-time"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + # Intentionally no properties defined + "RefC": oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + ), + } + + model_schema = oai.Schema.construct( + type="object", + properties={ + "Key": oai.Schema.construct( + allOf=[ + oai.Reference.construct(ref="#/components/schemas/RefA"), + oai.Reference.construct(ref="#/components/schemas/RefB"), + oai.Reference.construct(ref="#/components/schemas/RefC"), + oai.Schema.construct( + title=mocker.MagicMock(), + description=mocker.MagicMock(), + required=["Float"], + properties={ + "String": oai.Schema.construct(type="string"), + "Float": oai.Schema.construct(type="number", format="float"), + }, + ), + ] + ), + }, + ) + + components = {**schemas, "Model": model_schema} + + from openapi_python_client.parser.properties import ModelProperty, Schemas + + schemas_holder = Schemas() + model, schemas_holder = build_model_property( + data=model_schema, name="Model", required=True, schemas=schemas_holder, parent_name=None + ) + model.resolve_references(components, schemas_holder) + assert sorted(p.name for p in model.required_properties) == [] + assert sorted(p.name for p in model.optional_properties) == ["Key"] + assert all(not p.required for p in model.optional_properties) + + key_property = model.optional_properties[0] + assert isinstance(key_property, ModelProperty) + key_property.resolve_references(components, schemas_holder) + assert sorted(p.name for p in key_property.required_properties) == ["DateTime", "Float", "String"] + assert all(p.required for p in key_property.required_properties) + assert sorted(p.name for p in key_property.optional_properties) == ["Enum", "Int"] + assert all(not p.required for p in key_property.optional_properties) From 67bce4180461c10a76f2355a7efaaae167b62d8d Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 18:34:26 -0500 Subject: [PATCH 11/50] Regen --- .../api/tests/defaults_tests_defaults_post.py | 34 +++++++++++-------- ...tional_value_tests_optional_query_param.py | 2 +- .../custom_e2e/models/a_model.py | 7 ++-- ...el_with_primitive_additional_properties.py | 2 +- .../api/tests/defaults_tests_defaults_post.py | 34 +++++++++++-------- ...tional_value_tests_optional_query_param.py | 2 +- .../my_test_api_client/models/a_model.py | 7 ++-- ...el_with_primitive_additional_properties.py | 2 +- 8 files changed, 54 insertions(+), 36 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index e4b71e321..d61560254 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -122,32 +122,38 @@ def httpx_request( params: Dict[str, Any] = { "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, } - if string_prop is not UNSET and string_prop is not None: + if not isinstance(string_prop, Unset) and string_prop is not None: params["string_prop"] = string_prop - if not_required_not_nullable_datetime_prop is not UNSET and not_required_not_nullable_datetime_prop is not None: + if ( + not isinstance(json_not_required_not_nullable_datetime_prop, Unset) + and json_not_required_not_nullable_datetime_prop is not None + ): params["not_required_not_nullable_datetime_prop"] = json_not_required_not_nullable_datetime_prop - if not_required_nullable_datetime_prop is not UNSET and not_required_nullable_datetime_prop is not None: + if ( + not isinstance(json_not_required_nullable_datetime_prop, Unset) + and json_not_required_nullable_datetime_prop is not None + ): params["not_required_nullable_datetime_prop"] = json_not_required_nullable_datetime_prop - if required_nullable_datetime_prop is not None: + if json_required_nullable_datetime_prop is not None: params["required_nullable_datetime_prop"] = json_required_nullable_datetime_prop - if date_prop is not UNSET and date_prop is not None: + if not isinstance(json_date_prop, Unset) and json_date_prop is not None: params["date_prop"] = json_date_prop - if float_prop is not UNSET and float_prop is not None: + if not isinstance(float_prop, Unset) and float_prop is not None: params["float_prop"] = float_prop - if int_prop is not UNSET and int_prop is not None: + if not isinstance(int_prop, Unset) and int_prop is not None: params["int_prop"] = int_prop - if boolean_prop is not UNSET and boolean_prop is not None: + if not isinstance(boolean_prop, Unset) and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if list_prop is not UNSET and list_prop is not None: + if not isinstance(json_list_prop, Unset) and json_list_prop is not None: params["list_prop"] = json_list_prop - if union_prop is not UNSET and union_prop is not None: + if not isinstance(json_union_prop, Unset) and json_union_prop is not None: params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET and union_prop_with_ref is not None: + if not isinstance(json_union_prop_with_ref, Unset) and json_union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET and enum_prop is not None: + if not isinstance(json_enum_prop, Unset) and json_enum_prop is not None: params["enum_prop"] = json_enum_prop - if model_prop is not UNSET and model_prop is not None: - params["model_prop"] = json_model_prop + if not isinstance(json_model_prop, Unset) and json_model_prop is not None: + params.update(json_model_prop) response = client.request( "post", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index 8ff5a52a3..279ce8ca8 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -47,7 +47,7 @@ def httpx_request( json_query_param = query_param params: Dict[str, Any] = {} - if query_param is not UNSET and query_param is not None: + if not isinstance(json_query_param, Unset) and json_query_param is not None: params["query_param"] = json_query_param response = client.request( diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 3e46992a4..9462c38b9 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -153,11 +153,14 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) - nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) + nullable_model = None + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET _not_required_model = d.pop("not_required_model", UNSET) - if _not_required_model is not None and not isinstance(_not_required_model, Unset): + if not isinstance(_not_required_model, Unset): not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) not_required_nullable_model = None diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index feb30878d..1ba447347 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -33,7 +33,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): + if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( cast(Dict[str, Any], _a_date_holder) ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index 540f68b44..f87317ead 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -98,32 +98,38 @@ def _get_kwargs( params: Dict[str, Any] = { "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, } - if string_prop is not UNSET and string_prop is not None: + if not isinstance(string_prop, Unset) and string_prop is not None: params["string_prop"] = string_prop - if not_required_not_nullable_datetime_prop is not UNSET and not_required_not_nullable_datetime_prop is not None: + if ( + not isinstance(json_not_required_not_nullable_datetime_prop, Unset) + and json_not_required_not_nullable_datetime_prop is not None + ): params["not_required_not_nullable_datetime_prop"] = json_not_required_not_nullable_datetime_prop - if not_required_nullable_datetime_prop is not UNSET and not_required_nullable_datetime_prop is not None: + if ( + not isinstance(json_not_required_nullable_datetime_prop, Unset) + and json_not_required_nullable_datetime_prop is not None + ): params["not_required_nullable_datetime_prop"] = json_not_required_nullable_datetime_prop - if required_nullable_datetime_prop is not None: + if json_required_nullable_datetime_prop is not None: params["required_nullable_datetime_prop"] = json_required_nullable_datetime_prop - if date_prop is not UNSET and date_prop is not None: + if not isinstance(json_date_prop, Unset) and json_date_prop is not None: params["date_prop"] = json_date_prop - if float_prop is not UNSET and float_prop is not None: + if not isinstance(float_prop, Unset) and float_prop is not None: params["float_prop"] = float_prop - if int_prop is not UNSET and int_prop is not None: + if not isinstance(int_prop, Unset) and int_prop is not None: params["int_prop"] = int_prop - if boolean_prop is not UNSET and boolean_prop is not None: + if not isinstance(boolean_prop, Unset) and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if list_prop is not UNSET and list_prop is not None: + if not isinstance(json_list_prop, Unset) and json_list_prop is not None: params["list_prop"] = json_list_prop - if union_prop is not UNSET and union_prop is not None: + if not isinstance(json_union_prop, Unset) and json_union_prop is not None: params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET and union_prop_with_ref is not None: + if not isinstance(json_union_prop_with_ref, Unset) and json_union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET and enum_prop is not None: + if not isinstance(json_enum_prop, Unset) and json_enum_prop is not None: params["enum_prop"] = json_enum_prop - if model_prop is not UNSET and model_prop is not None: - params["model_prop"] = json_model_prop + if not isinstance(json_model_prop, Unset) and json_model_prop is not None: + params.update(json_model_prop) return { "url": url, diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 2c14c2949..23bd9e741 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -24,7 +24,7 @@ def _get_kwargs( json_query_param = query_param params: Dict[str, Any] = {} - if query_param is not UNSET and query_param is not None: + if not isinstance(json_query_param, Unset) and json_query_param is not None: params["query_param"] = json_query_param return { diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 3e46992a4..9462c38b9 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -153,11 +153,14 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) - nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) + nullable_model = None + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET _not_required_model = d.pop("not_required_model", UNSET) - if _not_required_model is not None and not isinstance(_not_required_model, Unset): + if not isinstance(_not_required_model, Unset): not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) not_required_nullable_model = None diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index feb30878d..1ba447347 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -33,7 +33,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): + if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( cast(Dict[str, Any], _a_date_holder) ) From f02e943d374bbbef7dd170798a3c338f3465e8a3 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 18:40:25 -0500 Subject: [PATCH 12/50] Add tests for union --- .../custom_e2e/models/a_model.py | 145 ++++++++++++++++++ .../my_test_api_client/models/a_model.py | 145 ++++++++++++++++++ end_to_end_tests/openapi.json | 57 ++++++- 3 files changed, 346 insertions(+), 1 deletion(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 9462c38b9..e3410d097 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -10,6 +10,8 @@ from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum +from ..models.free_form_model import FreeFormModel +from ..models.model_with_union_property import ModelWithUnionProperty from ..types import UNSET, Unset @@ -22,15 +24,19 @@ class AModel: a_date: datetime.date required_not_nullable: str model: AModelModel + one_of_models: Union[FreeFormModel, ModelWithUnionProperty] a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] nullable_model: Optional[AModelNullableModel] + nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET + not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] = UNSET + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -45,6 +51,12 @@ def to_dict(self) -> Dict[str, Any]: required_not_nullable = self.required_not_nullable model = self.model.to_dict() + if isinstance(self.one_of_models, FreeFormModel): + one_of_models = self.one_of_models.to_dict() + + else: + one_of_models = self.one_of_models.to_dict() + nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -74,6 +86,45 @@ def to_dict(self) -> Dict[str, Any]: self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None ) + nullable_one_of_models: Union[None, Dict[str, Any]] + if isinstance(self.nullable_one_of_models, Unset): + nullable_one_of_models = UNSET + if self.nullable_one_of_models is None: + nullable_one_of_models = None + elif isinstance(self.nullable_one_of_models, FreeFormModel): + nullable_one_of_models = self.nullable_one_of_models.to_dict() + + else: + nullable_one_of_models = self.nullable_one_of_models.to_dict() + + not_required_one_of_models: Union[Unset, Dict[str, Any]] + if isinstance(self.not_required_one_of_models, Unset): + not_required_one_of_models = UNSET + elif isinstance(self.not_required_one_of_models, FreeFormModel): + not_required_one_of_models = UNSET + if not isinstance(self.not_required_one_of_models, Unset): + not_required_one_of_models = self.not_required_one_of_models.to_dict() + + else: + not_required_one_of_models = UNSET + if not isinstance(self.not_required_one_of_models, Unset): + not_required_one_of_models = self.not_required_one_of_models.to_dict() + + not_required_nullable_one_of_models: Union[Unset, None, Dict[str, Any]] + if isinstance(self.not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = UNSET + elif self.not_required_nullable_one_of_models is None: + not_required_nullable_one_of_models = None + elif isinstance(self.not_required_nullable_one_of_models, FreeFormModel): + not_required_nullable_one_of_models = UNSET + if not isinstance(self.not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() + + else: + not_required_nullable_one_of_models = UNSET + if not isinstance(self.not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() + field_dict: Dict[str, Any] = {} field_dict.update( { @@ -82,9 +133,11 @@ def to_dict(self) -> Dict[str, Any]: "a_date": a_date, "required_not_nullable": required_not_nullable, "model": model, + "one_of_models": one_of_models, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, "nullable_model": nullable_model, + "nullable_one_of_models": nullable_one_of_models, } ) if nested_list_of_enums is not UNSET: @@ -99,6 +152,10 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_model"] = not_required_model if not_required_nullable_model is not UNSET: field_dict["not_required_nullable_model"] = not_required_nullable_model + if not_required_one_of_models is not UNSET: + field_dict["not_required_one_of_models"] = not_required_one_of_models + if not_required_nullable_one_of_models is not UNSET: + field_dict["not_required_nullable_one_of_models"] = not_required_nullable_one_of_models return field_dict @@ -128,6 +185,21 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat model = AModelModel.from_dict(d.pop("model")) + def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + one_of_models: Union[FreeFormModel, ModelWithUnionProperty] + try: + one_of_models = FreeFormModel.from_dict(data) + + return one_of_models + except: # noqa: E722 + pass + one_of_models = ModelWithUnionProperty.from_dict(data) + + return one_of_models + + one_of_models = _parse_one_of_models(d.pop("one_of_models")) + nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -170,12 +242,82 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat cast(Dict[str, Any], _not_required_nullable_model) ) + def _parse_nullable_one_of_models(data: Any) -> Union[None, FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] + try: + nullable_one_of_models = FreeFormModel.from_dict(data) + + return nullable_one_of_models + except: # noqa: E722 + pass + nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + + return nullable_one_of_models + + nullable_one_of_models = _parse_nullable_one_of_models(d.pop("nullable_one_of_models")) + + def _parse_not_required_one_of_models(data: Any) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] + try: + not_required_one_of_models = UNSET + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict( + cast(Dict[str, Any], _not_required_one_of_models) + ) + + return not_required_one_of_models + except: # noqa: E722 + pass + not_required_one_of_models = UNSET + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict( + cast(Dict[str, Any], _not_required_one_of_models) + ) + + return not_required_one_of_models + + not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) + + def _parse_not_required_nullable_one_of_models( + data: Any, + ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] + try: + not_required_nullable_one_of_models = UNSET + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = FreeFormModel.from_dict( + cast(Dict[str, Any], _not_required_nullable_one_of_models) + ) + + return not_required_nullable_one_of_models + except: # noqa: E722 + pass + not_required_nullable_one_of_models = UNSET + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( + cast(Dict[str, Any], _not_required_nullable_one_of_models) + ) + + return not_required_nullable_one_of_models + + not_required_nullable_one_of_models = _parse_not_required_nullable_one_of_models( + d.pop("not_required_nullable_one_of_models", UNSET) + ) + a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, model=model, + one_of_models=one_of_models, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, @@ -185,6 +327,9 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat nullable_model=nullable_model, not_required_model=not_required_model, not_required_nullable_model=not_required_nullable_model, + nullable_one_of_models=nullable_one_of_models, + not_required_one_of_models=not_required_one_of_models, + not_required_nullable_one_of_models=not_required_nullable_one_of_models, ) return a_model diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 9462c38b9..e3410d097 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -10,6 +10,8 @@ from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum +from ..models.free_form_model import FreeFormModel +from ..models.model_with_union_property import ModelWithUnionProperty from ..types import UNSET, Unset @@ -22,15 +24,19 @@ class AModel: a_date: datetime.date required_not_nullable: str model: AModelModel + one_of_models: Union[FreeFormModel, ModelWithUnionProperty] a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] nullable_model: Optional[AModelNullableModel] + nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET + not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] = UNSET + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -45,6 +51,12 @@ def to_dict(self) -> Dict[str, Any]: required_not_nullable = self.required_not_nullable model = self.model.to_dict() + if isinstance(self.one_of_models, FreeFormModel): + one_of_models = self.one_of_models.to_dict() + + else: + one_of_models = self.one_of_models.to_dict() + nested_list_of_enums: Union[Unset, List[Any]] = UNSET if not isinstance(self.nested_list_of_enums, Unset): nested_list_of_enums = [] @@ -74,6 +86,45 @@ def to_dict(self) -> Dict[str, Any]: self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None ) + nullable_one_of_models: Union[None, Dict[str, Any]] + if isinstance(self.nullable_one_of_models, Unset): + nullable_one_of_models = UNSET + if self.nullable_one_of_models is None: + nullable_one_of_models = None + elif isinstance(self.nullable_one_of_models, FreeFormModel): + nullable_one_of_models = self.nullable_one_of_models.to_dict() + + else: + nullable_one_of_models = self.nullable_one_of_models.to_dict() + + not_required_one_of_models: Union[Unset, Dict[str, Any]] + if isinstance(self.not_required_one_of_models, Unset): + not_required_one_of_models = UNSET + elif isinstance(self.not_required_one_of_models, FreeFormModel): + not_required_one_of_models = UNSET + if not isinstance(self.not_required_one_of_models, Unset): + not_required_one_of_models = self.not_required_one_of_models.to_dict() + + else: + not_required_one_of_models = UNSET + if not isinstance(self.not_required_one_of_models, Unset): + not_required_one_of_models = self.not_required_one_of_models.to_dict() + + not_required_nullable_one_of_models: Union[Unset, None, Dict[str, Any]] + if isinstance(self.not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = UNSET + elif self.not_required_nullable_one_of_models is None: + not_required_nullable_one_of_models = None + elif isinstance(self.not_required_nullable_one_of_models, FreeFormModel): + not_required_nullable_one_of_models = UNSET + if not isinstance(self.not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() + + else: + not_required_nullable_one_of_models = UNSET + if not isinstance(self.not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() + field_dict: Dict[str, Any] = {} field_dict.update( { @@ -82,9 +133,11 @@ def to_dict(self) -> Dict[str, Any]: "a_date": a_date, "required_not_nullable": required_not_nullable, "model": model, + "one_of_models": one_of_models, "a_nullable_date": a_nullable_date, "required_nullable": required_nullable, "nullable_model": nullable_model, + "nullable_one_of_models": nullable_one_of_models, } ) if nested_list_of_enums is not UNSET: @@ -99,6 +152,10 @@ def to_dict(self) -> Dict[str, Any]: field_dict["not_required_model"] = not_required_model if not_required_nullable_model is not UNSET: field_dict["not_required_nullable_model"] = not_required_nullable_model + if not_required_one_of_models is not UNSET: + field_dict["not_required_one_of_models"] = not_required_one_of_models + if not_required_nullable_one_of_models is not UNSET: + field_dict["not_required_nullable_one_of_models"] = not_required_nullable_one_of_models return field_dict @@ -128,6 +185,21 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat model = AModelModel.from_dict(d.pop("model")) + def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + one_of_models: Union[FreeFormModel, ModelWithUnionProperty] + try: + one_of_models = FreeFormModel.from_dict(data) + + return one_of_models + except: # noqa: E722 + pass + one_of_models = ModelWithUnionProperty.from_dict(data) + + return one_of_models + + one_of_models = _parse_one_of_models(d.pop("one_of_models")) + nested_list_of_enums = [] _nested_list_of_enums = d.pop("nested_list_of_enums", UNSET) for nested_list_of_enums_item_data in _nested_list_of_enums or []: @@ -170,12 +242,82 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat cast(Dict[str, Any], _not_required_nullable_model) ) + def _parse_nullable_one_of_models(data: Any) -> Union[None, FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] + try: + nullable_one_of_models = FreeFormModel.from_dict(data) + + return nullable_one_of_models + except: # noqa: E722 + pass + nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + + return nullable_one_of_models + + nullable_one_of_models = _parse_nullable_one_of_models(d.pop("nullable_one_of_models")) + + def _parse_not_required_one_of_models(data: Any) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] + try: + not_required_one_of_models = UNSET + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict( + cast(Dict[str, Any], _not_required_one_of_models) + ) + + return not_required_one_of_models + except: # noqa: E722 + pass + not_required_one_of_models = UNSET + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict( + cast(Dict[str, Any], _not_required_one_of_models) + ) + + return not_required_one_of_models + + not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) + + def _parse_not_required_nullable_one_of_models( + data: Any, + ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty]: + data = None if isinstance(data, Unset) else data + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] + try: + not_required_nullable_one_of_models = UNSET + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = FreeFormModel.from_dict( + cast(Dict[str, Any], _not_required_nullable_one_of_models) + ) + + return not_required_nullable_one_of_models + except: # noqa: E722 + pass + not_required_nullable_one_of_models = UNSET + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( + cast(Dict[str, Any], _not_required_nullable_one_of_models) + ) + + return not_required_nullable_one_of_models + + not_required_nullable_one_of_models = _parse_not_required_nullable_one_of_models( + d.pop("not_required_nullable_one_of_models", UNSET) + ) + a_model = AModel( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, required_not_nullable=required_not_nullable, model=model, + one_of_models=one_of_models, nested_list_of_enums=nested_list_of_enums, a_nullable_date=a_nullable_date, attr_1_leading_digit=attr_1_leading_digit, @@ -185,6 +327,9 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat nullable_model=nullable_model, not_required_model=not_required_model, not_required_nullable_model=not_required_nullable_model, + nullable_one_of_models=nullable_one_of_models, + not_required_one_of_models=not_required_one_of_models, + not_required_nullable_one_of_models=not_required_nullable_one_of_models, ) return a_model diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 6d7d15c6c..404656e31 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -667,7 +667,18 @@ "schemas": { "AModel": { "title": "AModel", - "required": ["an_enum_value", "aCamelDateTime", "a_date", "a_nullable_date", "required_nullable", "required_not_nullable", "model", "nullable_model"], + "required": [ + "an_enum_value", + "aCamelDateTime", + "a_date", + "a_nullable_date", + "required_nullable", + "required_not_nullable", + "model", + "nullable_model", + "one_of_models", + "nullable_one_of_models" + ], "type": "object", "properties": { "an_enum_value": { @@ -767,6 +778,50 @@ } ], "nullable": true + }, + "one_of_models": { + "oneOf": [ + { + "ref": "#components/schemas/FreeFormModel" + }, + { + "ref": "#components/schemas/ModelWithUnionProperty" + } + ], + "nullable": false + }, + "nullable_one_of_models": { + "oneOf": [ + { + "ref": "#components/schemas/FreeFormModel" + }, + { + "ref": "#components/schemas/ModelWithUnionProperty" + } + ], + "nullable": true + }, + "not_required_one_of_models": { + "oneOf": [ + { + "ref": "#components/schemas/FreeFormModel" + }, + { + "ref": "#components/schemas/ModelWithUnionProperty" + } + ], + "nullable": false + }, + "not_required_nullable_one_of_models": { + "oneOf": [ + { + "ref": "#components/schemas/FreeFormModel" + }, + { + "ref": "#components/schemas/ModelWithUnionProperty" + } + ], + "nullable": true } }, "description": "A Model for testing all the ways custom objects can be used ", From f9788d73abcc61cc7c5981e2e3945d539af96169 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Wed, 27 Jan 2021 19:03:01 -0500 Subject: [PATCH 13/50] Make progress toward fixing it --- .../custom_e2e/models/a_model.py | 67 ++++++++++--------- .../custom_e2e/models/a_model_model.py | 9 +-- .../models/a_model_not_required_model.py | 9 +-- .../a_model_not_required_nullable_model.py | 9 +-- .../models/a_model_nullable_model.py | 9 +-- .../models/model_with_any_json_properties.py | 4 +- ...el_with_primitive_additional_properties.py | 8 +-- .../models/model_with_union_property.py | 9 +-- .../my_test_api_client/models/a_model.py | 67 ++++++++++--------- .../models/a_model_model.py | 9 +-- .../models/a_model_not_required_model.py | 9 +-- .../a_model_not_required_nullable_model.py | 9 +-- .../models/a_model_nullable_model.py | 9 +-- .../models/model_with_any_json_properties.py | 4 +- ...el_with_primitive_additional_properties.py | 8 +-- .../models/model_with_union_property.py | 9 +-- .../property_templates/date_property.pyi | 2 +- .../property_templates/datetime_property.pyi | 2 +- .../property_templates/dict_property.pyi | 2 +- .../property_templates/enum_property.pyi | 2 +- .../property_templates/model_property.pyi | 4 +- .../property_templates/union_property.pyi | 11 ++- 22 files changed, 143 insertions(+), 128 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index e3410d097..1355a34d4 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -164,8 +164,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "AModel": d = src_dict.copy() an_enum_value = AnEnum(d.pop("an_enum_value")) - def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.date]: - data = None if isinstance(data, Unset) else data + def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datetime.date]: a_camel_date_time: Union[datetime.datetime, datetime.date] try: a_camel_date_time = isoparse(data) @@ -185,8 +184,7 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat model = AModelModel.from_dict(d.pop("model")) - def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data + def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, ModelWithUnionProperty]: one_of_models: Union[FreeFormModel, ModelWithUnionProperty] try: one_of_models = FreeFormModel.from_dict(data) @@ -214,7 +212,7 @@ def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProper a_nullable_date = None _a_nullable_date = d.pop("a_nullable_date") - if _a_nullable_date is not None: + if _a_nullable_date is not None and not isinstance(_a_nullable_date, Unset): a_nullable_date = isoparse(cast(str, _a_nullable_date)).date() attr_1_leading_digit = d.pop("1_leading_digit", UNSET) @@ -227,24 +225,25 @@ def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProper nullable_model = None _nullable_model = d.pop("nullable_model") - if _nullable_model is not None: - nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) + if _nullable_model is not None and not isinstance(_nullable_model, Unset): + nullable_model = AModelNullableModel.from_dict(_nullable_model) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET _not_required_model = d.pop("not_required_model", UNSET) - if not isinstance(_not_required_model, Unset): - not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) + if _not_required_model is not None and not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(_not_required_model) not_required_nullable_model = None _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( - cast(Dict[str, Any], _not_required_nullable_model) - ) + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model) - def _parse_nullable_one_of_models(data: Any) -> Union[None, FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data + def _parse_nullable_one_of_models( + data: Union[None, Dict[str, Any]] + ) -> Union[None, FreeFormModel, ModelWithUnionProperty]: nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] + if data is None: + return data try: nullable_one_of_models = FreeFormModel.from_dict(data) @@ -257,52 +256,56 @@ def _parse_nullable_one_of_models(data: Any) -> Union[None, FreeFormModel, Model nullable_one_of_models = _parse_nullable_one_of_models(d.pop("nullable_one_of_models")) - def _parse_not_required_one_of_models(data: Any) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data + def _parse_not_required_one_of_models( + data: Union[Unset, Dict[str, Any]] + ) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] + if isinstance(data, Unset): + return data try: not_required_one_of_models = UNSET _not_required_one_of_models = data - if not isinstance(_not_required_one_of_models, Unset): - not_required_one_of_models = FreeFormModel.from_dict( - cast(Dict[str, Any], _not_required_one_of_models) - ) + if _not_required_one_of_models is not None and not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict(_not_required_one_of_models) return not_required_one_of_models except: # noqa: E722 pass not_required_one_of_models = UNSET _not_required_one_of_models = data - if not isinstance(_not_required_one_of_models, Unset): - not_required_one_of_models = ModelWithUnionProperty.from_dict( - cast(Dict[str, Any], _not_required_one_of_models) - ) + if _not_required_one_of_models is not None and not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict(_not_required_one_of_models) return not_required_one_of_models not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) def _parse_not_required_nullable_one_of_models( - data: Any, + data: Union[Unset, None, Dict[str, Any]] ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] + if data is None: + return data + if isinstance(data, Unset): + return data try: not_required_nullable_one_of_models = UNSET _not_required_nullable_one_of_models = data - if not isinstance(_not_required_nullable_one_of_models, Unset): - not_required_nullable_one_of_models = FreeFormModel.from_dict( - cast(Dict[str, Any], _not_required_nullable_one_of_models) - ) + if _not_required_nullable_one_of_models is not None and not isinstance( + _not_required_nullable_one_of_models, Unset + ): + not_required_nullable_one_of_models = FreeFormModel.from_dict(_not_required_nullable_one_of_models) return not_required_nullable_one_of_models except: # noqa: E722 pass not_required_nullable_one_of_models = UNSET _not_required_nullable_one_of_models = data - if not isinstance(_not_required_nullable_one_of_models, Unset): + if _not_required_nullable_one_of_models is not None and not isinstance( + _not_required_nullable_one_of_models, Unset + ): not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( - cast(Dict[str, Any], _not_required_nullable_one_of_models) + _not_required_nullable_one_of_models ) return not_required_nullable_one_of_models diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py index 0700798c8..724c5f414 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py index a08f547aa..7c9cad150 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py index 52ee2ddc3..00a8de6b4 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py index 2f21cc5ac..09e6558ed 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py index 62481f913..21d57f432 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py @@ -3,7 +3,6 @@ import attr from ..models.model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty -from ..types import Unset @attr.s(auto_attribs=True) @@ -40,9 +39,8 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonProperties": for prop_name, prop_dict in d.items(): def _parse_additional_property( - data: Any, + data: Union[Dict[str, Any], List[Any], str, float, int, bool] ) -> Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool]: - data = None if isinstance(data, Unset) else data additional_property: Union[ ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool ] diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 1ba447347..83feaf044 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Union, cast +from typing import Any, Dict, List, Union import attr @@ -33,10 +33,8 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if not isinstance(_a_date_holder, Unset): - a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( - cast(Dict[str, Any], _a_date_holder) - ) + if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): + a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder) model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( a_date_holder=a_date_holder, diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index 35bc2a853..956ea64b3 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -38,13 +38,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "ModelWithUnionProperty": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -52,7 +53,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index e3410d097..1355a34d4 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -164,8 +164,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "AModel": d = src_dict.copy() an_enum_value = AnEnum(d.pop("an_enum_value")) - def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.date]: - data = None if isinstance(data, Unset) else data + def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datetime.date]: a_camel_date_time: Union[datetime.datetime, datetime.date] try: a_camel_date_time = isoparse(data) @@ -185,8 +184,7 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat model = AModelModel.from_dict(d.pop("model")) - def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data + def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, ModelWithUnionProperty]: one_of_models: Union[FreeFormModel, ModelWithUnionProperty] try: one_of_models = FreeFormModel.from_dict(data) @@ -214,7 +212,7 @@ def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProper a_nullable_date = None _a_nullable_date = d.pop("a_nullable_date") - if _a_nullable_date is not None: + if _a_nullable_date is not None and not isinstance(_a_nullable_date, Unset): a_nullable_date = isoparse(cast(str, _a_nullable_date)).date() attr_1_leading_digit = d.pop("1_leading_digit", UNSET) @@ -227,24 +225,25 @@ def _parse_one_of_models(data: Any) -> Union[FreeFormModel, ModelWithUnionProper nullable_model = None _nullable_model = d.pop("nullable_model") - if _nullable_model is not None: - nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) + if _nullable_model is not None and not isinstance(_nullable_model, Unset): + nullable_model = AModelNullableModel.from_dict(_nullable_model) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET _not_required_model = d.pop("not_required_model", UNSET) - if not isinstance(_not_required_model, Unset): - not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) + if _not_required_model is not None and not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(_not_required_model) not_required_nullable_model = None _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( - cast(Dict[str, Any], _not_required_nullable_model) - ) + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model) - def _parse_nullable_one_of_models(data: Any) -> Union[None, FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data + def _parse_nullable_one_of_models( + data: Union[None, Dict[str, Any]] + ) -> Union[None, FreeFormModel, ModelWithUnionProperty]: nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] + if data is None: + return data try: nullable_one_of_models = FreeFormModel.from_dict(data) @@ -257,52 +256,56 @@ def _parse_nullable_one_of_models(data: Any) -> Union[None, FreeFormModel, Model nullable_one_of_models = _parse_nullable_one_of_models(d.pop("nullable_one_of_models")) - def _parse_not_required_one_of_models(data: Any) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data + def _parse_not_required_one_of_models( + data: Union[Unset, Dict[str, Any]] + ) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] + if isinstance(data, Unset): + return data try: not_required_one_of_models = UNSET _not_required_one_of_models = data - if not isinstance(_not_required_one_of_models, Unset): - not_required_one_of_models = FreeFormModel.from_dict( - cast(Dict[str, Any], _not_required_one_of_models) - ) + if _not_required_one_of_models is not None and not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict(_not_required_one_of_models) return not_required_one_of_models except: # noqa: E722 pass not_required_one_of_models = UNSET _not_required_one_of_models = data - if not isinstance(_not_required_one_of_models, Unset): - not_required_one_of_models = ModelWithUnionProperty.from_dict( - cast(Dict[str, Any], _not_required_one_of_models) - ) + if _not_required_one_of_models is not None and not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict(_not_required_one_of_models) return not_required_one_of_models not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) def _parse_not_required_nullable_one_of_models( - data: Any, + data: Union[Unset, None, Dict[str, Any]] ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty]: - data = None if isinstance(data, Unset) else data not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] + if data is None: + return data + if isinstance(data, Unset): + return data try: not_required_nullable_one_of_models = UNSET _not_required_nullable_one_of_models = data - if not isinstance(_not_required_nullable_one_of_models, Unset): - not_required_nullable_one_of_models = FreeFormModel.from_dict( - cast(Dict[str, Any], _not_required_nullable_one_of_models) - ) + if _not_required_nullable_one_of_models is not None and not isinstance( + _not_required_nullable_one_of_models, Unset + ): + not_required_nullable_one_of_models = FreeFormModel.from_dict(_not_required_nullable_one_of_models) return not_required_nullable_one_of_models except: # noqa: E722 pass not_required_nullable_one_of_models = UNSET _not_required_nullable_one_of_models = data - if not isinstance(_not_required_nullable_one_of_models, Unset): + if _not_required_nullable_one_of_models is not None and not isinstance( + _not_required_nullable_one_of_models, Unset + ): not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( - cast(Dict[str, Any], _not_required_nullable_one_of_models) + _not_required_nullable_one_of_models ) return not_required_nullable_one_of_models diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py index 0700798c8..724c5f414 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py index a08f547aa..7c9cad150 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py index 52ee2ddc3..00a8de6b4 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py index 2f21cc5ac..09e6558ed 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -40,13 +40,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -54,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py index 62481f913..21d57f432 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py @@ -3,7 +3,6 @@ import attr from ..models.model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty -from ..types import Unset @attr.s(auto_attribs=True) @@ -40,9 +39,8 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonProperties": for prop_name, prop_dict in d.items(): def _parse_additional_property( - data: Any, + data: Union[Dict[str, Any], List[Any], str, float, int, bool] ) -> Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool]: - data = None if isinstance(data, Unset) else data additional_property: Union[ ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool ] diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 1ba447347..83feaf044 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Union, cast +from typing import Any, Dict, List, Union import attr @@ -33,10 +33,8 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) - if not isinstance(_a_date_holder, Unset): - a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( - cast(Dict[str, Any], _a_date_holder) - ) + if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): + a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder) model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( a_date_holder=a_date_holder, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index 35bc2a853..956ea64b3 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -38,13 +38,14 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "ModelWithUnionProperty": d = src_dict.copy() - def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: - data = None if isinstance(data, Unset) else data + def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: a_property: Union[Unset, AnEnum, AnIntEnum] + if isinstance(data, Unset): + return data try: a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnEnum(_a_property) return a_property @@ -52,7 +53,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]: pass a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and not isinstance(_a_property, Unset): a_property = AnIntEnum(_a_property) return a_property diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index bc2cae912..f73df9437 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None: +if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): {{ property.python_name }} = isoparse(cast(str, _{{ property.python_name }})).date() {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index 91ce0cacc..88f370b32 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -9,7 +9,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None: +if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): {{ property.python_name }} = isoparse(cast(str, _{{ property.python_name }})) {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/dict_property.pyi b/openapi_python_client/templates/property_templates/dict_property.pyi index 36a6b4292..ca16cb538 100644 --- a/openapi_python_client/templates/property_templates/dict_property.pyi +++ b/openapi_python_client/templates/property_templates/dict_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None: +if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): {{ property.python_name }} = _{{ property.python_name }} {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 831f633d5..3bf16564e 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None: +if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): {{ property.python_name }} = {{ property.reference.class_name }}(_{{ property.python_name }}) {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index 6aef71d0f..ebbba35bb 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -10,8 +10,8 @@ {{ property.python_name }}: {{ property.get_type_string() }} = UNSET {% endif %} _{{ property.python_name }} = {{source}} -if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{% if property.nullable and not property.required %} and {% endif %}{% if not property.required %}not isinstance(_{{ property.python_name }}, Unset){% endif %}: - {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(cast(Dict[str, Any], _{{ property.python_name }})) +if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): + {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(_{{ property.python_name }}) {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 509c7f34e..d493cb6ba 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -1,7 +1,14 @@ {% macro construct(property, source, initial_value=None) %} -def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string() }}: - data = None if isinstance(data, Unset) else data +def _parse_{{ property.python_name }}(data: {{ property.get_type_string(json=True) }}) -> {{ property.get_type_string() }}: {{ property.python_name }}: {{ property.get_type_string() }} + {% if "None" in property.get_type_string(json=True) %} + if data is None: + return data + {% endif %} + {% if "Unset" in property.get_type_string(json=True) %} + if isinstance(data, Unset): + return data + {% endif %} {% for inner_property in property.inner_properties_with_template() %} {% if not loop.last or property.has_properties_without_templates %} try: From 55e16f3031da0ba491cbc9c89ea93596296f4133 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Thu, 28 Jan 2021 08:07:49 -0500 Subject: [PATCH 14/50] feat: Change optional Open API query parameters to allow `None (#40) --- .../api/tests/defaults_tests_defaults_post.py | 100 +++++--- ...tional_value_tests_optional_query_param.py | 9 +- .../custom_e2e/models/a_model.py | 10 +- .../custom_e2e/models/a_model_model.py | 6 +- .../models/a_model_not_required_model.py | 6 +- .../a_model_not_required_nullable_model.py | 6 +- .../models/a_model_nullable_model.py | 6 +- ...el_with_primitive_additional_properties.py | 4 +- .../models/model_with_union_property.py | 6 +- .../golden-record-custom/custom_e2e/types.py | 5 +- .../api/tests/defaults_tests_defaults_post.py | 218 +++++++++++------- ...tional_value_tests_optional_query_param.py | 17 +- .../my_test_api_client/models/a_model.py | 10 +- .../models/a_model_model.py | 6 +- .../models/a_model_not_required_model.py | 6 +- .../a_model_not_required_nullable_model.py | 6 +- .../models/a_model_nullable_model.py | 6 +- ...el_with_primitive_additional_properties.py | 4 +- .../models/model_with_union_property.py | 6 +- .../golden-record/my_test_api_client/types.py | 5 +- end_to_end_tests/openapi.json | 41 +++- .../parser/properties/__init__.py | 62 +++-- .../parser/properties/enum_property.py | 14 +- .../parser/properties/model_property.py | 13 +- .../parser/properties/property.py | 48 +++- .../templates/endpoint_macros.pyi | 8 +- .../property_templates/date_property.pyi | 6 +- .../property_templates/datetime_property.pyi | 6 +- .../property_templates/enum_property.pyi | 10 +- .../property_templates/file_property.pyi | 6 +- .../property_templates/list_property.pyi | 8 +- .../property_templates/model_property.pyi | 6 +- .../property_templates/union_property.pyi | 10 +- openapi_python_client/templates/types.py | 5 +- pyproject.toml | 3 +- .../test_parser/test_properties/test_init.py | 141 ++++++----- .../test_properties/test_model_property.py | 4 +- .../test_date_property/optional_nullable.py | 2 +- 38 files changed, 506 insertions(+), 329 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index f87ad3e1b..d61560254 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -7,7 +7,7 @@ Client = httpx.Client import datetime -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union from dateutil.parser import isoparse @@ -41,65 +41,101 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def httpx_request( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: - json_datetime_prop: Union[Unset, str] = UNSET - if not isinstance(datetime_prop, Unset): - json_datetime_prop = datetime_prop.isoformat() + json_not_required_not_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_not_nullable_datetime_prop, Unset): + json_not_required_not_nullable_datetime_prop = ( + not_required_not_nullable_datetime_prop.isoformat() if not_required_not_nullable_datetime_prop else None + ) - json_date_prop: Union[Unset, str] = UNSET + json_not_required_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_nullable_datetime_prop, Unset): + json_not_required_nullable_datetime_prop = ( + not_required_nullable_datetime_prop.isoformat() if not_required_nullable_datetime_prop else None + ) + + json_required_not_nullable_datetime_prop = required_not_nullable_datetime_prop.isoformat() + + json_required_nullable_datetime_prop = ( + required_nullable_datetime_prop.isoformat() if required_nullable_datetime_prop else None + ) + + json_date_prop: Union[Unset, None, str] = UNSET if not isinstance(date_prop, Unset): - json_date_prop = date_prop.isoformat() + json_date_prop = date_prop.isoformat() if date_prop else None - json_list_prop: Union[Unset, List[Any]] = UNSET + json_list_prop: Union[Unset, None, List[Any]] = UNSET if not isinstance(list_prop, Unset): - json_list_prop = [] - for list_prop_item_data in list_prop: - list_prop_item = list_prop_item_data.value + if list_prop is None: + json_list_prop = None + else: + json_list_prop = [] + for list_prop_item_data in list_prop: + list_prop_item = list_prop_item_data.value - json_list_prop.append(list_prop_item) + json_list_prop.append(list_prop_item) - json_union_prop: Union[Unset, float, str] + json_union_prop: Union[Unset, None, float, str] if isinstance(union_prop, Unset): json_union_prop = UNSET + elif union_prop is None: + json_union_prop = None else: json_union_prop = union_prop - json_union_prop_with_ref: Union[Unset, float, AnEnum] + json_union_prop_with_ref: Union[Unset, None, float, int] if isinstance(union_prop_with_ref, Unset): json_union_prop_with_ref = UNSET + elif union_prop_with_ref is None: + json_union_prop_with_ref = None elif isinstance(union_prop_with_ref, AnEnum): json_union_prop_with_ref = UNSET if not isinstance(union_prop_with_ref, Unset): - json_union_prop_with_ref = union_prop_with_ref + json_union_prop_with_ref = union_prop_with_ref.value else: json_union_prop_with_ref = union_prop_with_ref - json_enum_prop: Union[Unset, AnEnum] = UNSET + json_enum_prop: Union[Unset, None, int] = UNSET if not isinstance(enum_prop, Unset): - json_enum_prop = enum_prop + json_enum_prop = enum_prop.value if enum_prop else None - json_model_prop: Union[Unset, Dict[str, Any]] = UNSET + json_model_prop: Union[Unset, None, Dict[str, Any]] = UNSET if not isinstance(model_prop, Unset): - json_model_prop = model_prop.to_dict() + json_model_prop = model_prop.to_dict() if model_prop else None - params: Dict[str, Any] = {} + params: Dict[str, Any] = { + "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, + } if not isinstance(string_prop, Unset) and string_prop is not None: params["string_prop"] = string_prop - if not isinstance(json_datetime_prop, Unset) and json_datetime_prop is not None: - params["datetime_prop"] = json_datetime_prop + if ( + not isinstance(json_not_required_not_nullable_datetime_prop, Unset) + and json_not_required_not_nullable_datetime_prop is not None + ): + params["not_required_not_nullable_datetime_prop"] = json_not_required_not_nullable_datetime_prop + if ( + not isinstance(json_not_required_nullable_datetime_prop, Unset) + and json_not_required_nullable_datetime_prop is not None + ): + params["not_required_nullable_datetime_prop"] = json_not_required_nullable_datetime_prop + if json_required_nullable_datetime_prop is not None: + params["required_nullable_datetime_prop"] = json_required_nullable_datetime_prop if not isinstance(json_date_prop, Unset) and json_date_prop is not None: params["date_prop"] = json_date_prop if not isinstance(float_prop, Unset) and float_prop is not None: diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index 616dc4252..279ce8ca8 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -36,12 +36,15 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def httpx_request( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: - json_query_param: Union[Unset, List[Any]] = UNSET + json_query_param: Union[Unset, None, List[Any]] = UNSET if not isinstance(query_param, Unset): - json_query_param = query_param + if query_param is None: + json_query_param = None + else: + json_query_param = query_param params: Dict[str, Any] = {} if not isinstance(json_query_param, Unset) and json_query_param is not None: diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 15a7cc68c..9462c38b9 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -27,10 +27,10 @@ class AModel: nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET - not_required_nullable: Union[Unset, Optional[str]] = UNSET + not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET - not_required_nullable_model: Union[Optional[AModelNotRequiredNullableModel], Unset] = UNSET + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -68,7 +68,7 @@ def to_dict(self) -> Dict[str, Any]: if not isinstance(self.not_required_model, Unset): not_required_model = self.not_required_model.to_dict() - not_required_nullable_model: Union[None, Unset, Dict[str, Any]] = UNSET + not_required_nullable_model: Union[Unset, None, Dict[str, Any]] = UNSET if not isinstance(self.not_required_nullable_model, Unset): not_required_nullable_model = ( self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None @@ -158,7 +158,7 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat if _nullable_model is not None: nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET _not_required_model = d.pop("not_required_model", UNSET) if not isinstance(_not_required_model, Unset): not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py index c1a00c152..0700798c8 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -15,18 +15,18 @@ class AModelModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py index adecb4225..a08f547aa 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -15,18 +15,18 @@ class AModelNotRequiredModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py index 9de2e3798..52ee2ddc3 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -15,18 +15,18 @@ class AModelNotRequiredNullableModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py index cbcf120f8..2f21cc5ac 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -15,18 +15,18 @@ class AModelNullableModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 797c1ce31..1ba447347 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -12,7 +12,7 @@ class ModelWithPrimitiveAdditionalProperties: """ """ - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -31,7 +31,7 @@ def to_dict(self) -> Dict[str, Any]: @staticmethod def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index cbecc7c90..35bc2a853 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -14,18 +14,18 @@ class ModelWithUnionProperty: a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update({}) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/types.py b/end_to_end_tests/golden-record-custom/custom_e2e/types.py index 2061b9f08..a354a2192 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/types.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/types.py @@ -11,6 +11,9 @@ def __bool__(self) -> bool: UNSET: Unset = Unset() +# Used as `FileProperty._json_type_string` +FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]] + @attr.s(auto_attribs=True) class File: @@ -20,7 +23,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]: + def to_tuple(self) -> FileJsonType: """ Return a tuple representation that httpx will accept for multipart/form-data """ return self.file_name, self.payload, self.mime_type diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index ff6ef2409..f87317ead 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -14,68 +14,104 @@ def _get_kwargs( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Dict[str, Any]: url = "{}/tests/defaults".format(client.base_url) headers: Dict[str, Any] = client.get_headers() - json_datetime_prop: Union[Unset, str] = UNSET - if not isinstance(datetime_prop, Unset): - json_datetime_prop = datetime_prop.isoformat() + json_not_required_not_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_not_nullable_datetime_prop, Unset): + json_not_required_not_nullable_datetime_prop = ( + not_required_not_nullable_datetime_prop.isoformat() if not_required_not_nullable_datetime_prop else None + ) + + json_not_required_nullable_datetime_prop: Union[Unset, None, str] = UNSET + if not isinstance(not_required_nullable_datetime_prop, Unset): + json_not_required_nullable_datetime_prop = ( + not_required_nullable_datetime_prop.isoformat() if not_required_nullable_datetime_prop else None + ) + + json_required_not_nullable_datetime_prop = required_not_nullable_datetime_prop.isoformat() - json_date_prop: Union[Unset, str] = UNSET + json_required_nullable_datetime_prop = ( + required_nullable_datetime_prop.isoformat() if required_nullable_datetime_prop else None + ) + + json_date_prop: Union[Unset, None, str] = UNSET if not isinstance(date_prop, Unset): - json_date_prop = date_prop.isoformat() + json_date_prop = date_prop.isoformat() if date_prop else None - json_list_prop: Union[Unset, List[Any]] = UNSET + json_list_prop: Union[Unset, None, List[Any]] = UNSET if not isinstance(list_prop, Unset): - json_list_prop = [] - for list_prop_item_data in list_prop: - list_prop_item = list_prop_item_data.value + if list_prop is None: + json_list_prop = None + else: + json_list_prop = [] + for list_prop_item_data in list_prop: + list_prop_item = list_prop_item_data.value - json_list_prop.append(list_prop_item) + json_list_prop.append(list_prop_item) - json_union_prop: Union[Unset, float, str] + json_union_prop: Union[Unset, None, float, str] if isinstance(union_prop, Unset): json_union_prop = UNSET + elif union_prop is None: + json_union_prop = None else: json_union_prop = union_prop - json_union_prop_with_ref: Union[Unset, float, AnEnum] + json_union_prop_with_ref: Union[Unset, None, float, int] if isinstance(union_prop_with_ref, Unset): json_union_prop_with_ref = UNSET + elif union_prop_with_ref is None: + json_union_prop_with_ref = None elif isinstance(union_prop_with_ref, AnEnum): json_union_prop_with_ref = UNSET if not isinstance(union_prop_with_ref, Unset): - json_union_prop_with_ref = union_prop_with_ref + json_union_prop_with_ref = union_prop_with_ref.value else: json_union_prop_with_ref = union_prop_with_ref - json_enum_prop: Union[Unset, AnEnum] = UNSET + json_enum_prop: Union[Unset, None, int] = UNSET if not isinstance(enum_prop, Unset): - json_enum_prop = enum_prop + json_enum_prop = enum_prop.value if enum_prop else None - json_model_prop: Union[Unset, Dict[str, Any]] = UNSET + json_model_prop: Union[Unset, None, Dict[str, Any]] = UNSET if not isinstance(model_prop, Unset): - json_model_prop = model_prop.to_dict() + json_model_prop = model_prop.to_dict() if model_prop else None - params: Dict[str, Any] = {} + params: Dict[str, Any] = { + "required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop, + } if not isinstance(string_prop, Unset) and string_prop is not None: params["string_prop"] = string_prop - if not isinstance(json_datetime_prop, Unset) and json_datetime_prop is not None: - params["datetime_prop"] = json_datetime_prop + if ( + not isinstance(json_not_required_not_nullable_datetime_prop, Unset) + and json_not_required_not_nullable_datetime_prop is not None + ): + params["not_required_not_nullable_datetime_prop"] = json_not_required_not_nullable_datetime_prop + if ( + not isinstance(json_not_required_nullable_datetime_prop, Unset) + and json_not_required_nullable_datetime_prop is not None + ): + params["not_required_nullable_datetime_prop"] = json_not_required_nullable_datetime_prop + if json_required_nullable_datetime_prop is not None: + params["required_nullable_datetime_prop"] = json_required_nullable_datetime_prop if not isinstance(json_date_prop, Unset) and json_date_prop is not None: params["date_prop"] = json_date_prop if not isinstance(float_prop, Unset) and float_prop is not None: @@ -128,22 +164,28 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def sync_detailed( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -165,24 +207,30 @@ def sync_detailed( def sync( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ return sync_detailed( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -198,22 +246,28 @@ def sync( async def asyncio_detailed( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, @@ -234,17 +288,20 @@ async def asyncio_detailed( async def asyncio( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, - model_prop: Union[ModelWithUnionProperty, Unset] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + not_required_not_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + not_required_nullable_datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + required_not_nullable_datetime_prop: datetime.datetime = isoparse("1010-10-10T00:00:00"), + required_nullable_datetime_prop: Optional[datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = UNSET, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = UNSET, + model_prop: Union[Unset, None, ModelWithUnionProperty] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -252,7 +309,10 @@ async def asyncio( await asyncio_detailed( client=client, string_prop=string_prop, - datetime_prop=datetime_prop, + not_required_not_nullable_datetime_prop=not_required_not_nullable_datetime_prop, + not_required_nullable_datetime_prop=not_required_nullable_datetime_prop, + required_not_nullable_datetime_prop=required_not_nullable_datetime_prop, + required_nullable_datetime_prop=required_nullable_datetime_prop, date_prop=date_prop, float_prop=float_prop, int_prop=int_prop, diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 576a770fe..23bd9e741 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -10,15 +10,18 @@ def _get_kwargs( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Dict[str, Any]: url = "{}/tests/optional_query_param/".format(client.base_url) headers: Dict[str, Any] = client.get_headers() - json_query_param: Union[Unset, List[Any]] = UNSET + json_query_param: Union[Unset, None, List[Any]] = UNSET if not isinstance(query_param, Unset): - json_query_param = query_param + if query_param is None: + json_query_param = None + else: + json_query_param = query_param params: Dict[str, Any] = {} if not isinstance(json_query_param, Unset) and json_query_param is not None: @@ -57,7 +60,7 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def sync_detailed( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -74,7 +77,7 @@ def sync_detailed( def sync( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ Test optional query parameters """ @@ -87,7 +90,7 @@ def sync( async def asyncio_detailed( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -103,7 +106,7 @@ async def asyncio_detailed( async def asyncio( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = UNSET, ) -> Optional[Union[None, HTTPValidationError]]: """ Test optional query parameters """ diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 15a7cc68c..9462c38b9 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -27,10 +27,10 @@ class AModel: nullable_model: Optional[AModelNullableModel] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET - not_required_nullable: Union[Unset, Optional[str]] = UNSET + not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET - not_required_nullable_model: Union[Optional[AModelNotRequiredNullableModel], Unset] = UNSET + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -68,7 +68,7 @@ def to_dict(self) -> Dict[str, Any]: if not isinstance(self.not_required_model, Unset): not_required_model = self.not_required_model.to_dict() - not_required_nullable_model: Union[None, Unset, Dict[str, Any]] = UNSET + not_required_nullable_model: Union[Unset, None, Dict[str, Any]] = UNSET if not isinstance(self.not_required_nullable_model, Unset): not_required_nullable_model = ( self.not_required_nullable_model.to_dict() if self.not_required_nullable_model else None @@ -158,7 +158,7 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat if _nullable_model is not None: nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model)) - not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET + not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET _not_required_model = d.pop("not_required_model", UNSET) if not isinstance(_not_required_model, Unset): not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model)) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py index c1a00c152..0700798c8 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -15,18 +15,18 @@ class AModelModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py index adecb4225..a08f547aa 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -15,18 +15,18 @@ class AModelNotRequiredModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py index 9de2e3798..52ee2ddc3 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -15,18 +15,18 @@ class AModelNotRequiredNullableModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py index cbcf120f8..2f21cc5ac 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -15,18 +15,18 @@ class AModelNullableModel: additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 797c1ce31..1ba447347 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -12,7 +12,7 @@ class ModelWithPrimitiveAdditionalProperties: """ """ - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -31,7 +31,7 @@ def to_dict(self) -> Dict[str, Any]: @staticmethod def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index cbecc7c90..35bc2a853 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -14,18 +14,18 @@ class ModelWithUnionProperty: a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, AnEnum, AnIntEnum] + a_property: Union[Unset, int] if isinstance(self.a_property, Unset): a_property = UNSET elif isinstance(self.a_property, AnEnum): a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value else: a_property = UNSET if not isinstance(self.a_property, Unset): - a_property = self.a_property + a_property = self.a_property.value field_dict: Dict[str, Any] = {} field_dict.update({}) diff --git a/end_to_end_tests/golden-record/my_test_api_client/types.py b/end_to_end_tests/golden-record/my_test_api_client/types.py index 2061b9f08..a354a2192 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/types.py +++ b/end_to_end_tests/golden-record/my_test_api_client/types.py @@ -11,6 +11,9 @@ def __bool__(self) -> bool: UNSET: Unset = Unset() +# Used as `FileProperty._json_type_string` +FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]] + @attr.s(auto_attribs=True) class File: @@ -20,7 +23,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]: + def to_tuple(self) -> FileJsonType: """ Return a tuple representation that httpx will accept for multipart/form-data """ return self.file_name, self.payload, self.mime_type diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 8562f6796..6d7d15c6c 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -290,12 +290,49 @@ { "required": false, "schema": { - "title": "Datetime Prop", + "title": "Not Required, Not Nullable Datetime Prop", + "nullable": false, "type": "string", "format": "date-time", "default": "1010-10-10T00:00:00" }, - "name": "datetime_prop", + "name": "not_required_not_nullable_datetime_prop", + "in": "query" + }, + { + "required": false, + "schema": { + "title": "Not Required, Nullable Datetime Prop", + "nullable": true, + "type": "string", + "format": "date-time", + "default": "1010-10-10T00:00:00" + }, + "name": "not_required_nullable_datetime_prop", + "in": "query" + }, + { + "required": true, + "schema": { + "title": "Required, Not Nullable Datetime Prop", + "nullable": false, + "type": "string", + "format": "date-time", + "default": "1010-10-10T00:00:00" + }, + "name": "required_not_nullable_datetime_prop", + "in": "query" + }, + { + "required": true, + "schema": { + "title": "Required, Nullable Datetime Prop", + "nullable": true, + "type": "string", + "format": "date-time", + "default": "1010-10-10T00:00:00" + }, + "name": "required_nullable_datetime_prop", "in": "query" }, { diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index f6289ce7c..b84166f23 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -19,6 +19,7 @@ class NoneProperty(Property): """ A property that is always None (used for empty schemas) """ _type_string: ClassVar[str] = "None" + _json_type_string: ClassVar[str] = "None" template: ClassVar[Optional[str]] = "none_property.pyi" @@ -29,6 +30,7 @@ class StringProperty(Property): max_length: Optional[int] = None pattern: Optional[str] = None _type_string: ClassVar[str] = "str" + _json_type_string: ClassVar[str] = "str" @attr.s(auto_attribs=True, frozen=True) @@ -38,6 +40,7 @@ class DateTimeProperty(Property): """ _type_string: ClassVar[str] = "datetime.datetime" + _json_type_string: ClassVar[str] = "str" template: ClassVar[str] = "datetime_property.pyi" def get_imports(self, *, prefix: str) -> Set[str]: @@ -58,6 +61,7 @@ class DateProperty(Property): """ A property of type datetime.date """ _type_string: ClassVar[str] = "datetime.date" + _json_type_string: ClassVar[str] = "str" template: ClassVar[str] = "date_property.pyi" def get_imports(self, *, prefix: str) -> Set[str]: @@ -78,6 +82,8 @@ class FileProperty(Property): """ A property used for uploading files """ _type_string: ClassVar[str] = "File" + # Return type of File.to_tuple() + _json_type_string: ClassVar[str] = "Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]" template: ClassVar[str] = "file_property.pyi" def get_imports(self, *, prefix: str) -> Set[str]: @@ -98,6 +104,7 @@ class FloatProperty(Property): """ A property of type float """ _type_string: ClassVar[str] = "float" + _json_type_string: ClassVar[str] = "float" @attr.s(auto_attribs=True, frozen=True) @@ -105,6 +112,7 @@ class IntProperty(Property): """ A property of type int """ _type_string: ClassVar[str] = "int" + _json_type_string: ClassVar[str] = "int" @attr.s(auto_attribs=True, frozen=True) @@ -112,6 +120,7 @@ class BooleanProperty(Property): """ Property for bool """ _type_string: ClassVar[str] = "bool" + _json_type_string: ClassVar[str] = "bool" InnerProp = TypeVar("InnerProp", bound=Property) @@ -122,18 +131,11 @@ class ListProperty(Property, Generic[InnerProp]): """ A property representing a list (array) of other properties """ inner_property: InnerProp + _json_type_string: ClassVar[str] = "List[Any]" template: ClassVar[str] = "list_property.pyi" - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - type_string = f"List[{self.inner_property.get_type_string()}]" - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + def get_base_type_string(self) -> str: + return f"List[{self.inner_property.get_type_string()}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" @@ -167,18 +169,38 @@ def __attrs_post_init__(self) -> None: self, "has_properties_without_templates", any(prop.template is None for prop in self.inner_properties) ) - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - inner_types = [p.get_type_string(no_optional=True) for p in self.inner_properties] - inner_prop_string = ", ".join(inner_types) - type_string = f"Union[{inner_prop_string}]" + def _get_inner_prop_string(self, json: bool = False) -> str: + inner_types = [p.get_type_string(no_optional=True, json=json) for p in self.inner_properties] + unique_inner_types = list(dict.fromkeys(inner_types)) + return ", ".join(unique_inner_types) + + def get_base_type_string(self, json: bool = False) -> str: + return f"Union[{self._get_inner_prop_string(json=json)}]" + + def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str: + """ + Get a string representation of type that should be used when declaring this property. + + This implementation differs slightly from `Property.get_type_string` in order to collapse + nested union types. + """ + type_string = self.get_base_type_string(json=json) if no_optional: return type_string - if not self.required: - type_string = f"Union[Unset, {inner_prop_string}]" - if self.nullable: - type_string = f"Optional[{type_string}]" - return type_string + if self.required: + if self.nullable: + return f"Union[None, {self._get_inner_prop_string(json=json)}]" + else: + return type_string + else: + if self.nullable: + return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]" + else: + if query_parameter: + # For query parameters, None has the same meaning as Unset + return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]" + else: + return f"Union[Unset, {self._get_inner_prop_string(json=json)}]" def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/enum_property.py b/openapi_python_client/parser/properties/enum_property.py index 1217f23ee..6938dd716 100644 --- a/openapi_python_client/parser/properties/enum_property.py +++ b/openapi_python_client/parser/properties/enum_property.py @@ -18,21 +18,13 @@ class EnumProperty(Property): values: Dict[str, ValueType] reference: Reference value_type: Type[ValueType] + _json_type_string: ClassVar[str] = "int" default: Optional[Any] = attr.ib() template: ClassVar[str] = "enum_property.pyi" - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - - type_string = self.reference.class_name - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + def get_base_type_string(self) -> str: + return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 4bcbe4695..c4c203a5d 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -25,6 +25,7 @@ class ModelProperty(Property): description: str relative_imports: Set[str] additional_properties: Union[bool, Property] + _json_type_string: ClassVar[str] = "Dict[str, Any]" template: ClassVar[str] = "model_property.pyi" json_is_dict: ClassVar[bool] = True @@ -72,16 +73,8 @@ def resolve_references( return schemas - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - type_string = self.reference.class_name - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[{type_string}, Unset]" - return type_string + def get_base_type_string(self) -> str: + return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index a94af72ba..c0ec0d56e 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -24,6 +24,7 @@ class Property: required: bool nullable: bool _type_string: ClassVar[str] = "" + _json_type_string: ClassVar[str] = "" # Type of the property after JSON serialization default: Optional[str] = attr.ib() python_name: str = attr.ib(init=False) @@ -33,21 +34,39 @@ class Property: def __attrs_post_init__(self) -> None: object.__setattr__(self, "python_name", utils.to_valid_python_identifier(utils.snake_case(self.name))) - def get_type_string(self, no_optional: bool = False) -> str: + def get_base_type_string(self) -> str: + return self._type_string + + def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str: """ Get a string representation of type that should be used when declaring this property Args: no_optional: Do not include Optional or Unset even if the value is optional (needed for isinstance checks) + query_parameter: True if the property's type is being used for a query parameter + json: True if the type refers to the property after JSON serialization """ - type_string = self._type_string + if json: + type_string = self._json_type_string + else: + type_string = self.get_base_type_string() + if no_optional: - return self._type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + return type_string + if self.required: + if self.nullable: + return f"Optional[{type_string}]" + else: + return type_string + else: + if self.nullable: + return f"Union[Unset, None, {type_string}]" + else: + if query_parameter: + # For query parameters, None has the same meaning as Unset + return f"Union[Unset, None, {type_string}]" + else: + return f"Union[Unset, {type_string}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" @@ -70,8 +89,13 @@ def get_imports(self, *, prefix: str) -> Set[str]: imports.add(f"from {prefix}types import UNSET, Unset") return imports - def to_string(self) -> str: - """ How this should be declared in a dataclass """ + def to_string(self, query_parameter: bool = False) -> str: + """ + How this should be declared in a dataclass + + Args: + query_parameter: True if the property's type is being used for a query parameter + """ default: Optional[str] if self.default is not None: default = self.default @@ -81,6 +105,6 @@ def to_string(self) -> str: default = None if default is not None: - return f"{self.python_name}: {self.get_type_string()} = {default}" + return f"{self.python_name}: {self.get_type_string(query_parameter=query_parameter)} = {default}" else: - return f"{self.python_name}: {self.get_type_string()}" + return f"{self.python_name}: {self.get_type_string(query_parameter=query_parameter)}" diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 8d3d464c3..6586ecd70 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -17,12 +17,12 @@ if {{ parameter.python_name }} is not UNSET: {% set destination = "json_" + property.python_name %} {% if property.template %} {% from "property_templates/" + property.template import transform %} -{{ transform(property, property.python_name, destination) }} +{{ transform(property, property.python_name, destination, query_parameter=True) }} {% endif %} {% endfor %} params: Dict[str, Any] = { {% for property in endpoint.query_parameters %} - {% if property.required %} + {% if property.required and not property.nullable %} {% if property.template %} "{{ property.name }}": {{ "json_" + property.python_name }}, {% else %} @@ -32,7 +32,7 @@ params: Dict[str, Any] = { {% endfor %} } {% for property in endpoint.query_parameters %} - {% if not property.required %} + {% if not property.required or property.nullable %} {% set property_name = "json_" + property.python_name if property.template else property.python_name %} if {% if not property.required %}not isinstance({{ property_name }}, Unset) and {% endif %}{{ property_name }} is not None: {% if property.json_is_dict %} @@ -97,7 +97,7 @@ json_body: {{ endpoint.json_body.get_type_string() }}, {% endif %} {# query parameters #} {% for parameter in endpoint.query_parameters %} -{{ parameter.to_string() }}, +{{ parameter.to_string(query_parameter=True) }}, {% endfor %} {% for parameter in endpoint.header_parameters %} {{ parameter.to_string() }}, diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index a3a980c8f..bc2cae912 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -9,13 +9,13 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {{ destination }} = {{ source }}.isoformat() {% if property.nullable %}if {{ source }} else None {%endif%} {% else %} -{{ destination }}{% if declare_type %}: Union[Unset, str]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.isoformat() diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index b8e1b8ff0..91ce0cacc 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -14,7 +14,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None @@ -22,9 +22,9 @@ if _{{ property.python_name }} is not None: {{ destination }} = {{ source }}.isoformat() {% endif %} {% else %} -{{ destination }}{% if declare_type %}: Union[Unset, str]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.isoformat() diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 4765a6fd5..831f633d5 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -9,7 +9,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.value if {{ source }} else None @@ -17,12 +17,12 @@ if _{{ property.python_name }} is not None: {{ destination }} = {{ source }}.value {% endif %} {% else %} -{{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} - {{ destination }} = {{ source }} if {{ source }} else None +{% if property.nullable or query_parameter %} + {{ destination }} = {{ source }}.value if {{ source }} else None {% else %} - {{ destination }} = {{ source }} + {{ destination }} = {{ source }}.value {% endif %} {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/file_property.pyi b/openapi_python_client/templates/property_templates/file_property.pyi index ffa3c20d9..50a331851 100644 --- a/openapi_python_client/templates/property_templates/file_property.pyi +++ b/openapi_python_client/templates/property_templates/file_property.pyi @@ -4,7 +4,7 @@ ) {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None @@ -12,9 +12,9 @@ {{ destination }} = {{ source }}.to_tuple() {% endif %} {% else %} -{{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.to_tuple() diff --git a/openapi_python_client/templates/property_templates/list_property.pyi b/openapi_python_client/templates/property_templates/list_property.pyi index d05a13960..5f58bcd30 100644 --- a/openapi_python_client/templates/property_templates/list_property.pyi +++ b/openapi_python_client/templates/property_templates/list_property.pyi @@ -32,7 +32,7 @@ for {{ inner_source }} in {{ source }}: {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% set inner_property = property.inner_property %} {% if property.required %} {% if property.nullable %} @@ -44,13 +44,13 @@ else: {{ _transform(property, source, destination) }} {% endif %} {% else %} -{{ destination }}{% if declare_type %}: Union[Unset, List[Any]]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} if {{ source }} is None: {{ destination }} = None else: - {{ _transform(property, source, destination) | indent(4)}} + {{ _transform(property, source, destination) | indent(8)}} {% else %} {{ _transform(property, source, destination) | indent(4)}} {% endif %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index b41289409..6aef71d0f 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -15,7 +15,7 @@ if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{ {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None @@ -23,9 +23,9 @@ if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{ {{ destination }} = {{ source }}.to_dict() {% endif %} {% else %} -{{ destination }}{% if declare_type %}: Union[{% if property.nullable %}None, {% endif %}Unset, Dict[str, Any]]{% endif %} = UNSET +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable %} +{% if property.nullable or query_parameter %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.to_dict() diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 4c632c60a..509c7f34e 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -24,20 +24,20 @@ def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string( {{ property.python_name }} = _parse_{{ property.python_name }}({{ source }}) {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} -{% if not property.required %} -{{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} +{% if not property.required or property.nullable %} +{{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} if isinstance({{ source }}, Unset): {{ destination }} = UNSET {% endif %} -{% if property.nullable %} +{% if property.nullable or (query_parameter and not property.required) %} {% if property.required %} if {{ source }} is None: {% else %}{# There's an if UNSET statement before this #} elif {{ source }} is None: {% endif %} - {{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = None + {{ destination }} = None {% endif %} {% for inner_property in property.inner_properties_with_template() %} {% if loop.first and property.required and not property.nullable %}{# No if UNSET or if None statement before this #} diff --git a/openapi_python_client/templates/types.py b/openapi_python_client/templates/types.py index 2061b9f08..a354a2192 100644 --- a/openapi_python_client/templates/types.py +++ b/openapi_python_client/templates/types.py @@ -11,6 +11,9 @@ def __bool__(self) -> bool: UNSET: Unset = Unset() +# Used as `FileProperty._json_type_string` +FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]] + @attr.s(auto_attribs=True) class File: @@ -20,7 +23,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]: + def to_tuple(self) -> FileJsonType: """ Return a tuple representation that httpx will accept for multipart/form-data """ return self.file_name, self.payload, self.mime_type diff --git a/pyproject.toml b/pyproject.toml index 222b69561..4d74fea82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,8 +55,9 @@ isort .\ && flake8 openapi_python_client\ && safety check --bare\ && mypy openapi_python_client\ - && pytest --cov openapi_python_client tests --cov-report=term-missing\ + && task unit\ """ +unit = "pytest --cov openapi_python_client tests --cov-report=term-missing" regen = "python -m end_to_end_tests.regen_golden_record" regen_custom = "python -m end_to_end_tests.regen_golden_record custom" e2e = "pytest openapi_python_client end_to_end_tests/test_end_to_end.py" diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 2f3c13676..604b1bd1d 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -16,45 +16,55 @@ class TestProperty: - def test_get_type_string(self, mocker): + @pytest.mark.parametrize( + "query_parameter,nullable,required,no_optional,expected", + [ + (False, False, False, False, "Union[Unset, TestType]"), + (False, False, False, True, "TestType"), + (False, False, True, False, "TestType"), + (False, False, True, True, "TestType"), + (False, True, False, False, "Union[Unset, None, TestType]"), + (False, True, False, True, "TestType"), + (False, True, True, False, "Optional[TestType]"), + (False, True, True, True, "TestType"), + (True, False, False, False, "Union[Unset, None, TestType]"), + (True, False, False, True, "TestType"), + (True, False, True, False, "TestType"), + (True, False, True, True, "TestType"), + (True, True, False, False, "Union[Unset, None, TestType]"), + (True, True, False, True, "TestType"), + (True, True, True, False, "Optional[TestType]"), + (True, True, True, True, "TestType"), + ], + ) + def test_get_type_string(self, mocker, query_parameter, nullable, required, no_optional, expected): from openapi_python_client.parser.properties import Property mocker.patch.object(Property, "_type_string", "TestType") - p = Property(name="test", required=True, default=None, nullable=False) - - base_type_string = f"TestType" - - assert p.get_type_string() == base_type_string + p = Property(name="test", required=required, default=None, nullable=nullable) + assert p.get_type_string(no_optional=no_optional, query_parameter=query_parameter) == expected - p = Property(name="test", required=True, default=None, nullable=True) - assert p.get_type_string() == f"Optional[{base_type_string}]" - assert p.get_type_string(no_optional=True) == base_type_string - - p = Property(name="test", required=False, default=None, nullable=True) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" - assert p.get_type_string(no_optional=True) == base_type_string - - p = Property(name="test", required=False, default=None, nullable=False) - assert p.get_type_string() == f"Union[Unset, {base_type_string}]" - assert p.get_type_string(no_optional=True) == base_type_string - - def test_to_string(self, mocker): + @pytest.mark.parametrize( + "query_parameter,default,required,expected", + [ + (False, None, False, "test: Union[Unset, TestType] = UNSET"), + (False, None, True, "test: TestType"), + (False, "Test", False, "test: Union[Unset, TestType] = Test"), + (False, "Test", True, "test: TestType = Test"), + (True, None, False, "test: Union[Unset, None, TestType] = UNSET"), + (True, None, True, "test: TestType"), + (True, "Test", False, "test: Union[Unset, None, TestType] = Test"), + (True, "Test", True, "test: TestType = Test"), + ], + ) + def test_to_string(self, mocker, query_parameter, default, required, expected): from openapi_python_client.parser.properties import Property name = "test" - get_type_string = mocker.patch.object(Property, "get_type_string") - p = Property(name=name, required=True, default=None, nullable=False) - - assert p.to_string() == f"{name}: {get_type_string()}" - - p = Property(name=name, required=False, default=None, nullable=False) - assert p.to_string() == f"{name}: {get_type_string()} = UNSET" - - p = Property(name=name, required=True, default=None, nullable=False) - assert p.to_string() == f"{name}: {get_type_string()}" + mocker.patch.object(Property, "_type_string", "TestType") + p = Property(name=name, required=required, default=default, nullable=False) - p = Property(name=name, required=True, default="TEST", nullable=False) - assert p.to_string() == f"{name}: {get_type_string()} = TEST" + assert p.to_string(query_parameter=query_parameter) == expected def test_get_imports(self): from openapi_python_client.parser.properties import Property @@ -87,7 +97,7 @@ def test_get_type_string(self): assert p.get_type_string() == f"Optional[{base_type_string}]" p = StringProperty(name="test", required=False, default=None, nullable=True) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" + assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" p = StringProperty(name="test", required=False, default=None, nullable=False) assert p.get_type_string() == f"Union[Unset, {base_type_string}]" @@ -202,7 +212,7 @@ def test_get_type_string(self, mocker): assert p.get_type_string(no_optional=True) == base_type_string p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" + assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False) @@ -242,7 +252,28 @@ def test_get_type_imports(self, mocker): class TestUnionProperty: - def test_get_type_string(self, mocker): + @pytest.mark.parametrize( + "query_parameter,nullable,required,no_optional,expected", + [ + (False, False, False, False, "Union[Unset, inner_type_string_1, inner_type_string_2]"), + (False, False, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, False, True, False, "Union[inner_type_string_1, inner_type_string_2]"), + (False, False, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), + (False, True, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2]"), + (False, True, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, False, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), + (True, False, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, False, True, False, "Union[inner_type_string_1, inner_type_string_2]"), + (True, False, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), + (True, True, False, True, "Union[inner_type_string_1, inner_type_string_2]"), + (True, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2]"), + (True, True, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + ], + ) + def test_get_type_string(self, mocker, query_parameter, nullable, required, no_optional, expected): from openapi_python_client.parser.properties import UnionProperty inner_property_1 = mocker.MagicMock() @@ -251,46 +282,13 @@ def test_get_type_string(self, mocker): inner_property_2.get_type_string.return_value = "inner_type_string_2" p = UnionProperty( name="test", - required=True, - default=None, - inner_properties=[inner_property_1, inner_property_2], - nullable=False, - ) - - base_type_string = f"Union[inner_type_string_1, inner_type_string_2]" - - assert p.get_type_string() == base_type_string - - p = UnionProperty( - name="test", - required=True, - default=None, - inner_properties=[inner_property_1, inner_property_2], - nullable=True, - ) - assert p.get_type_string() == f"Optional[{base_type_string}]" - assert p.get_type_string(no_optional=True) == base_type_string - - base_type_string_with_unset = f"Union[Unset, inner_type_string_1, inner_type_string_2]" - p = UnionProperty( - name="test", - required=False, + required=required, default=None, inner_properties=[inner_property_1, inner_property_2], - nullable=True, + nullable=nullable, ) - assert p.get_type_string() == f"Optional[{base_type_string_with_unset}]" - assert p.get_type_string(no_optional=True) == base_type_string - p = UnionProperty( - name="test", - required=False, - default=None, - inner_properties=[inner_property_1, inner_property_2], - nullable=False, - ) - assert p.get_type_string() == base_type_string_with_unset - assert p.get_type_string(no_optional=True) == base_type_string + assert p.get_type_string(query_parameter=query_parameter, no_optional=no_optional) == expected def test_get_imports(self, mocker): from openapi_python_client.parser.properties import UnionProperty @@ -389,7 +387,7 @@ def test_get_type_string(self, mocker): reference=fake_reference, value_type=str, ) - assert p.get_type_string() == f"Union[Unset, Optional[{base_type_string}]]" + assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string p = properties.EnumProperty( @@ -990,7 +988,6 @@ def test__string_based_property_unsupported_format(self, mocker): def test_build_schemas(mocker): build_model_property = mocker.patch(f"{MODULE_NAME}.build_model_property") in_data = {"1": mocker.MagicMock(enum=None), "2": mocker.MagicMock(enum=None), "3": mocker.MagicMock(enum=None)} - model_1 = mocker.MagicMock() schemas_1 = mocker.MagicMock() model_2 = mocker.MagicMock() diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 421f40d48..83d521ab1 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -4,9 +4,9 @@ @pytest.mark.parametrize( "no_optional,nullable,required,expected", [ - (False, False, False, "Union[MyClass, Unset]"), + (False, False, False, "Union[Unset, MyClass]"), (False, False, True, "MyClass"), - (False, True, False, "Union[Optional[MyClass], Unset]"), + (False, True, False, "Union[Unset, None, MyClass]"), (False, True, True, "Optional[MyClass]"), (True, False, False, "MyClass"), (True, False, True, "MyClass"), diff --git a/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py b/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py index cf8780024..be32cfbd3 100644 --- a/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py +++ b/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py @@ -6,7 +6,7 @@ some_source = date(2020, 10, 12) -some_destination: Union[Unset, str] = UNSET +some_destination: Union[Unset, None, str] = UNSET if not isinstance(some_source, Unset): some_destination = some_source.isoformat() if some_source else None From 8e88fa49e113ac5e726d9698237ac873704ca27a Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Thu, 28 Jan 2021 08:43:11 -0500 Subject: [PATCH 15/50] Refactor --- .../parser/properties/__init__.py | 39 +++++++++++-------- .../property_templates/union_property.pyi | 4 +- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index b84166f23..96d146a4a 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -169,38 +169,43 @@ def __attrs_post_init__(self) -> None: self, "has_properties_without_templates", any(prop.template is None for prop in self.inner_properties) ) - def _get_inner_prop_string(self, json: bool = False) -> str: + def _get_inner_type_strings(self, json: bool = False) -> List[str]: inner_types = [p.get_type_string(no_optional=True, json=json) for p in self.inner_properties] unique_inner_types = list(dict.fromkeys(inner_types)) - return ", ".join(unique_inner_types) + return unique_inner_types def get_base_type_string(self, json: bool = False) -> str: - return f"Union[{self._get_inner_prop_string(json=json)}]" + return f"Union[{', '.join(self._get_inner_type_strings(json=json))}]" - def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str: - """ - Get a string representation of type that should be used when declaring this property. - - This implementation differs slightly from `Property.get_type_string` in order to collapse - nested union types. - """ - type_string = self.get_base_type_string(json=json) + def get_type_strings_in_union(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> List[str]: + type_strings = self._get_inner_type_strings(json=json) if no_optional: - return type_string + return type_strings if self.required: if self.nullable: - return f"Union[None, {self._get_inner_prop_string(json=json)}]" + return ["None"] + type_strings else: - return type_string + return type_strings else: if self.nullable: - return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]" + return ["Unset", "None"] + type_strings else: if query_parameter: # For query parameters, None has the same meaning as Unset - return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]" + return ["Unset", "None"] + type_strings else: - return f"Union[Unset, {self._get_inner_prop_string(json=json)}]" + return ["Unset"] + type_strings + + def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str: + """ + Get a string representation of type that should be used when declaring this property. + + This implementation differs slightly from `Property.get_type_string` in order to collapse + nested union types. + """ + return ( + f"Union[{', '.join(self.get_type_strings_in_union(no_optional=no_optional, query_parameter=query_parameter, json=json))}]" + ) def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index d493cb6ba..0d5f09a07 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -1,11 +1,11 @@ {% macro construct(property, source, initial_value=None) %} def _parse_{{ property.python_name }}(data: {{ property.get_type_string(json=True) }}) -> {{ property.get_type_string() }}: {{ property.python_name }}: {{ property.get_type_string() }} - {% if "None" in property.get_type_string(json=True) %} + {% if "None" in property.get_type_strings_in_union(json=True) %} if data is None: return data {% endif %} - {% if "Unset" in property.get_type_string(json=True) %} + {% if "Unset" in property.get_type_strings_in_union(json=True) %} if isinstance(data, Unset): return data {% endif %} From 915d7c34e84eae602f354b8cdd64af3507fa4a57 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Thu, 28 Jan 2021 09:06:28 -0500 Subject: [PATCH 16/50] Check type --- .../api/tests/defaults_tests_defaults_post.py | 2 - .../custom_e2e/api/tests/get_user_list.py | 4 -- .../api/tests/int_enum_tests_int_enum_post.py | 2 - .../tests/json_body_tests_json_body_post.py | 2 - ...tional_value_tests_optional_query_param.py | 2 - .../api/tests/test_inline_objects.py | 2 - .../tests/upload_file_tests_upload_post.py | 2 - .../custom_e2e/models/a_model.py | 63 ++++++++++--------- .../custom_e2e/models/a_model_model.py | 4 ++ .../models/a_model_not_required_model.py | 4 ++ .../a_model_not_required_nullable_model.py | 4 ++ .../models/a_model_nullable_model.py | 4 ++ .../models/http_validation_error.py | 2 - ...odel_with_additional_properties_inlined.py | 2 - .../models/model_with_any_json_properties.py | 4 +- ...el_with_primitive_additional_properties.py | 2 - .../models/model_with_union_property.py | 4 ++ .../api/tests/defaults_tests_defaults_post.py | 2 - .../api/tests/get_user_list.py | 4 -- .../api/tests/int_enum_tests_int_enum_post.py | 2 - .../tests/json_body_tests_json_body_post.py | 2 - ...tional_value_tests_optional_query_param.py | 2 - .../api/tests/test_inline_objects.py | 2 - .../tests/upload_file_tests_upload_post.py | 2 - .../my_test_api_client/models/a_model.py | 63 ++++++++++--------- .../models/a_model_model.py | 4 ++ .../models/a_model_not_required_model.py | 4 ++ .../a_model_not_required_nullable_model.py | 4 ++ .../models/a_model_nullable_model.py | 4 ++ .../models/http_validation_error.py | 2 - ...odel_with_additional_properties_inlined.py | 2 - .../models/model_with_any_json_properties.py | 4 +- ...el_with_primitive_additional_properties.py | 2 - .../models/model_with_union_property.py | 4 ++ end_to_end_tests/openapi.json | 3 + .../property_templates/date_property.pyi | 2 + .../property_templates/datetime_property.pyi | 2 + .../property_templates/dict_property.pyi | 2 + .../property_templates/enum_property.pyi | 2 + .../property_templates/file_property.pyi | 2 + .../property_templates/list_property.pyi | 2 + .../property_templates/model_property.pyi | 6 +- .../property_templates/none_property.pyi | 2 + .../property_templates/union_property.pyi | 11 +++- 44 files changed, 138 insertions(+), 114 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index 0168a4fed..d61560254 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -23,8 +23,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py index c77035a76..72758fd75 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py @@ -19,16 +19,12 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[List[AModel], response_200 = [] _response_200 = response.json() for response_200_item_data in _response_200: - if not isinstance(response_200_item_data, dict): - raise ValueError("Cannot construct model from value " + str(response_200_item_data)) response_200_item = AModel.from_dict(response_200_item_data) response_200.append(response_200_item) return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py index ec87505f2..855a8d999 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py @@ -18,8 +18,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/json_body_tests_json_body_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/json_body_tests_json_body_post.py index e9aaa3b81..30f80e33d 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/json_body_tests_json_body_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/json_body_tests_json_body_post.py @@ -16,8 +16,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index c4e442f62..279ce8ca8 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -18,8 +18,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/test_inline_objects.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/test_inline_objects.py index 52163498b..d60561d8a 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/test_inline_objects.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/test_inline_objects.py @@ -12,8 +12,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[TestInlineObjectsResponse_200]: if response.status_code == 200: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_200 = TestInlineObjectsResponse_200.from_dict(response.json()) return response_200 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/upload_file_tests_upload_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/upload_file_tests_upload_post.py index 72d6720e2..2d084a9e0 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/upload_file_tests_upload_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/upload_file_tests_upload_post.py @@ -22,8 +22,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[ return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index e120497c0..5f11adb3a 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -36,7 +36,7 @@ class AModel: not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] = UNSET - not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] = UNSET + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -110,7 +110,7 @@ def to_dict(self) -> Dict[str, Any]: if not isinstance(self.not_required_one_of_models, Unset): not_required_one_of_models = self.not_required_one_of_models.to_dict() - not_required_nullable_one_of_models: Union[Unset, None, Dict[str, Any]] + not_required_nullable_one_of_models: Union[Unset, None, Dict[str, Any], str] if isinstance(self.not_required_nullable_one_of_models, Unset): not_required_nullable_one_of_models = UNSET elif self.not_required_nullable_one_of_models is None: @@ -120,11 +120,14 @@ def to_dict(self) -> Dict[str, Any]: if not isinstance(self.not_required_nullable_one_of_models, Unset): not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() - else: + elif isinstance(self.not_required_nullable_one_of_models, ModelWithUnionProperty): not_required_nullable_one_of_models = UNSET if not isinstance(self.not_required_nullable_one_of_models, Unset): not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() + else: + not_required_nullable_one_of_models = self.not_required_nullable_one_of_models + field_dict: Dict[str, Any] = {} field_dict.update( { @@ -167,11 +170,15 @@ def from_dict(src_dict: Dict[str, Any]) -> "AModel": def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datetime.date]: a_camel_date_time: Union[datetime.datetime, datetime.date] try: + if not isinstance(data, str): + raise TypeError() a_camel_date_time = isoparse(data) return a_camel_date_time except: # noqa: E722 pass + if not isinstance(data, str): + raise TypeError() a_camel_date_time = isoparse(data).date() return a_camel_date_time @@ -182,22 +189,20 @@ def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datet required_not_nullable = d.pop("required_not_nullable") - if not isinstance(d.pop("model"), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("model"))) model = AModelModel.from_dict(d.pop("model")) def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, ModelWithUnionProperty]: one_of_models: Union[FreeFormModel, ModelWithUnionProperty] try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() one_of_models = FreeFormModel.from_dict(data) return one_of_models except: # noqa: E722 pass if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() one_of_models = ModelWithUnionProperty.from_dict(data) return one_of_models @@ -231,24 +236,16 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo nullable_model = None if d.pop("nullable_model") is not None and not isinstance(d.pop("nullable_model"), Unset): - if not isinstance(d.pop("nullable_model"), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("nullable_model"))) nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET if d.pop("not_required_model", UNSET) is not None and not isinstance(d.pop("not_required_model", UNSET), Unset): - if not isinstance(d.pop("not_required_model", UNSET), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("not_required_model", UNSET))) not_required_model = AModelNotRequiredModel.from_dict(d.pop("not_required_model", UNSET)) not_required_nullable_model = None if d.pop("not_required_nullable_model", UNSET) is not None and not isinstance( d.pop("not_required_nullable_model", UNSET), Unset ): - if not isinstance(d.pop("not_required_nullable_model", UNSET), dict): - raise ValueError( - "Cannot construct model from value " + str(d.pop("not_required_nullable_model", UNSET)) - ) not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( d.pop("not_required_nullable_model", UNSET) ) @@ -261,14 +258,14 @@ def _parse_nullable_one_of_models( return data try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() nullable_one_of_models = FreeFormModel.from_dict(data) return nullable_one_of_models except: # noqa: E722 pass if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() nullable_one_of_models = ModelWithUnionProperty.from_dict(data) return nullable_one_of_models @@ -282,19 +279,19 @@ def _parse_not_required_one_of_models( if isinstance(data, Unset): return data try: + if not isinstance(data, dict): + raise TypeError() not_required_one_of_models = UNSET if data is not None and not isinstance(data, Unset): - if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) not_required_one_of_models = FreeFormModel.from_dict(data) return not_required_one_of_models except: # noqa: E722 pass + if not isinstance(data, dict): + raise TypeError() not_required_one_of_models = UNSET if data is not None and not isinstance(data, Unset): - if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) not_required_one_of_models = ModelWithUnionProperty.from_dict(data) return not_required_one_of_models @@ -302,30 +299,34 @@ def _parse_not_required_one_of_models( not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) def _parse_not_required_nullable_one_of_models( - data: Union[Unset, None, Dict[str, Any]] - ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty]: - not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] + data: Union[Unset, None, Dict[str, Any], str] + ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str]: + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] if data is None: return data if isinstance(data, Unset): return data try: + if not isinstance(data, dict): + raise TypeError() not_required_nullable_one_of_models = UNSET if data is not None and not isinstance(data, Unset): - if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) not_required_nullable_one_of_models = FreeFormModel.from_dict(data) return not_required_nullable_one_of_models except: # noqa: E722 pass - not_required_nullable_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): + try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) - not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + raise TypeError() + not_required_nullable_one_of_models = UNSET + if data is not None and not isinstance(data, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict(data) - return not_required_nullable_one_of_models + return not_required_nullable_one_of_models + except: # noqa: E722 + pass + return cast(Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str], data) not_required_nullable_one_of_models = _parse_not_required_nullable_one_of_models( d.pop("not_required_nullable_one_of_models", UNSET) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py index 724c5f414..a51e66578 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py index 7c9cad150..505feab12 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py index 00a8de6b4..732e96133 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py index 09e6558ed..3f2d667a6 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py index 695662ad8..1b25a6d98 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py @@ -34,8 +34,6 @@ def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError": detail = [] _detail = d.pop("detail", UNSET) for detail_item_data in _detail or []: - if not isinstance(detail_item_data, dict): - raise ValueError("Cannot construct model from value " + str(detail_item_data)) detail_item = ValidationError.from_dict(detail_item_data) detail.append(detail_item) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py index a68e8f222..30acb7957 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py @@ -41,8 +41,6 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlined additional_properties = {} for prop_name, prop_dict in d.items(): - if not isinstance(prop_dict, dict): - raise ValueError("Cannot construct model from value " + str(prop_dict)) additional_property = ModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict(prop_dict) additional_properties[prop_name] = additional_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py index 5ce4fbb8c..7971f562e 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py @@ -46,13 +46,15 @@ def _parse_additional_property( ] try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() additional_property = ModelWithAnyJsonPropertiesAdditionalProperty.from_dict(data) return additional_property except: # noqa: E722 pass try: + if not isinstance(data, list): + raise TypeError() additional_property = cast(List[str], data) return additional_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index a97c64fb6..8f3001c9f 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -33,8 +33,6 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET if d.pop("a_date_holder", UNSET) is not None and not isinstance(d.pop("a_date_holder", UNSET), Unset): - if not isinstance(d.pop("a_date_holder", UNSET), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("a_date_holder", UNSET))) a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(d.pop("a_date_holder", UNSET)) model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index 956ea64b3..425fe9c09 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -43,6 +43,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -51,6 +53,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index 304856de9..f87317ead 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -146,8 +146,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py index e1020e492..e43c92d9b 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py @@ -50,16 +50,12 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[List[AModel], response_200 = [] _response_200 = response.json() for response_200_item_data in _response_200: - if not isinstance(response_200_item_data, dict): - raise ValueError("Cannot construct model from value " + str(response_200_item_data)) response_200_item = AModel.from_dict(response_200_item_data) response_200.append(response_200_item) return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py index da7588b0a..cace678f1 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py @@ -38,8 +38,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/json_body_tests_json_body_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/json_body_tests_json_body_post.py index 244083ee9..408f2dab1 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/json_body_tests_json_body_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/json_body_tests_json_body_post.py @@ -34,8 +34,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 2b2e21453..23bd9e741 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -42,8 +42,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/test_inline_objects.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/test_inline_objects.py index e80566576..0f134aa87 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/test_inline_objects.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/test_inline_objects.py @@ -30,8 +30,6 @@ def _get_kwargs( def _parse_response(*, response: httpx.Response) -> Optional[TestInlineObjectsResponse_200]: if response.status_code == 200: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_200 = TestInlineObjectsResponse_200.from_dict(response.json()) return response_200 diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/upload_file_tests_upload_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/upload_file_tests_upload_post.py index 13b2d25ca..f8a54ec77 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/upload_file_tests_upload_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/upload_file_tests_upload_post.py @@ -36,8 +36,6 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPVal return response_200 if response.status_code == 422: - if not isinstance(response.json(), dict): - raise ValueError("Cannot construct model from value " + str(response.json())) response_422 = HTTPValidationError.from_dict(response.json()) return response_422 diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index e120497c0..5f11adb3a 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -36,7 +36,7 @@ class AModel: not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] = UNSET - not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] = UNSET + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -110,7 +110,7 @@ def to_dict(self) -> Dict[str, Any]: if not isinstance(self.not_required_one_of_models, Unset): not_required_one_of_models = self.not_required_one_of_models.to_dict() - not_required_nullable_one_of_models: Union[Unset, None, Dict[str, Any]] + not_required_nullable_one_of_models: Union[Unset, None, Dict[str, Any], str] if isinstance(self.not_required_nullable_one_of_models, Unset): not_required_nullable_one_of_models = UNSET elif self.not_required_nullable_one_of_models is None: @@ -120,11 +120,14 @@ def to_dict(self) -> Dict[str, Any]: if not isinstance(self.not_required_nullable_one_of_models, Unset): not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() - else: + elif isinstance(self.not_required_nullable_one_of_models, ModelWithUnionProperty): not_required_nullable_one_of_models = UNSET if not isinstance(self.not_required_nullable_one_of_models, Unset): not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict() + else: + not_required_nullable_one_of_models = self.not_required_nullable_one_of_models + field_dict: Dict[str, Any] = {} field_dict.update( { @@ -167,11 +170,15 @@ def from_dict(src_dict: Dict[str, Any]) -> "AModel": def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datetime.date]: a_camel_date_time: Union[datetime.datetime, datetime.date] try: + if not isinstance(data, str): + raise TypeError() a_camel_date_time = isoparse(data) return a_camel_date_time except: # noqa: E722 pass + if not isinstance(data, str): + raise TypeError() a_camel_date_time = isoparse(data).date() return a_camel_date_time @@ -182,22 +189,20 @@ def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datet required_not_nullable = d.pop("required_not_nullable") - if not isinstance(d.pop("model"), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("model"))) model = AModelModel.from_dict(d.pop("model")) def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, ModelWithUnionProperty]: one_of_models: Union[FreeFormModel, ModelWithUnionProperty] try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() one_of_models = FreeFormModel.from_dict(data) return one_of_models except: # noqa: E722 pass if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() one_of_models = ModelWithUnionProperty.from_dict(data) return one_of_models @@ -231,24 +236,16 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo nullable_model = None if d.pop("nullable_model") is not None and not isinstance(d.pop("nullable_model"), Unset): - if not isinstance(d.pop("nullable_model"), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("nullable_model"))) nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET if d.pop("not_required_model", UNSET) is not None and not isinstance(d.pop("not_required_model", UNSET), Unset): - if not isinstance(d.pop("not_required_model", UNSET), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("not_required_model", UNSET))) not_required_model = AModelNotRequiredModel.from_dict(d.pop("not_required_model", UNSET)) not_required_nullable_model = None if d.pop("not_required_nullable_model", UNSET) is not None and not isinstance( d.pop("not_required_nullable_model", UNSET), Unset ): - if not isinstance(d.pop("not_required_nullable_model", UNSET), dict): - raise ValueError( - "Cannot construct model from value " + str(d.pop("not_required_nullable_model", UNSET)) - ) not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( d.pop("not_required_nullable_model", UNSET) ) @@ -261,14 +258,14 @@ def _parse_nullable_one_of_models( return data try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() nullable_one_of_models = FreeFormModel.from_dict(data) return nullable_one_of_models except: # noqa: E722 pass if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() nullable_one_of_models = ModelWithUnionProperty.from_dict(data) return nullable_one_of_models @@ -282,19 +279,19 @@ def _parse_not_required_one_of_models( if isinstance(data, Unset): return data try: + if not isinstance(data, dict): + raise TypeError() not_required_one_of_models = UNSET if data is not None and not isinstance(data, Unset): - if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) not_required_one_of_models = FreeFormModel.from_dict(data) return not_required_one_of_models except: # noqa: E722 pass + if not isinstance(data, dict): + raise TypeError() not_required_one_of_models = UNSET if data is not None and not isinstance(data, Unset): - if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) not_required_one_of_models = ModelWithUnionProperty.from_dict(data) return not_required_one_of_models @@ -302,30 +299,34 @@ def _parse_not_required_one_of_models( not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) def _parse_not_required_nullable_one_of_models( - data: Union[Unset, None, Dict[str, Any]] - ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty]: - not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty] + data: Union[Unset, None, Dict[str, Any], str] + ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str]: + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] if data is None: return data if isinstance(data, Unset): return data try: + if not isinstance(data, dict): + raise TypeError() not_required_nullable_one_of_models = UNSET if data is not None and not isinstance(data, Unset): - if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) not_required_nullable_one_of_models = FreeFormModel.from_dict(data) return not_required_nullable_one_of_models except: # noqa: E722 pass - not_required_nullable_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): + try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) - not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + raise TypeError() + not_required_nullable_one_of_models = UNSET + if data is not None and not isinstance(data, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict(data) - return not_required_nullable_one_of_models + return not_required_nullable_one_of_models + except: # noqa: E722 + pass + return cast(Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str], data) not_required_nullable_one_of_models = _parse_not_required_nullable_one_of_models( d.pop("not_required_nullable_one_of_models", UNSET) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py index 724c5f414..a51e66578 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py index 7c9cad150..505feab12 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py index 00a8de6b4..732e96133 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py index 09e6558ed..3f2d667a6 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -45,6 +45,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -53,6 +55,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py b/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py index 695662ad8..1b25a6d98 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py @@ -34,8 +34,6 @@ def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError": detail = [] _detail = d.pop("detail", UNSET) for detail_item_data in _detail or []: - if not isinstance(detail_item_data, dict): - raise ValueError("Cannot construct model from value " + str(detail_item_data)) detail_item = ValidationError.from_dict(detail_item_data) detail.append(detail_item) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py index a68e8f222..30acb7957 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py @@ -41,8 +41,6 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlined additional_properties = {} for prop_name, prop_dict in d.items(): - if not isinstance(prop_dict, dict): - raise ValueError("Cannot construct model from value " + str(prop_dict)) additional_property = ModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict(prop_dict) additional_properties[prop_name] = additional_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py index 5ce4fbb8c..7971f562e 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py @@ -46,13 +46,15 @@ def _parse_additional_property( ] try: if not isinstance(data, dict): - raise ValueError("Cannot construct model from value " + str(data)) + raise TypeError() additional_property = ModelWithAnyJsonPropertiesAdditionalProperty.from_dict(data) return additional_property except: # noqa: E722 pass try: + if not isinstance(data, list): + raise TypeError() additional_property = cast(List[str], data) return additional_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index a97c64fb6..8f3001c9f 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -33,8 +33,6 @@ def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperti d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET if d.pop("a_date_holder", UNSET) is not None and not isinstance(d.pop("a_date_holder", UNSET), Unset): - if not isinstance(d.pop("a_date_holder", UNSET), dict): - raise ValueError("Cannot construct model from value " + str(d.pop("a_date_holder", UNSET))) a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(d.pop("a_date_holder", UNSET)) model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index 956ea64b3..425fe9c09 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -43,6 +43,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): @@ -51,6 +53,8 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass + if not isinstance(data, int): + raise TypeError() a_property = UNSET _a_property = data if _a_property is not None and not isinstance(_a_property, Unset): diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 404656e31..971bbaa03 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -819,6 +819,9 @@ }, { "ref": "#components/schemas/ModelWithUnionProperty" + }, + { + "type": "string" } ], "nullable": true diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index f73df9437..ae1cf03dc 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -9,6 +9,8 @@ if _{{ property.python_name }} is not None and not isinstance(_{{ property.pytho {% endif %} {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, str){% endmacro %} + {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {{ destination }} = {{ source }}.isoformat() {% if property.nullable %}if {{ source }} else None {%endif%} diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index 88f370b32..0af84dee5 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -14,6 +14,8 @@ if _{{ property.python_name }} is not None and not isinstance(_{{ property.pytho {% endif %} {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, str){% endmacro %} + {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} diff --git a/openapi_python_client/templates/property_templates/dict_property.pyi b/openapi_python_client/templates/property_templates/dict_property.pyi index ca16cb538..1158b0cbc 100644 --- a/openapi_python_client/templates/property_templates/dict_property.pyi +++ b/openapi_python_client/templates/property_templates/dict_property.pyi @@ -9,6 +9,8 @@ if _{{ property.python_name }} is not None and not isinstance(_{{ property.pyth {% endif %} {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, dict){% endmacro %} + {% macro transform(property, source, destination, declare_type=True) %} {% if property.nullable %} {{ destination }} = {{ source }} if {{ source }} else None diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 3bf16564e..8838aaa44 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -9,6 +9,8 @@ if _{{ property.python_name }} is not None and not isinstance(_{{ property.pytho {% endif %} {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, int){% endmacro %} + {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} diff --git a/openapi_python_client/templates/property_templates/file_property.pyi b/openapi_python_client/templates/property_templates/file_property.pyi index 50a331851..3a5b5e746 100644 --- a/openapi_python_client/templates/property_templates/file_property.pyi +++ b/openapi_python_client/templates/property_templates/file_property.pyi @@ -4,6 +4,8 @@ ) {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, bytes){% endmacro %} + {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} diff --git a/openapi_python_client/templates/property_templates/list_property.pyi b/openapi_python_client/templates/property_templates/list_property.pyi index 5f58bcd30..6f2d03f68 100644 --- a/openapi_python_client/templates/property_templates/list_property.pyi +++ b/openapi_python_client/templates/property_templates/list_property.pyi @@ -17,6 +17,8 @@ for {{ inner_source }} in (_{{ property.python_name }} or []): {% endif %} {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, list){% endmacro %} + {% macro _transform(property, source, destination) %} {% set inner_property = property.inner_property %} {% if inner_property.template %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index cb4b198ff..56a3cb919 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,7 +1,5 @@ {% macro construct(property, source, initial_value=None) %} {% if property.required and not property.nullable %} -if not isinstance({{ source }}, dict): - raise ValueError("Cannot construct model from value " + str({{ source }})) {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) {% else %} {% if initial_value != None %} @@ -12,12 +10,12 @@ if not isinstance({{ source }}, dict): {{ property.python_name }}: {{ property.get_type_string() }} = UNSET {% endif %} if {{ source }} is not None and not isinstance({{ source }}, Unset): - if not isinstance({{ source }}, dict): - raise ValueError("Cannot construct model from value " + str({{ source }})) {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) {% endif %} {% endmacro %} +{% macro check_type_for_construct(source) %}isinstance({{ source }}, dict){% endmacro %} + {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} diff --git a/openapi_python_client/templates/property_templates/none_property.pyi b/openapi_python_client/templates/property_templates/none_property.pyi index b3178780a..235530c8b 100644 --- a/openapi_python_client/templates/property_templates/none_property.pyi +++ b/openapi_python_client/templates/property_templates/none_property.pyi @@ -2,6 +2,8 @@ {{ property.python_name }} = {{ initial_value }} {% endmacro %} +{% macro check_type_for_construct(source) %}{{ source }} is None{% endmacro %} + {% macro transform(property, source, destination, declare_type=True) %} {{ destination }} = None {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 0d5f09a07..c414fb65d 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -12,13 +12,17 @@ def _parse_{{ property.python_name }}(data: {{ property.get_type_string(json=Tru {% for inner_property in property.inner_properties_with_template() %} {% if not loop.last or property.has_properties_without_templates %} try: - {% from "property_templates/" + inner_property.template import construct %} + {% from "property_templates/" + inner_property.template import construct, check_type_for_construct %} + if not {{ check_type_for_construct("data") }}: + raise TypeError() {{ construct(inner_property, "data", initial_value="UNSET") | indent(8) }} return {{ property.python_name }} except: # noqa: E722 pass {% else %}{# Don't do try/except for the last one #} - {% from "property_templates/" + inner_property.template import construct %} + {% from "property_templates/" + inner_property.template import construct, check_type_for_construct %} + if not {{ check_type_for_construct("data") }}: + raise TypeError() {{ construct(inner_property, "data", initial_value="UNSET") | indent(4) }} return {{ property.python_name }} {% endif %} @@ -31,6 +35,9 @@ def _parse_{{ property.python_name }}(data: {{ property.get_type_string(json=Tru {{ property.python_name }} = _parse_{{ property.python_name }}({{ source }}) {% endmacro %} +{# For now we assume there will be no unions of unions #} +{% macro check_type_for_construct(source) %}True{% endmacro %} + {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if not property.required or property.nullable %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} From 9c002560f4df749aebb5e4f55a6ee747b41d1430 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Thu, 28 Jan 2021 09:16:13 -0500 Subject: [PATCH 17/50] Revert changes to Unset --- .../custom_e2e/models/a_model.py | 43 +++++++++++-------- .../custom_e2e/models/a_model_model.py | 4 +- .../models/a_model_not_required_model.py | 4 +- .../a_model_not_required_nullable_model.py | 4 +- .../models/a_model_nullable_model.py | 4 +- ...el_with_primitive_additional_properties.py | 5 ++- .../models/model_with_union_property.py | 4 +- .../my_test_api_client/models/a_model.py | 43 +++++++++++-------- .../models/a_model_model.py | 4 +- .../models/a_model_not_required_model.py | 4 +- .../a_model_not_required_nullable_model.py | 4 +- .../models/a_model_nullable_model.py | 4 +- ...el_with_primitive_additional_properties.py | 5 ++- .../models/model_with_union_property.py | 4 +- .../parser/properties/__init__.py | 9 ++-- .../property_templates/date_property.pyi | 2 +- .../property_templates/datetime_property.pyi | 2 +- .../property_templates/dict_property.pyi | 2 +- .../property_templates/enum_property.pyi | 2 +- .../property_templates/model_property.pyi | 5 ++- .../test_date_property/optional_nullable.py | 2 +- .../test_date_property/required_nullable.py | 2 +- 22 files changed, 89 insertions(+), 73 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 5f11adb3a..83d7518a7 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -223,7 +223,7 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo a_nullable_date = None _a_nullable_date = d.pop("a_nullable_date") - if _a_nullable_date is not None and not isinstance(_a_nullable_date, Unset): + if _a_nullable_date is not None: a_nullable_date = isoparse(cast(str, _a_nullable_date)).date() attr_1_leading_digit = d.pop("1_leading_digit", UNSET) @@ -235,20 +235,19 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) nullable_model = None - if d.pop("nullable_model") is not None and not isinstance(d.pop("nullable_model"), Unset): - nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = AModelNullableModel.from_dict(_nullable_model) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET - if d.pop("not_required_model", UNSET) is not None and not isinstance(d.pop("not_required_model", UNSET), Unset): - not_required_model = AModelNotRequiredModel.from_dict(d.pop("not_required_model", UNSET)) + _not_required_model = d.pop("not_required_model", UNSET) + if not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(_not_required_model) not_required_nullable_model = None - if d.pop("not_required_nullable_model", UNSET) is not None and not isinstance( - d.pop("not_required_nullable_model", UNSET), Unset - ): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( - d.pop("not_required_nullable_model", UNSET) - ) + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model) def _parse_nullable_one_of_models( data: Union[None, Dict[str, Any]] @@ -282,8 +281,9 @@ def _parse_not_required_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_one_of_models = FreeFormModel.from_dict(data) + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict(_not_required_one_of_models) return not_required_one_of_models except: # noqa: E722 @@ -291,8 +291,9 @@ def _parse_not_required_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_one_of_models = ModelWithUnionProperty.from_dict(data) + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict(_not_required_one_of_models) return not_required_one_of_models @@ -310,8 +311,9 @@ def _parse_not_required_nullable_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_nullable_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_nullable_one_of_models = FreeFormModel.from_dict(data) + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = FreeFormModel.from_dict(_not_required_nullable_one_of_models) return not_required_nullable_one_of_models except: # noqa: E722 @@ -320,8 +322,11 @@ def _parse_not_required_nullable_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_nullable_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( + _not_required_nullable_one_of_models + ) return not_required_nullable_one_of_models except: # noqa: E722 diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py index a51e66578..186a20d96 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py index 505feab12..c868d6778 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py index 732e96133..346eaf1c1 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py index 3f2d667a6..ce8951d04 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 8f3001c9f..32b23d7e5 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -32,8 +32,9 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET - if d.pop("a_date_holder", UNSET) is not None and not isinstance(d.pop("a_date_holder", UNSET), Unset): - a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(d.pop("a_date_holder", UNSET)) + _a_date_holder = d.pop("a_date_holder", UNSET) + if not isinstance(_a_date_holder, Unset): + a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder) model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( a_date_holder=a_date_holder, diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index 425fe9c09..d530e0908 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -47,7 +47,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -57,7 +57,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 5f11adb3a..83d7518a7 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -223,7 +223,7 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo a_nullable_date = None _a_nullable_date = d.pop("a_nullable_date") - if _a_nullable_date is not None and not isinstance(_a_nullable_date, Unset): + if _a_nullable_date is not None: a_nullable_date = isoparse(cast(str, _a_nullable_date)).date() attr_1_leading_digit = d.pop("1_leading_digit", UNSET) @@ -235,20 +235,19 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) nullable_model = None - if d.pop("nullable_model") is not None and not isinstance(d.pop("nullable_model"), Unset): - nullable_model = AModelNullableModel.from_dict(d.pop("nullable_model")) + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = AModelNullableModel.from_dict(_nullable_model) not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET - if d.pop("not_required_model", UNSET) is not None and not isinstance(d.pop("not_required_model", UNSET), Unset): - not_required_model = AModelNotRequiredModel.from_dict(d.pop("not_required_model", UNSET)) + _not_required_model = d.pop("not_required_model", UNSET) + if not isinstance(_not_required_model, Unset): + not_required_model = AModelNotRequiredModel.from_dict(_not_required_model) not_required_nullable_model = None - if d.pop("not_required_nullable_model", UNSET) is not None and not isinstance( - d.pop("not_required_nullable_model", UNSET), Unset - ): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict( - d.pop("not_required_nullable_model", UNSET) - ) + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model) def _parse_nullable_one_of_models( data: Union[None, Dict[str, Any]] @@ -282,8 +281,9 @@ def _parse_not_required_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_one_of_models = FreeFormModel.from_dict(data) + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict(_not_required_one_of_models) return not_required_one_of_models except: # noqa: E722 @@ -291,8 +291,9 @@ def _parse_not_required_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_one_of_models = ModelWithUnionProperty.from_dict(data) + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict(_not_required_one_of_models) return not_required_one_of_models @@ -310,8 +311,9 @@ def _parse_not_required_nullable_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_nullable_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_nullable_one_of_models = FreeFormModel.from_dict(data) + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = FreeFormModel.from_dict(_not_required_nullable_one_of_models) return not_required_nullable_one_of_models except: # noqa: E722 @@ -320,8 +322,11 @@ def _parse_not_required_nullable_one_of_models( if not isinstance(data, dict): raise TypeError() not_required_nullable_one_of_models = UNSET - if data is not None and not isinstance(data, Unset): - not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( + _not_required_nullable_one_of_models + ) return not_required_nullable_one_of_models except: # noqa: E722 diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py index a51e66578..186a20d96 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py index 505feab12..c868d6778 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py index 732e96133..346eaf1c1 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py index 3f2d667a6..ce8951d04 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -49,7 +49,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -59,7 +59,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 8f3001c9f..32b23d7e5 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -32,8 +32,9 @@ def to_dict(self) -> Dict[str, Any]: def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET - if d.pop("a_date_holder", UNSET) is not None and not isinstance(d.pop("a_date_holder", UNSET), Unset): - a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(d.pop("a_date_holder", UNSET)) + _a_date_holder = d.pop("a_date_holder", UNSET) + if not isinstance(_a_date_holder, Unset): + a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder) model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( a_date_holder=a_date_holder, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index 425fe9c09..d530e0908 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -47,7 +47,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnEnum(_a_property) return a_property @@ -57,7 +57,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None and not isinstance(_a_property, Unset): + if _a_property is not None: a_property = AnIntEnum(_a_property) return a_property diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 96d146a4a..1794cf6ed 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -177,7 +177,9 @@ def _get_inner_type_strings(self, json: bool = False) -> List[str]: def get_base_type_string(self, json: bool = False) -> str: return f"Union[{', '.join(self._get_inner_type_strings(json=json))}]" - def get_type_strings_in_union(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> List[str]: + def get_type_strings_in_union( + self, no_optional: bool = False, query_parameter: bool = False, json: bool = False + ) -> List[str]: type_strings = self._get_inner_type_strings(json=json) if no_optional: return type_strings @@ -203,9 +205,10 @@ def get_type_string(self, no_optional: bool = False, query_parameter: bool = Fal This implementation differs slightly from `Property.get_type_string` in order to collapse nested union types. """ - return ( - f"Union[{', '.join(self.get_type_strings_in_union(no_optional=no_optional, query_parameter=query_parameter, json=json))}]" + type_strings_in_union = self.get_type_strings_in_union( + no_optional=no_optional, query_parameter=query_parameter, json=json ) + return f"Union[{', '.join(type_strings_in_union)}]" def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index ae1cf03dc..d883d8787 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): +if _{{ property.python_name }} is not None: {{ property.python_name }} = isoparse(cast(str, _{{ property.python_name }})).date() {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index 0af84dee5..53f432a59 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -9,7 +9,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): +if _{{ property.python_name }} is not None: {{ property.python_name }} = isoparse(cast(str, _{{ property.python_name }})) {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/dict_property.pyi b/openapi_python_client/templates/property_templates/dict_property.pyi index 1158b0cbc..c4a853d72 100644 --- a/openapi_python_client/templates/property_templates/dict_property.pyi +++ b/openapi_python_client/templates/property_templates/dict_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): +if _{{ property.python_name }} is not None: {{ property.python_name }} = _{{ property.python_name }} {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 8838aaa44..782d3ec44 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None and not isinstance(_{{ property.python_name }}, Unset): +if _{{ property.python_name }} is not None: {{ property.python_name }} = {{ property.reference.class_name }}(_{{ property.python_name }}) {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index 56a3cb919..1cabf2996 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -9,8 +9,9 @@ {% else %} {{ property.python_name }}: {{ property.get_type_string() }} = UNSET {% endif %} -if {{ source }} is not None and not isinstance({{ source }}, Unset): - {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) +_{{ property.python_name }} = {{source}} +if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{% if property.nullable and not property.required %} and {% endif %}{% if not property.required %}not isinstance(_{{ property.python_name }}, Unset){% endif %}: + {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(_{{ property.python_name }}) {% endif %} {% endmacro %} diff --git a/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py b/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py index 95441cc62..be32cfbd3 100644 --- a/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py +++ b/tests/test_templates/test_property_templates/test_date_property/optional_nullable.py @@ -17,6 +17,6 @@ a_prop = None _a_prop = some_destination -if _a_prop is not None and not isinstance(_a_prop, Unset): +if _a_prop is not None: a_prop = isoparse(cast(str, _a_prop)).date() diff --git a/tests/test_templates/test_property_templates/test_date_property/required_nullable.py b/tests/test_templates/test_property_templates/test_date_property/required_nullable.py index 685dfbafc..b6ef423b8 100644 --- a/tests/test_templates/test_property_templates/test_date_property/required_nullable.py +++ b/tests/test_templates/test_property_templates/test_date_property/required_nullable.py @@ -13,6 +13,6 @@ a_prop = None _a_prop = some_destination -if _a_prop is not None and not isinstance(_a_prop, Unset): +if _a_prop is not None: a_prop = isoparse(cast(str, _a_prop)).date() From 64c31ce92b0b05125c7643fab940a834fa2a043c Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Thu, 28 Jan 2021 09:30:29 -0500 Subject: [PATCH 18/50] Regenerate tests --- .../golden-record-custom/custom_e2e/models/a_model_model.py | 4 ++-- .../custom_e2e/models/a_model_not_required_model.py | 4 ++-- .../custom_e2e/models/a_model_not_required_nullable_model.py | 4 ++-- .../custom_e2e/models/a_model_nullable_model.py | 4 ++-- .../custom_e2e/models/model_with_union_property.py | 4 ++-- .../golden-record/my_test_api_client/models/a_model_model.py | 4 ++-- .../my_test_api_client/models/a_model_not_required_model.py | 4 ++-- .../models/a_model_not_required_nullable_model.py | 4 ++-- .../my_test_api_client/models/a_model_nullable_model.py | 4 ++-- .../my_test_api_client/models/model_with_union_property.py | 4 ++-- .../templates/property_templates/enum_property.pyi | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py index 186a20d96..cef48694b 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py index c868d6778..3f56b7f52 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py index 346eaf1c1..55ef6810a 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py index ce8951d04..05c4f8897 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index d530e0908..99fcdfe96 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -43,7 +43,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -53,7 +53,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py index 186a20d96..cef48694b 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py index c868d6778..3f56b7f52 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py index 346eaf1c1..55ef6810a 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py index ce8951d04..05c4f8897 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py @@ -45,7 +45,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -55,7 +55,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index d530e0908..99fcdfe96 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -43,7 +43,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum if isinstance(data, Unset): return data try: - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data @@ -53,7 +53,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum return a_property except: # noqa: E722 pass - if not isinstance(data, int): + if not (isinstance(data, int) or isinstance(data, str)): raise TypeError() a_property = UNSET _a_property = data diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 782d3ec44..6d87c2918 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -9,7 +9,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro check_type_for_construct(source) %}isinstance({{ source }}, int){% endmacro %} +{% macro check_type_for_construct(source) %}(isinstance({{ source }}, int) or isinstance({{ source }}, str)){% endmacro %} {% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} From eece180cfd78f024eb235e2a0b0395f1543115c0 Mon Sep 17 00:00:00 2001 From: William Bowen Date: Fri, 22 Jan 2021 11:58:11 -0500 Subject: [PATCH 19/50] fix: Handle Unset Enums when deserializing (#306) --- CHANGELOG.md | 46 ++++++++++++++----- .../models/model_with_union_property.py | 4 +- .../models/model_with_union_property.py | 4 +- .../property_templates/enum_property.pyi | 2 +- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 761f0abe5..7b2372aca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,21 +5,45 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.0 - Unreleased + +### Additions + +- New `--meta` command line option for specifying what type of metadata should be generated: + - `poetry` is the default value, same behavior you're used to in previous versions + - `setup` will generate a pyproject.toml with no Poetry information, and instead create a `setup.py` with the + project info. + - `none` will not create a project folder at all, only the inner package folder (which won't be inner anymore) +- Attempt to detect and alert users if they are using an unsupported version of OpenAPI (#281). +- Fixes `Enum` deserialization when the value is `UNSET`. + +### Changes + +- Lowered the minimum version of `python-dateutil` to 2.8.0 for improved compatibility (#298 & #299). Thanks @bowenwr! +- The `from_dict` method on generated models is now a `@classmethod` instead of `@staticmethod` (#215 & #292). Thanks @forest-benchling! + ## 0.7.3 - 2020-12-21 + ### Fixes + - Spacing and extra returns for Union types of `additionalProperties` (#266 & #268). Thanks @joshzana & @packyg! - Title of inline schemas will no longer be missing characters (#271 & #274). Thanks @kalzoo! -- Handling of nulls (Nones) when parsing or constructing dates (#267). Thanks @fyhertz! +- Handling of nulls (Nones) when parsing or constructing dates (#267). Thanks @fyhertz! ## 0.7.2 - 2020-12-08 + ### Fixes + - A bug in handling optional properties that are themselves models (introduced in 0.7.1) (#262). Thanks @packyg! ## 0.7.1 - 2020-12-08 + ### Additions + - Support for additionalProperties attribute in OpenAPI schemas and "free-form" objects by adding an `additional_properties` attribute to generated models. **COMPATIBILITY NOTE**: this will prevent any model property with a name that would be coerced to "additional_properties" in the generated client from generating properly (#218 & #252). Thanks @packyg! ### Fixes + - Enums will once again work with query parameters (#259). Thanks @packyg! - Generated Poetry metadata in pyproject.toml will properly indicate Python 3.6 compatibility (#258). Thanks @bowenwr! @@ -27,18 +51,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking Changes -- Any request/response field that is not `required` and wasn't specified is now set to `UNSET` instead of `None`. +- Any request/response field that is not `required` and wasn't specified is now set to `UNSET` instead of `None`. - Values that are `UNSET` will not be sent along in API calls -- Schemas defined with `type=object` will now be converted into classes, just like if they were created as ref components. - The previous behavior was a combination of skipping and using generic Dicts for these schemas. -- Response schema handling was unified with input schema handling, meaning that responses will behave differently than before. - Specifically, instead of the content-type deciding what the generated Python type is, the schema itself will. - - As a result of this, endpoints that used to return `bytes` when content-type was application/octet-stream will now return a `File` object if the type of the data is "binary", just like if you were submitting that type instead of receiving it. +- Schemas defined with `type=object` will now be converted into classes, just like if they were created as ref components. + The previous behavior was a combination of skipping and using generic Dicts for these schemas. +- Response schema handling was unified with input schema handling, meaning that responses will behave differently than before. + Specifically, instead of the content-type deciding what the generated Python type is, the schema itself will. + - As a result of this, endpoints that used to return `bytes` when content-type was application/octet-stream will now return a `File` object if the type of the data is "binary", just like if you were submitting that type instead of receiving it. - Instead of skipping input properties with no type, enum, anyOf, or oneOf declared, the property will be declared as `None`. -- Class (models and Enums) names will now contain the name of their parent element (if any). For example, a property - declared in an endpoint will be named like {endpoint_name}_{previous_class_name}. Classes will no longer be - deduplicated by appending a number to the end of the generated name, so if two names conflict with this new naming - scheme, there will be an error instead. +- Class (models and Enums) names will now contain the name of their parent element (if any). For example, a property + declared in an endpoint will be named like {endpoint*name}*{previous_class_name}. Classes will no longer be + deduplicated by appending a number to the end of the generated name, so if two names conflict with this new naming + scheme, there will be an error instead. ### Additions diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index 99fcdfe96..3b417f3f5 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -47,7 +47,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and _a_property is not UNSET: a_property = AnEnum(_a_property) return a_property @@ -57,7 +57,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and _a_property is not UNSET: a_property = AnIntEnum(_a_property) return a_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index 99fcdfe96..3b417f3f5 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -47,7 +47,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and _a_property is not UNSET: a_property = AnEnum(_a_property) return a_property @@ -57,7 +57,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum raise TypeError() a_property = UNSET _a_property = data - if _a_property is not None: + if _a_property is not None and _a_property is not UNSET: a_property = AnIntEnum(_a_property) return a_property diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 6d87c2918..764e66ade 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -4,7 +4,7 @@ {% else %} {{ property.python_name }} = {{ initial_value }} _{{ property.python_name }} = {{ source }} -if _{{ property.python_name }} is not None: +if _{{ property.python_name }} is not None and _{{ property.python_name }} is not UNSET: {{ property.python_name }} = {{ property.reference.class_name }}(_{{ property.python_name }}) {% endif %} {% endmacro %} From 981fade294a23156d5ba3863ff5dacb51d312d91 Mon Sep 17 00:00:00 2001 From: William Bowen Date: Thu, 14 Jan 2021 11:21:16 -0500 Subject: [PATCH 20/50] fix: Lower version requirements for python-dateutil in generated client #298 (#299) * Lower version requirements for python-dateutil in generated client #298 * Update CHANGELOG.md Co-authored-by: Dylan Anthony <43723790+dbanty@users.noreply.github.com> Co-authored-by: Dylan Anthony <43723790+dbanty@users.noreply.github.com> --- CHANGELOG.md | 42 +++++++------------ .../golden-record-custom/pyproject.toml | 2 +- end_to_end_tests/golden-record/pyproject.toml | 2 +- .../templates/pyproject.toml | 2 +- openapi_python_client/templates/setup.py | 19 +++++++++ 5 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 openapi_python_client/templates/setup.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b2372aca..ce2404f32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,45 +5,33 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.8.0 - Unreleased +## Unreleased ### Additions - - New `--meta` command line option for specifying what type of metadata should be generated: - `poetry` is the default value, same behavior you're used to in previous versions - - `setup` will generate a pyproject.toml with no Poetry information, and instead create a `setup.py` with the + - `setup` will generate a pyproject.toml with no Poetry information, and instead create a `setup.py` with the project info. - `none` will not create a project folder at all, only the inner package folder (which won't be inner anymore) -- Attempt to detect and alert users if they are using an unsupported version of OpenAPI (#281). -- Fixes `Enum` deserialization when the value is `UNSET`. - -### Changes +- Lowered the minimum version of `python-dateutil` for improved dependency compatibility with other projects -- Lowered the minimum version of `python-dateutil` to 2.8.0 for improved compatibility (#298 & #299). Thanks @bowenwr! -- The `from_dict` method on generated models is now a `@classmethod` instead of `@staticmethod` (#215 & #292). Thanks @forest-benchling! ## 0.7.3 - 2020-12-21 - ### Fixes - - Spacing and extra returns for Union types of `additionalProperties` (#266 & #268). Thanks @joshzana & @packyg! - Title of inline schemas will no longer be missing characters (#271 & #274). Thanks @kalzoo! -- Handling of nulls (Nones) when parsing or constructing dates (#267). Thanks @fyhertz! +- Handling of nulls (Nones) when parsing or constructing dates (#267). Thanks @fyhertz! -## 0.7.2 - 2020-12-08 +## 0.7.2 - 2020-12-08 ### Fixes - - A bug in handling optional properties that are themselves models (introduced in 0.7.1) (#262). Thanks @packyg! ## 0.7.1 - 2020-12-08 - ### Additions - - Support for additionalProperties attribute in OpenAPI schemas and "free-form" objects by adding an `additional_properties` attribute to generated models. **COMPATIBILITY NOTE**: this will prevent any model property with a name that would be coerced to "additional_properties" in the generated client from generating properly (#218 & #252). Thanks @packyg! ### Fixes - - Enums will once again work with query parameters (#259). Thanks @packyg! - Generated Poetry metadata in pyproject.toml will properly indicate Python 3.6 compatibility (#258). Thanks @bowenwr! @@ -51,18 +39,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking Changes -- Any request/response field that is not `required` and wasn't specified is now set to `UNSET` instead of `None`. +- Any request/response field that is not `required` and wasn't specified is now set to `UNSET` instead of `None`. - Values that are `UNSET` will not be sent along in API calls -- Schemas defined with `type=object` will now be converted into classes, just like if they were created as ref components. - The previous behavior was a combination of skipping and using generic Dicts for these schemas. -- Response schema handling was unified with input schema handling, meaning that responses will behave differently than before. - Specifically, instead of the content-type deciding what the generated Python type is, the schema itself will. - - As a result of this, endpoints that used to return `bytes` when content-type was application/octet-stream will now return a `File` object if the type of the data is "binary", just like if you were submitting that type instead of receiving it. +- Schemas defined with `type=object` will now be converted into classes, just like if they were created as ref components. + The previous behavior was a combination of skipping and using generic Dicts for these schemas. +- Response schema handling was unified with input schema handling, meaning that responses will behave differently than before. + Specifically, instead of the content-type deciding what the generated Python type is, the schema itself will. + - As a result of this, endpoints that used to return `bytes` when content-type was application/octet-stream will now return a `File` object if the type of the data is "binary", just like if you were submitting that type instead of receiving it. - Instead of skipping input properties with no type, enum, anyOf, or oneOf declared, the property will be declared as `None`. -- Class (models and Enums) names will now contain the name of their parent element (if any). For example, a property - declared in an endpoint will be named like {endpoint*name}*{previous_class_name}. Classes will no longer be - deduplicated by appending a number to the end of the generated name, so if two names conflict with this new naming - scheme, there will be an error instead. +- Class (models and Enums) names will now contain the name of their parent element (if any). For example, a property + declared in an endpoint will be named like {endpoint_name}_{previous_class_name}. Classes will no longer be + deduplicated by appending a number to the end of the generated name, so if two names conflict with this new naming + scheme, there will be an error instead. ### Additions diff --git a/end_to_end_tests/golden-record-custom/pyproject.toml b/end_to_end_tests/golden-record-custom/pyproject.toml index 87f375197..9f9f94914 100644 --- a/end_to_end_tests/golden-record-custom/pyproject.toml +++ b/end_to_end_tests/golden-record-custom/pyproject.toml @@ -16,7 +16,7 @@ include = ["CHANGELOG.md", "custom_e2e/py.typed"] python = "^3.6" httpx = "^0.15.0" attrs = "^20.1.0" -python-dateutil = "^2.8.1" +python-dateutil = "^2.8.0" [tool.black] line-length = 120 diff --git a/end_to_end_tests/golden-record/pyproject.toml b/end_to_end_tests/golden-record/pyproject.toml index 777ed75a3..6b7d0be67 100644 --- a/end_to_end_tests/golden-record/pyproject.toml +++ b/end_to_end_tests/golden-record/pyproject.toml @@ -16,7 +16,7 @@ include = ["CHANGELOG.md", "my_test_api_client/py.typed"] python = "^3.6" httpx = "^0.15.0" attrs = "^20.1.0" -python-dateutil = "^2.8.1" +python-dateutil = "^2.8.0" [tool.black] line-length = 120 diff --git a/openapi_python_client/templates/pyproject.toml b/openapi_python_client/templates/pyproject.toml index 6dff89c2c..97e1f543c 100644 --- a/openapi_python_client/templates/pyproject.toml +++ b/openapi_python_client/templates/pyproject.toml @@ -16,7 +16,7 @@ include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] python = "^3.6" httpx = "^0.15.0" attrs = "^20.1.0" -python-dateutil = "^2.8.1" +python-dateutil = "^2.8.0" [tool.black] line-length = 120 diff --git a/openapi_python_client/templates/setup.py b/openapi_python_client/templates/setup.py new file mode 100644 index 000000000..7339b7ccc --- /dev/null +++ b/openapi_python_client/templates/setup.py @@ -0,0 +1,19 @@ +import pathlib + +from setuptools import find_packages, setup + +here = pathlib.Path(__file__).parent.resolve() +long_description = (here / "README.md").read_text(encoding="utf-8") + +setup( + name="{{ project_name }}", + version="{{ version }}", + description="{{ description }}", + long_description=long_description, + long_description_content_type="text/markdown", + package_dir={"": "{{ package_name }}"}, + packages=find_packages(where="{{ package_name }}"), + python_requires=">=3.6, <4", + install_requires=["httpx >= 0.15.0, < 0.17.0", "attrs >= 20.1.0", "python-dateutil >= 2.8.0, < 3"], + package_data={"": ["CHANGELOG.md"], "{{ package_name }}": ["py.typed"]}, +) From 6b665b70eb8637a5a86e8500978f7175fddacd11 Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Mon, 11 Jan 2021 13:33:27 -0500 Subject: [PATCH 21/50] Change model from_dict from staticmethod to classmethod --- .../custom_e2e/models/a_model.py | 10 +- .../body_upload_file_tests_upload_post.py | 10 +- .../custom_e2e/models/free_form_model.py | 10 +- .../models/http_validation_error.py | 10 +- ...odel_with_additional_properties_inlined.py | 10 +- ..._properties_inlined_additional_property.py | 14 +-- .../model_with_additional_properties_refed.py | 10 +- .../models/model_with_any_json_properties.py | 10 +- ...any_json_properties_additional_property.py | 10 +- ...el_with_primitive_additional_properties.py | 10 +- ...ive_additional_properties_a_date_holder.py | 10 +- .../models/model_with_union_property.py | 10 +- .../models/test_inline_objects_json_body.py | 10 +- .../test_inline_objects_response_200.py | 10 +- .../custom_e2e/models/validation_error.py | 10 +- .../my_test_api_client/models/a_model.py | 113 +----------------- .../body_upload_file_tests_upload_post.py | 10 +- .../models/free_form_model.py | 10 +- .../models/http_validation_error.py | 10 +- ...odel_with_additional_properties_inlined.py | 10 +- ..._properties_inlined_additional_property.py | 14 +-- .../model_with_additional_properties_refed.py | 10 +- .../models/model_with_any_json_properties.py | 10 +- ...any_json_properties_additional_property.py | 10 +- ...el_with_primitive_additional_properties.py | 10 +- ...ive_additional_properties_a_date_holder.py | 10 +- .../models/model_with_union_property.py | 10 +- .../models/test_inline_objects_json_body.py | 10 +- .../test_inline_objects_response_200.py | 10 +- .../models/validation_error.py | 10 +- openapi_python_client/templates/model.pyi | 11 +- 31 files changed, 188 insertions(+), 234 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 83d7518a7..e2bbc7101 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -1,5 +1,5 @@ import datetime -from typing import Any, Dict, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Type, TypeVar, Union, cast import attr from dateutil.parser import isoparse @@ -14,6 +14,8 @@ from ..models.model_with_union_property import ModelWithUnionProperty from ..types import UNSET, Unset +T = TypeVar("T", bound="AModel") + @attr.s(auto_attribs=True) class AModel: @@ -162,8 +164,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModel": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() an_enum_value = AnEnum(d.pop("an_enum_value")) @@ -337,7 +339,7 @@ def _parse_not_required_nullable_one_of_models( d.pop("not_required_nullable_one_of_models", UNSET) ) - a_model = AModel( + a_model = cls( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/body_upload_file_tests_upload_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/body_upload_file_tests_upload_post.py index 657411d54..97db03356 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/body_upload_file_tests_upload_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/body_upload_file_tests_upload_post.py @@ -1,10 +1,12 @@ from io import BytesIO -from typing import Any, Dict +from typing import Any, Dict, Type, TypeVar import attr from ..types import File +T = TypeVar("T", bound="BodyUploadFileTestsUploadPost") + @attr.s(auto_attribs=True) class BodyUploadFileTestsUploadPost: @@ -24,12 +26,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "BodyUploadFileTestsUploadPost": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() some_file = File(payload=BytesIO(d.pop("some_file"))) - body_upload_file_tests_upload_post = BodyUploadFileTestsUploadPost( + body_upload_file_tests_upload_post = cls( some_file=some_file, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/free_form_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/free_form_model.py index 0e1b93899..1a86b6bac 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/free_form_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/free_form_model.py @@ -1,7 +1,9 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr +T = TypeVar("T", bound="FreeFormModel") + @attr.s(auto_attribs=True) class FreeFormModel: @@ -17,10 +19,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "FreeFormModel": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - free_form_model = FreeFormModel() + free_form_model = cls() free_form_model.additional_properties = d return free_form_model diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py index 1b25a6d98..3025b07af 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py @@ -1,10 +1,12 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr from ..models.validation_error import ValidationError from ..types import UNSET, Unset +T = TypeVar("T", bound="HTTPValidationError") + @attr.s(auto_attribs=True) class HTTPValidationError: @@ -28,8 +30,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() detail = [] _detail = d.pop("detail", UNSET) @@ -38,7 +40,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError": detail.append(detail_item) - http_validation_error = HTTPValidationError( + http_validation_error = cls( detail=detail, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py index 30acb7957..a81e57a8e 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr @@ -7,6 +7,8 @@ ) from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlined") + @attr.s(auto_attribs=True) class ModelWithAdditionalPropertiesInlined: @@ -30,12 +32,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlined": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_number = d.pop("a_number", UNSET) - model_with_additional_properties_inlined = ModelWithAdditionalPropertiesInlined( + model_with_additional_properties_inlined = cls( a_number=a_number, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined_additional_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined_additional_property.py index 4ce45f8ef..baedb6193 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined_additional_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_inlined_additional_property.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlinedAdditionalProperty") + @attr.s(auto_attribs=True) class ModelWithAdditionalPropertiesInlinedAdditionalProperty: @@ -23,15 +25,13 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlinedAdditionalProperty": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() extra_props_prop = d.pop("extra_props_prop", UNSET) - model_with_additional_properties_inlined_additional_property = ( - ModelWithAdditionalPropertiesInlinedAdditionalProperty( - extra_props_prop=extra_props_prop, - ) + model_with_additional_properties_inlined_additional_property = cls( + extra_props_prop=extra_props_prop, ) model_with_additional_properties_inlined_additional_property.additional_properties = d diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_refed.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_refed.py index c5eb4a7a4..b265db582 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_refed.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_additional_properties_refed.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr from ..models.an_enum import AnEnum +T = TypeVar("T", bound="ModelWithAdditionalPropertiesRefed") + @attr.s(auto_attribs=True) class ModelWithAdditionalPropertiesRefed: @@ -21,10 +23,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesRefed": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_additional_properties_refed = ModelWithAdditionalPropertiesRefed() + model_with_additional_properties_refed = cls() additional_properties = {} for prop_name, prop_dict in d.items(): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py index 7971f562e..716bcd618 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, List, Union, cast +from typing import Any, Dict, List, Type, TypeVar, Union, cast import attr from ..models.model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty +T = TypeVar("T", bound="ModelWithAnyJsonProperties") + @attr.s(auto_attribs=True) class ModelWithAnyJsonProperties: @@ -30,10 +32,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonProperties": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_any_json_properties = ModelWithAnyJsonProperties() + model_with_any_json_properties = cls() additional_properties = {} for prop_name, prop_dict in d.items(): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py index c823a73ed..69aa84641 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py @@ -1,7 +1,9 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr +T = TypeVar("T", bound="ModelWithAnyJsonPropertiesAdditionalProperty") + @attr.s(auto_attribs=True) class ModelWithAnyJsonPropertiesAdditionalProperty: @@ -17,10 +19,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonPropertiesAdditionalProperty": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_any_json_properties_additional_property = ModelWithAnyJsonPropertiesAdditionalProperty() + model_with_any_json_properties_additional_property = cls() model_with_any_json_properties_additional_property.additional_properties = d return model_with_any_json_properties_additional_property diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 32b23d7e5..68e2238dd 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr @@ -7,6 +7,8 @@ ) from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithPrimitiveAdditionalProperties") + @attr.s(auto_attribs=True) class ModelWithPrimitiveAdditionalProperties: @@ -28,15 +30,15 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder) - model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( + model_with_primitive_additional_properties = cls( a_date_holder=a_date_holder, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties_a_date_holder.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties_a_date_holder.py index 394c68a12..3df34635f 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties_a_date_holder.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties_a_date_holder.py @@ -1,9 +1,11 @@ import datetime -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr from dateutil.parser import isoparse +T = TypeVar("T", bound="ModelWithPrimitiveAdditionalPropertiesADateHolder") + @attr.s(auto_attribs=True) class ModelWithPrimitiveAdditionalPropertiesADateHolder: @@ -21,10 +23,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalPropertiesADateHolder": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_primitive_additional_properties_a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder() + model_with_primitive_additional_properties_a_date_holder = cls() additional_properties = {} for prop_name, prop_dict in d.items(): diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py index 3b417f3f5..5c3414949 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Union +from typing import Any, Dict, Type, TypeVar, Union import attr @@ -6,6 +6,8 @@ from ..models.an_int_enum import AnIntEnum from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithUnionProperty") + @attr.s(auto_attribs=True) class ModelWithUnionProperty: @@ -34,8 +36,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithUnionProperty": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: @@ -64,7 +66,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum a_property = _parse_a_property(d.pop("a_property", UNSET)) - model_with_union_property = ModelWithUnionProperty( + model_with_union_property = cls( a_property=a_property, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_json_body.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_json_body.py index e607209ca..1ee542873 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_json_body.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_json_body.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, Union +from typing import Any, Dict, Type, TypeVar, Union import attr from ..types import UNSET, Unset +T = TypeVar("T", bound="TestInlineObjectsJsonBody") + @attr.s(auto_attribs=True) class TestInlineObjectsJsonBody: @@ -21,12 +23,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "TestInlineObjectsJsonBody": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_property = d.pop("a_property", UNSET) - test_inline_objects_json_body = TestInlineObjectsJsonBody( + test_inline_objects_json_body = cls( a_property=a_property, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_response_200.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_response_200.py index 79daf6731..6e44a5b14 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_response_200.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objects_response_200.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, Union +from typing import Any, Dict, Type, TypeVar, Union import attr from ..types import UNSET, Unset +T = TypeVar("T", bound="TestInlineObjectsResponse_200") + @attr.s(auto_attribs=True) class TestInlineObjectsResponse_200: @@ -21,12 +23,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "TestInlineObjectsResponse_200": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_property = d.pop("a_property", UNSET) - test_inline_objects_response_200 = TestInlineObjectsResponse_200( + test_inline_objects_response_200 = cls( a_property=a_property, ) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/validation_error.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/validation_error.py index 2cd2b8959..a0cd07b51 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/validation_error.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/validation_error.py @@ -1,7 +1,9 @@ -from typing import Any, Dict, List, cast +from typing import Any, Dict, List, Type, TypeVar, cast import attr +T = TypeVar("T", bound="ValidationError") + @attr.s(auto_attribs=True) class ValidationError: @@ -28,8 +30,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ValidationError": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() loc = cast(List[str], d.pop("loc")) @@ -37,7 +39,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "ValidationError": type = d.pop("type") - validation_error = ValidationError( + validation_error = cls( loc=loc, msg=msg, type=type, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 83d7518a7..89a3b4790 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -1,5 +1,5 @@ import datetime -from typing import Any, Dict, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Type, TypeVar, Union, cast import attr from dateutil.parser import isoparse @@ -14,6 +14,8 @@ from ..models.model_with_union_property import ModelWithUnionProperty from ..types import UNSET, Unset +T = TypeVar("T", bound="AModel") + @attr.s(auto_attribs=True) class AModel: @@ -162,8 +164,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModel": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() an_enum_value = AnEnum(d.pop("an_enum_value")) @@ -234,110 +236,7 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) - nullable_model = None - _nullable_model = d.pop("nullable_model") - if _nullable_model is not None: - nullable_model = AModelNullableModel.from_dict(_nullable_model) - - not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET - _not_required_model = d.pop("not_required_model", UNSET) - if not isinstance(_not_required_model, Unset): - not_required_model = AModelNotRequiredModel.from_dict(_not_required_model) - - not_required_nullable_model = None - _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) - if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model) - - def _parse_nullable_one_of_models( - data: Union[None, Dict[str, Any]] - ) -> Union[None, FreeFormModel, ModelWithUnionProperty]: - nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] - if data is None: - return data - try: - if not isinstance(data, dict): - raise TypeError() - nullable_one_of_models = FreeFormModel.from_dict(data) - - return nullable_one_of_models - except: # noqa: E722 - pass - if not isinstance(data, dict): - raise TypeError() - nullable_one_of_models = ModelWithUnionProperty.from_dict(data) - - return nullable_one_of_models - - nullable_one_of_models = _parse_nullable_one_of_models(d.pop("nullable_one_of_models")) - - def _parse_not_required_one_of_models( - data: Union[Unset, Dict[str, Any]] - ) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: - not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - not_required_one_of_models = UNSET - _not_required_one_of_models = data - if not isinstance(_not_required_one_of_models, Unset): - not_required_one_of_models = FreeFormModel.from_dict(_not_required_one_of_models) - - return not_required_one_of_models - except: # noqa: E722 - pass - if not isinstance(data, dict): - raise TypeError() - not_required_one_of_models = UNSET - _not_required_one_of_models = data - if not isinstance(_not_required_one_of_models, Unset): - not_required_one_of_models = ModelWithUnionProperty.from_dict(_not_required_one_of_models) - - return not_required_one_of_models - - not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) - - def _parse_not_required_nullable_one_of_models( - data: Union[Unset, None, Dict[str, Any], str] - ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str]: - not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - not_required_nullable_one_of_models = UNSET - _not_required_nullable_one_of_models = data - if not isinstance(_not_required_nullable_one_of_models, Unset): - not_required_nullable_one_of_models = FreeFormModel.from_dict(_not_required_nullable_one_of_models) - - return not_required_nullable_one_of_models - except: # noqa: E722 - pass - try: - if not isinstance(data, dict): - raise TypeError() - not_required_nullable_one_of_models = UNSET - _not_required_nullable_one_of_models = data - if not isinstance(_not_required_nullable_one_of_models, Unset): - not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( - _not_required_nullable_one_of_models - ) - - return not_required_nullable_one_of_models - except: # noqa: E722 - pass - return cast(Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str], data) - - not_required_nullable_one_of_models = _parse_not_required_nullable_one_of_models( - d.pop("not_required_nullable_one_of_models", UNSET) - ) - - a_model = AModel( + a_model = cls( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, a_date=a_date, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/body_upload_file_tests_upload_post.py b/end_to_end_tests/golden-record/my_test_api_client/models/body_upload_file_tests_upload_post.py index 657411d54..97db03356 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/body_upload_file_tests_upload_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/body_upload_file_tests_upload_post.py @@ -1,10 +1,12 @@ from io import BytesIO -from typing import Any, Dict +from typing import Any, Dict, Type, TypeVar import attr from ..types import File +T = TypeVar("T", bound="BodyUploadFileTestsUploadPost") + @attr.s(auto_attribs=True) class BodyUploadFileTestsUploadPost: @@ -24,12 +26,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "BodyUploadFileTestsUploadPost": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() some_file = File(payload=BytesIO(d.pop("some_file"))) - body_upload_file_tests_upload_post = BodyUploadFileTestsUploadPost( + body_upload_file_tests_upload_post = cls( some_file=some_file, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py index 0e1b93899..1a86b6bac 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/free_form_model.py @@ -1,7 +1,9 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr +T = TypeVar("T", bound="FreeFormModel") + @attr.s(auto_attribs=True) class FreeFormModel: @@ -17,10 +19,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "FreeFormModel": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - free_form_model = FreeFormModel() + free_form_model = cls() free_form_model.additional_properties = d return free_form_model diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py b/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py index 1b25a6d98..3025b07af 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py @@ -1,10 +1,12 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr from ..models.validation_error import ValidationError from ..types import UNSET, Unset +T = TypeVar("T", bound="HTTPValidationError") + @attr.s(auto_attribs=True) class HTTPValidationError: @@ -28,8 +30,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() detail = [] _detail = d.pop("detail", UNSET) @@ -38,7 +40,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "HTTPValidationError": detail.append(detail_item) - http_validation_error = HTTPValidationError( + http_validation_error = cls( detail=detail, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py index 30acb7957..a81e57a8e 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr @@ -7,6 +7,8 @@ ) from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlined") + @attr.s(auto_attribs=True) class ModelWithAdditionalPropertiesInlined: @@ -30,12 +32,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlined": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_number = d.pop("a_number", UNSET) - model_with_additional_properties_inlined = ModelWithAdditionalPropertiesInlined( + model_with_additional_properties_inlined = cls( a_number=a_number, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py index 4ce45f8ef..baedb6193 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlinedAdditionalProperty") + @attr.s(auto_attribs=True) class ModelWithAdditionalPropertiesInlinedAdditionalProperty: @@ -23,15 +25,13 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesInlinedAdditionalProperty": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() extra_props_prop = d.pop("extra_props_prop", UNSET) - model_with_additional_properties_inlined_additional_property = ( - ModelWithAdditionalPropertiesInlinedAdditionalProperty( - extra_props_prop=extra_props_prop, - ) + model_with_additional_properties_inlined_additional_property = cls( + extra_props_prop=extra_props_prop, ) model_with_additional_properties_inlined_additional_property.additional_properties = d diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py index c5eb4a7a4..b265db582 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_refed.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr from ..models.an_enum import AnEnum +T = TypeVar("T", bound="ModelWithAdditionalPropertiesRefed") + @attr.s(auto_attribs=True) class ModelWithAdditionalPropertiesRefed: @@ -21,10 +23,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAdditionalPropertiesRefed": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_additional_properties_refed = ModelWithAdditionalPropertiesRefed() + model_with_additional_properties_refed = cls() additional_properties = {} for prop_name, prop_dict in d.items(): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py index 7971f562e..716bcd618 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, List, Union, cast +from typing import Any, Dict, List, Type, TypeVar, Union, cast import attr from ..models.model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty +T = TypeVar("T", bound="ModelWithAnyJsonProperties") + @attr.s(auto_attribs=True) class ModelWithAnyJsonProperties: @@ -30,10 +32,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonProperties": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_any_json_properties = ModelWithAnyJsonProperties() + model_with_any_json_properties = cls() additional_properties = {} for prop_name, prop_dict in d.items(): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py index c823a73ed..69aa84641 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py @@ -1,7 +1,9 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr +T = TypeVar("T", bound="ModelWithAnyJsonPropertiesAdditionalProperty") + @attr.s(auto_attribs=True) class ModelWithAnyJsonPropertiesAdditionalProperty: @@ -17,10 +19,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonPropertiesAdditionalProperty": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_any_json_properties_additional_property = ModelWithAnyJsonPropertiesAdditionalProperty() + model_with_any_json_properties_additional_property = cls() model_with_any_json_properties_additional_property.additional_properties = d return model_with_any_json_properties_additional_property diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 32b23d7e5..68e2238dd 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Type, TypeVar, Union import attr @@ -7,6 +7,8 @@ ) from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithPrimitiveAdditionalProperties") + @attr.s(auto_attribs=True) class ModelWithPrimitiveAdditionalProperties: @@ -28,15 +30,15 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) if not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder) - model_with_primitive_additional_properties = ModelWithPrimitiveAdditionalProperties( + model_with_primitive_additional_properties = cls( a_date_holder=a_date_holder, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py index 394c68a12..3df34635f 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties_a_date_holder.py @@ -1,9 +1,11 @@ import datetime -from typing import Any, Dict, List +from typing import Any, Dict, List, Type, TypeVar import attr from dateutil.parser import isoparse +T = TypeVar("T", bound="ModelWithPrimitiveAdditionalPropertiesADateHolder") + @attr.s(auto_attribs=True) class ModelWithPrimitiveAdditionalPropertiesADateHolder: @@ -21,10 +23,10 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalPropertiesADateHolder": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - model_with_primitive_additional_properties_a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder() + model_with_primitive_additional_properties_a_date_holder = cls() additional_properties = {} for prop_name, prop_dict in d.items(): diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py index 3b417f3f5..5c3414949 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Union +from typing import Any, Dict, Type, TypeVar, Union import attr @@ -6,6 +6,8 @@ from ..models.an_int_enum import AnIntEnum from ..types import UNSET, Unset +T = TypeVar("T", bound="ModelWithUnionProperty") + @attr.s(auto_attribs=True) class ModelWithUnionProperty: @@ -34,8 +36,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ModelWithUnionProperty": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: @@ -64,7 +66,7 @@ def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum a_property = _parse_a_property(d.pop("a_property", UNSET)) - model_with_union_property = ModelWithUnionProperty( + model_with_union_property = cls( a_property=a_property, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_json_body.py b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_json_body.py index e607209ca..1ee542873 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_json_body.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_json_body.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, Union +from typing import Any, Dict, Type, TypeVar, Union import attr from ..types import UNSET, Unset +T = TypeVar("T", bound="TestInlineObjectsJsonBody") + @attr.s(auto_attribs=True) class TestInlineObjectsJsonBody: @@ -21,12 +23,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "TestInlineObjectsJsonBody": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_property = d.pop("a_property", UNSET) - test_inline_objects_json_body = TestInlineObjectsJsonBody( + test_inline_objects_json_body = cls( a_property=a_property, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_response_200.py b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_response_200.py index 79daf6731..6e44a5b14 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_response_200.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objects_response_200.py @@ -1,9 +1,11 @@ -from typing import Any, Dict, Union +from typing import Any, Dict, Type, TypeVar, Union import attr from ..types import UNSET, Unset +T = TypeVar("T", bound="TestInlineObjectsResponse_200") + @attr.s(auto_attribs=True) class TestInlineObjectsResponse_200: @@ -21,12 +23,12 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "TestInlineObjectsResponse_200": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_property = d.pop("a_property", UNSET) - test_inline_objects_response_200 = TestInlineObjectsResponse_200( + test_inline_objects_response_200 = cls( a_property=a_property, ) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/validation_error.py b/end_to_end_tests/golden-record/my_test_api_client/models/validation_error.py index 2cd2b8959..a0cd07b51 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/validation_error.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/validation_error.py @@ -1,7 +1,9 @@ -from typing import Any, Dict, List, cast +from typing import Any, Dict, List, Type, TypeVar, cast import attr +T = TypeVar("T", bound="ValidationError") + @attr.s(auto_attribs=True) class ValidationError: @@ -28,8 +30,8 @@ def to_dict(self) -> Dict[str, Any]: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "ValidationError": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() loc = cast(List[str], d.pop("loc")) @@ -37,7 +39,7 @@ def from_dict(src_dict: Dict[str, Any]) -> "ValidationError": type = d.pop("type") - validation_error = ValidationError( + validation_error = cls( loc=loc, msg=msg, type=type, diff --git a/openapi_python_client/templates/model.pyi b/openapi_python_client/templates/model.pyi index 0c81a32f9..c286489e3 100644 --- a/openapi_python_client/templates/model.pyi +++ b/openapi_python_client/templates/model.pyi @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, Type, TypeVar {% if model.additional_properties %} from typing import List @@ -18,6 +18,8 @@ from ..types import UNSET, Unset {% set additional_property_type = 'Any' if model.additional_properties == True else model.additional_properties.get_type_string() %} {% endif %} +T = TypeVar("T", bound="{{ model.reference.class_name }}") + @attr.s(auto_attribs=True) class {{ model.reference.class_name }}: """ {{ model.description }} """ @@ -72,8 +74,8 @@ class {{ model.reference.class_name }}: return field_dict - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "{{ model.reference.class_name }}": + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() {% for property in model.required_properties + model.optional_properties %} {% if property.required %} @@ -89,7 +91,7 @@ class {{ model.reference.class_name }}: {% endif %} {% endfor %} - {{model.reference.module_name}} = {{ model.reference.class_name }}( + {{model.reference.module_name}} = cls( {% for property in model.required_properties + model.optional_properties %} {{ property.python_name }}={{ property.python_name }}, {% endfor %} @@ -127,4 +129,3 @@ class {{ model.reference.class_name }}: def __contains__(self, key: str) -> bool: return key in self.additional_properties {% endif %} - From f4becc399406fe27ebfd46df5cbdce25e303905c Mon Sep 17 00:00:00 2001 From: William Bowen Date: Fri, 22 Jan 2021 11:58:11 -0500 Subject: [PATCH 22/50] fix: Handle Unset Enums when deserializing (#306) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce2404f32..803c72e35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `setup` will generate a pyproject.toml with no Poetry information, and instead create a `setup.py` with the project info. - `none` will not create a project folder at all, only the inner package folder (which won't be inner anymore) +<<<<<<< HEAD - Lowered the minimum version of `python-dateutil` for improved dependency compatibility with other projects +======= +- Attempt to detect and alert users if they are using an unsupported version of OpenAPI (#281). +- Fixes `Enum` deserialization when the value is `UNSET`. + +### Changes +>>>>>>> aa6972c... fix: Handle Unset Enums when deserializing (#306) ## 0.7.3 - 2020-12-21 From 248d5662289246146843a3c1600494a1184928bb Mon Sep 17 00:00:00 2001 From: Forest Tong Date: Tue, 6 Apr 2021 17:12:10 -0400 Subject: [PATCH 23/50] Cherry-pick a755ed9dc77b7d7e394057159831fbfa327be113 (#54) --- .../custom_e2e/models/__init__.py | 4 - .../custom_e2e/models/a_model.py | 22 ++-- .../custom_e2e/models/a_model_model.py | 90 -------------- .../models/a_model_not_required_model.py | 90 -------------- .../a_model_not_required_nullable_model.py | 90 -------------- .../models/a_model_nullable_model.py | 90 -------------- .../my_test_api_client/models/__init__.py | 4 - .../my_test_api_client/models/a_model.py | 117 ++++++++++++++++-- .../models/a_model_model.py | 90 -------------- .../models/a_model_not_required_model.py | 90 -------------- .../a_model_not_required_nullable_model.py | 90 -------------- .../models/a_model_nullable_model.py | 90 -------------- .../parser/properties/__init__.py | 32 +++-- 13 files changed, 142 insertions(+), 757 deletions(-) delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py delete mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py delete mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py index 6f5ac7423..d3ca924b3 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py @@ -1,10 +1,6 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel -from .a_model_model import AModelModel -from .a_model_not_required_model import AModelNotRequiredModel -from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index e2bbc7101..95fd63166 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -4,10 +4,6 @@ import attr from dateutil.parser import isoparse -from ..models.a_model_model import AModelModel -from ..models.a_model_not_required_model import AModelNotRequiredModel -from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..models.free_form_model import FreeFormModel @@ -25,18 +21,18 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str - model: AModelModel + model: ModelWithUnionProperty one_of_models: Union[FreeFormModel, ModelWithUnionProperty] a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] - nullable_model: Optional[AModelNullableModel] + nullable_model: Optional[ModelWithUnionProperty] nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET - not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET - not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET + not_required_model: Union[Unset, ModelWithUnionProperty] = UNSET + not_required_nullable_model: Union[Unset, None, ModelWithUnionProperty] = UNSET not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] = UNSET not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] = UNSET @@ -191,7 +187,7 @@ def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datet required_not_nullable = d.pop("required_not_nullable") - model = AModelModel.from_dict(d.pop("model")) + model = ModelWithUnionProperty.from_dict(d.pop("model")) def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, ModelWithUnionProperty]: one_of_models: Union[FreeFormModel, ModelWithUnionProperty] @@ -239,17 +235,17 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo nullable_model = None _nullable_model = d.pop("nullable_model") if _nullable_model is not None: - nullable_model = AModelNullableModel.from_dict(_nullable_model) + nullable_model = ModelWithUnionProperty.from_dict(_nullable_model) - not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET + not_required_model: Union[Unset, ModelWithUnionProperty] = UNSET _not_required_model = d.pop("not_required_model", UNSET) if not isinstance(_not_required_model, Unset): - not_required_model = AModelNotRequiredModel.from_dict(_not_required_model) + not_required_model = ModelWithUnionProperty.from_dict(_not_required_model) not_required_nullable_model = None _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): - not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model) + not_required_nullable_model = ModelWithUnionProperty.from_dict(_not_required_nullable_model) def _parse_nullable_one_of_models( data: Union[None, Dict[str, Any]] diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py deleted file mode 100644 index cef48694b..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_model = AModelModel( - a_property=a_property, - ) - - a_model_model.additional_properties = d - return a_model_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py deleted file mode 100644 index 3f56b7f52..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_model = AModelNotRequiredModel( - a_property=a_property, - ) - - a_model_not_required_model.additional_properties = d - return a_model_not_required_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py deleted file mode 100644 index 55ef6810a..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_not_required_nullable_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_nullable_model = AModelNotRequiredNullableModel( - a_property=a_property, - ) - - a_model_not_required_nullable_model.additional_properties = d - return a_model_not_required_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py deleted file mode 100644 index 05c4f8897..000000000 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model_nullable_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_nullable_model = AModelNullableModel( - a_property=a_property, - ) - - a_model_nullable_model.additional_properties = d - return a_model_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index 6f5ac7423..d3ca924b3 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,10 +1,6 @@ """ Contains all the data models used in inputs/outputs """ from .a_model import AModel -from .a_model_model import AModelModel -from .a_model_not_required_model import AModelNotRequiredModel -from .a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from .a_model_nullable_model import AModelNullableModel from .an_enum import AnEnum from .an_int_enum import AnIntEnum from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 89a3b4790..95fd63166 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -4,10 +4,6 @@ import attr from dateutil.parser import isoparse -from ..models.a_model_model import AModelModel -from ..models.a_model_not_required_model import AModelNotRequiredModel -from ..models.a_model_not_required_nullable_model import AModelNotRequiredNullableModel -from ..models.a_model_nullable_model import AModelNullableModel from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum from ..models.free_form_model import FreeFormModel @@ -25,18 +21,18 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str - model: AModelModel + model: ModelWithUnionProperty one_of_models: Union[FreeFormModel, ModelWithUnionProperty] a_nullable_date: Optional[datetime.date] required_nullable: Optional[str] - nullable_model: Optional[AModelNullableModel] + nullable_model: Optional[ModelWithUnionProperty] nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET attr_1_leading_digit: Union[Unset, str] = UNSET not_required_nullable: Union[Unset, None, str] = UNSET not_required_not_nullable: Union[Unset, str] = UNSET - not_required_model: Union[Unset, AModelNotRequiredModel] = UNSET - not_required_nullable_model: Union[Unset, None, AModelNotRequiredNullableModel] = UNSET + not_required_model: Union[Unset, ModelWithUnionProperty] = UNSET + not_required_nullable_model: Union[Unset, None, ModelWithUnionProperty] = UNSET not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] = UNSET not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] = UNSET @@ -191,7 +187,7 @@ def _parse_a_camel_date_time(data: Union[str]) -> Union[datetime.datetime, datet required_not_nullable = d.pop("required_not_nullable") - model = AModelModel.from_dict(d.pop("model")) + model = ModelWithUnionProperty.from_dict(d.pop("model")) def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, ModelWithUnionProperty]: one_of_models: Union[FreeFormModel, ModelWithUnionProperty] @@ -236,6 +232,109 @@ def _parse_one_of_models(data: Union[Dict[str, Any]]) -> Union[FreeFormModel, Mo not_required_not_nullable = d.pop("not_required_not_nullable", UNSET) + nullable_model = None + _nullable_model = d.pop("nullable_model") + if _nullable_model is not None: + nullable_model = ModelWithUnionProperty.from_dict(_nullable_model) + + not_required_model: Union[Unset, ModelWithUnionProperty] = UNSET + _not_required_model = d.pop("not_required_model", UNSET) + if not isinstance(_not_required_model, Unset): + not_required_model = ModelWithUnionProperty.from_dict(_not_required_model) + + not_required_nullable_model = None + _not_required_nullable_model = d.pop("not_required_nullable_model", UNSET) + if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset): + not_required_nullable_model = ModelWithUnionProperty.from_dict(_not_required_nullable_model) + + def _parse_nullable_one_of_models( + data: Union[None, Dict[str, Any]] + ) -> Union[None, FreeFormModel, ModelWithUnionProperty]: + nullable_one_of_models: Union[None, FreeFormModel, ModelWithUnionProperty] + if data is None: + return data + try: + if not isinstance(data, dict): + raise TypeError() + nullable_one_of_models = FreeFormModel.from_dict(data) + + return nullable_one_of_models + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + nullable_one_of_models = ModelWithUnionProperty.from_dict(data) + + return nullable_one_of_models + + nullable_one_of_models = _parse_nullable_one_of_models(d.pop("nullable_one_of_models")) + + def _parse_not_required_one_of_models( + data: Union[Unset, Dict[str, Any]] + ) -> Union[Unset, FreeFormModel, ModelWithUnionProperty]: + not_required_one_of_models: Union[Unset, FreeFormModel, ModelWithUnionProperty] + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + not_required_one_of_models = UNSET + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = FreeFormModel.from_dict(_not_required_one_of_models) + + return not_required_one_of_models + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + not_required_one_of_models = UNSET + _not_required_one_of_models = data + if not isinstance(_not_required_one_of_models, Unset): + not_required_one_of_models = ModelWithUnionProperty.from_dict(_not_required_one_of_models) + + return not_required_one_of_models + + not_required_one_of_models = _parse_not_required_one_of_models(d.pop("not_required_one_of_models", UNSET)) + + def _parse_not_required_nullable_one_of_models( + data: Union[Unset, None, Dict[str, Any], str] + ) -> Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str]: + not_required_nullable_one_of_models: Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str] + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + not_required_nullable_one_of_models = UNSET + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = FreeFormModel.from_dict(_not_required_nullable_one_of_models) + + return not_required_nullable_one_of_models + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + not_required_nullable_one_of_models = UNSET + _not_required_nullable_one_of_models = data + if not isinstance(_not_required_nullable_one_of_models, Unset): + not_required_nullable_one_of_models = ModelWithUnionProperty.from_dict( + _not_required_nullable_one_of_models + ) + + return not_required_nullable_one_of_models + except: # noqa: E722 + pass + return cast(Union[Unset, None, FreeFormModel, ModelWithUnionProperty, str], data) + + not_required_nullable_one_of_models = _parse_not_required_nullable_one_of_models( + d.pop("not_required_nullable_one_of_models", UNSET) + ) + a_model = cls( an_enum_value=an_enum_value, a_camel_date_time=a_camel_date_time, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py deleted file mode 100644 index cef48694b..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_model = AModelModel( - a_property=a_property, - ) - - a_model_model.additional_properties = d - return a_model_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py deleted file mode 100644 index 3f56b7f52..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_model = AModelNotRequiredModel( - a_property=a_property, - ) - - a_model_not_required_model.additional_properties = d - return a_model_not_required_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py deleted file mode 100644 index 55ef6810a..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_not_required_nullable_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNotRequiredNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNotRequiredNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_not_required_nullable_model = AModelNotRequiredNullableModel( - a_property=a_property, - ) - - a_model_not_required_nullable_model.additional_properties = d - return a_model_not_required_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py deleted file mode 100644 index 05c4f8897..000000000 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_nullable_model.py +++ /dev/null @@ -1,90 +0,0 @@ -from typing import Any, Dict, List, Union - -import attr - -from ..models.an_enum import AnEnum -from ..models.an_int_enum import AnIntEnum -from ..types import UNSET, Unset - - -@attr.s(auto_attribs=True) -class AModelNullableModel: - """ """ - - a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET - additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) - - def to_dict(self) -> Dict[str, Any]: - a_property: Union[Unset, int] - if isinstance(self.a_property, Unset): - a_property = UNSET - elif isinstance(self.a_property, AnEnum): - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - else: - a_property = UNSET - if not isinstance(self.a_property, Unset): - a_property = self.a_property.value - - field_dict: Dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if a_property is not UNSET: - field_dict["a_property"] = a_property - - return field_dict - - @staticmethod - def from_dict(src_dict: Dict[str, Any]) -> "AModelNullableModel": - d = src_dict.copy() - - def _parse_a_property(data: Union[Unset, int]) -> Union[Unset, AnEnum, AnIntEnum]: - a_property: Union[Unset, AnEnum, AnIntEnum] - if isinstance(data, Unset): - return data - try: - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnEnum(_a_property) - - return a_property - except: # noqa: E722 - pass - if not (isinstance(data, int) or isinstance(data, str)): - raise TypeError() - a_property = UNSET - _a_property = data - if _a_property is not None: - a_property = AnIntEnum(_a_property) - - return a_property - - a_property = _parse_a_property(d.pop("a_property", UNSET)) - - a_model_nullable_model = AModelNullableModel( - a_property=a_property, - ) - - a_model_nullable_model.additional_properties = d - return a_model_nullable_model - - @property - def additional_keys(self) -> List[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 1794cf6ed..f6d9e3626 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -466,6 +466,23 @@ def build_list_property( ) +def _property_from_ref( + name: str, + required: bool, + nullable: bool, + data: oai.Reference, + schemas: Schemas, +) -> Tuple[Union[Property, PropertyError], Schemas]: + reference = Reference.from_ref(data.ref) + existing = schemas.enums.get(reference.class_name) or schemas.models.get(reference.class_name) + if existing: + return ( + attr.evolve(existing, required=required, name=name, nullable=nullable), + schemas, + ) + return PropertyError(data=data, detail="Could not find reference in parsed models or enums"), schemas + + def _property_from_data( name: str, required: bool, @@ -476,14 +493,15 @@ def _property_from_data( """ Generate a Property from the OpenAPI dictionary representation of it """ name = utils.remove_string_escapes(name) if isinstance(data, oai.Reference): - reference = Reference.from_ref(data.ref) - existing = schemas.enums.get(reference.class_name) or schemas.models.get(reference.class_name) - if existing: - return ( - attr.evolve(existing, required=required, name=name), - schemas, + return _property_from_ref(name=name, required=required, nullable=False, data=data, schemas=schemas) + + for attribute in ["allOf", "anyOf", "oneOf"]: + sub_data = getattr(data, attribute) + if sub_data and len(sub_data) == 1 and isinstance(sub_data[0], oai.Reference): + return _property_from_ref( + name=name, required=required, nullable=data.nullable, data=sub_data[0], schemas=schemas ) - return PropertyError(data=data, detail="Could not find reference in parsed models or enums"), schemas + if data.enum: return build_enum_property( data=data, name=name, required=required, schemas=schemas, enum=data.enum, parent_name=parent_name From 0e1afa8e6385e23210de24206dc085a5211c660f Mon Sep 17 00:00:00 2001 From: George Murray Date: Thu, 8 Jul 2021 13:29:12 -0700 Subject: [PATCH 24/50] fix: Generate parameters to generated client without adding None BNCH-22940 (#77) Upstream generates the client this way, and in a parallel benchling-sdk ticket we'll be doing a conversion to UNSET for None parameters in the service layer. Making this change in the fork in the meantime will keep us in a good state. --- openapi_python_client/parser/properties/property.py | 6 +----- .../templates/property_templates/date_property.pyi | 2 +- .../templates/property_templates/datetime_property.pyi | 2 +- .../templates/property_templates/enum_property.pyi | 2 +- .../templates/property_templates/file_property.pyi | 2 +- .../templates/property_templates/list_property.pyi | 2 +- .../templates/property_templates/model_property.pyi | 2 +- .../templates/property_templates/union_property.pyi | 2 +- 8 files changed, 8 insertions(+), 12 deletions(-) diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index c0ec0d56e..542e2a5f7 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -62,11 +62,7 @@ def get_type_string(self, no_optional: bool = False, query_parameter: bool = Fal if self.nullable: return f"Union[Unset, None, {type_string}]" else: - if query_parameter: - # For query parameters, None has the same meaning as Unset - return f"Union[Unset, None, {type_string}]" - else: - return f"Union[Unset, {type_string}]" + return f"Union[Unset, {type_string}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index d883d8787..528a9961b 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -17,7 +17,7 @@ if _{{ property.python_name }} is not None: {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable or query_parameter %} +{% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.isoformat() diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index 53f432a59..5442c75fe 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -26,7 +26,7 @@ if _{{ property.python_name }} is not None: {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable or query_parameter %} +{% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.isoformat() diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 764e66ade..4c33ba051 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -21,7 +21,7 @@ if _{{ property.python_name }} is not None and _{{ property.python_name }} is no {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable or query_parameter %} +{% if property.nullable %} {{ destination }} = {{ source }}.value if {{ source }} else None {% else %} {{ destination }} = {{ source }}.value diff --git a/openapi_python_client/templates/property_templates/file_property.pyi b/openapi_python_client/templates/property_templates/file_property.pyi index 3a5b5e746..1758c07f6 100644 --- a/openapi_python_client/templates/property_templates/file_property.pyi +++ b/openapi_python_client/templates/property_templates/file_property.pyi @@ -16,7 +16,7 @@ {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable or query_parameter %} +{% if property.nullable %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.to_tuple() diff --git a/openapi_python_client/templates/property_templates/list_property.pyi b/openapi_python_client/templates/property_templates/list_property.pyi index 6f2d03f68..0705e9d93 100644 --- a/openapi_python_client/templates/property_templates/list_property.pyi +++ b/openapi_python_client/templates/property_templates/list_property.pyi @@ -48,7 +48,7 @@ else: {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable or query_parameter %} +{% if property.nullable %} if {{ source }} is None: {{ destination }} = None else: diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index 1cabf2996..40a8a8b78 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -27,7 +27,7 @@ if {% if property.nullable %}_{{ property.python_name }} is not None{% endif %}{ {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string(query_parameter=query_parameter, json=True) }}{% endif %} = UNSET if not isinstance({{ source }}, Unset): -{% if property.nullable or query_parameter %} +{% if property.nullable %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None {% else %} {{ destination }} = {{ source }}.to_dict() diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index c414fb65d..179dd4ae3 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -45,7 +45,7 @@ def _parse_{{ property.python_name }}(data: {{ property.get_type_string(json=Tru if isinstance({{ source }}, Unset): {{ destination }} = UNSET {% endif %} -{% if property.nullable or (query_parameter and not property.required) %} +{% if property.nullable %} {% if property.required %} if {{ source }} is None: {% else %}{# There's an if UNSET statement before this #} From e22c23540734134d9b8d026a63e625343a1de6df Mon Sep 17 00:00:00 2001 From: George Murray Date: Thu, 23 Sep 2021 08:49:36 -0700 Subject: [PATCH 25/50] feat: Add description to Property definitions BNCH-29178 To enable adding docstrings to python members in a generated way from the OpenAPI spec, add the description member to Property objects (which have been already parsed by the generator just not included in templates). --- .../parser/properties/__init__.py | 18 +++++++++++++++++- .../parser/properties/property.py | 1 + openapi_python_client/parser/responses.py | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index f6d9e3626..cfb585380 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -239,6 +239,7 @@ def _string_based_property( required=required, default=convert("datetime.datetime", data.default), nullable=data.nullable, + description=data.description, ) elif string_format == "date": return DateProperty( @@ -246,6 +247,7 @@ def _string_based_property( required=required, default=convert("datetime.date", data.default), nullable=data.nullable, + description=data.description, ) elif string_format == "binary": return FileProperty( @@ -253,6 +255,7 @@ def _string_based_property( required=required, default=None, nullable=data.nullable, + description=data.description, ) else: return StringProperty( @@ -261,6 +264,7 @@ def _string_based_property( required=required, pattern=data.pattern, nullable=data.nullable, + description=data.description, ) @@ -414,6 +418,7 @@ def build_enum_property( reference=reference, values=values, value_type=value_type, + description=data.description, ) schemas = attr.evolve(schemas, enums={**schemas.enums, prop.reference.class_name: prop}) return prop, schemas @@ -439,6 +444,7 @@ def build_union_property( default=default, inner_properties=sub_properties, nullable=data.nullable, + description=data.description, ), schemas, ) @@ -461,6 +467,7 @@ def build_list_property( default=None, inner_property=inner_prop, nullable=data.nullable, + description=data.description, ), schemas, ) @@ -517,6 +524,7 @@ def _property_from_data( default=convert("float", data.default), required=required, nullable=data.nullable, + description=data.description, ), schemas, ) @@ -527,6 +535,7 @@ def _property_from_data( default=convert("int", data.default), required=required, nullable=data.nullable, + description=data.description, ), schemas, ) @@ -537,6 +546,7 @@ def _property_from_data( required=required, default=convert("bool", data.default), nullable=data.nullable, + description=data.description, ), schemas, ) @@ -545,7 +555,13 @@ def _property_from_data( elif data.type == "object" or data.allOf: return build_model_property(data=data, name=name, schemas=schemas, required=required, parent_name=parent_name) elif not data.type: - return NoneProperty(name=name, required=required, nullable=False, default=None), schemas + return NoneProperty( + name=name, + required=required, + nullable=False, + default=None, + description=data.description + ), schemas return PropertyError(data=data, detail=f"unknown type {data.type}"), schemas diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index 542e2a5f7..2067e1539 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -27,6 +27,7 @@ class Property: _json_type_string: ClassVar[str] = "" # Type of the property after JSON serialization default: Optional[str] = attr.ib() python_name: str = attr.ib(init=False) + description: Optional[str] template: ClassVar[Optional[str]] = None json_is_dict: ClassVar[bool] = False diff --git a/openapi_python_client/parser/responses.py b/openapi_python_client/parser/responses.py index c6c6a49a1..b59937cd8 100644 --- a/openapi_python_client/parser/responses.py +++ b/openapi_python_client/parser/responses.py @@ -28,7 +28,7 @@ class Response: def empty_response(status_code: int, response_name: str) -> Response: return Response( status_code=status_code, - prop=NoneProperty(name=response_name, default=None, nullable=False, required=True), + prop=NoneProperty(name=response_name, default=None, nullable=False, required=True, description=None), source="None", ) From 6c40881765505f4700543a428a89449652895343 Mon Sep 17 00:00:00 2001 From: George Murray Date: Fri, 24 Sep 2021 19:17:55 -0700 Subject: [PATCH 26/50] feat: Implement discriminators knowledge in code generation BNCH-30443 (#87) The bulk of logic for this change is in benchling/benchling-sdk#180. This change adds knowledge of type mappings in the union property type for usage downstream. --- .../parser/properties/__init__.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index cfb585380..9a7ce2c11 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -162,6 +162,8 @@ class UnionProperty(Property): inner_properties: List[Property] template: ClassVar[str] = "union_property.pyi" has_properties_without_templates: bool = attr.ib(init=False) + discriminator_property: Optional[str] + discriminator_mappings: Dict[str, Property] def __attrs_post_init__(self) -> None: super().__attrs_post_init__() @@ -171,6 +173,8 @@ def __attrs_post_init__(self) -> None: def _get_inner_type_strings(self, json: bool = False) -> List[str]: inner_types = [p.get_type_string(no_optional=True, json=json) for p in self.inner_properties] + if not json: + inner_types.append("UnknownType") unique_inner_types = list(dict.fromkeys(inner_types)) return unique_inner_types @@ -428,13 +432,27 @@ def build_union_property( *, data: oai.Schema, name: str, required: bool, schemas: Schemas, parent_name: str ) -> Tuple[Union[UnionProperty, PropertyError], Schemas]: sub_properties: List[Property] = [] + inverted_mappings = {} + for k, v in (data.discriminator.mapping if data.discriminator else {}).items(): + class_name = Reference.from_ref(v).class_name + if class_name in inverted_mappings: + raise ArgumentError( + f"Mapping more than one name to a class is currently not supported (class: {class_name})." + ) + inverted_mappings[Reference.from_ref(v).class_name] = k + discriminator_mappings: Dict[str, Property] = {} for sub_prop_data in chain(data.anyOf, data.oneOf): sub_prop, schemas = property_from_data( name=name, required=required, data=sub_prop_data, schemas=schemas, parent_name=parent_name ) if isinstance(sub_prop, PropertyError): return PropertyError(detail=f"Invalid property in union {name}", data=sub_prop_data), schemas + sub_properties.append(sub_prop) + if data.discriminator is not None: + discriminated_by = inverted_mappings.get(sub_prop.reference.class_name) + if discriminated_by is not None: + discriminator_mappings[discriminated_by] = sub_prop default = convert_chain((prop._type_string for prop in sub_properties), data.default) return ( @@ -444,6 +462,8 @@ def build_union_property( default=default, inner_properties=sub_properties, nullable=data.nullable, + discriminator_property=data.discriminator.propertyName if data.discriminator else None, + discriminator_mappings=discriminator_mappings, description=data.description, ), schemas, From 800bf60f4326207004b433b327fcfcec738d003e Mon Sep 17 00:00:00 2001 From: George Murray Date: Thu, 14 Oct 2021 09:46:57 -0700 Subject: [PATCH 27/50] fix: null in openapi enums breaks client generation BNCH-32257 (#95) --- openapi_python_client/parser/properties/enum_property.py | 4 +++- tests/test_parser/test_properties/test_init.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/parser/properties/enum_property.py b/openapi_python_client/parser/properties/enum_property.py index 6938dd716..f28a4baf1 100644 --- a/openapi_python_client/parser/properties/enum_property.py +++ b/openapi_python_client/parser/properties/enum_property.py @@ -50,7 +50,9 @@ def values_from_list(values: List[ValueType]) -> Dict[str, ValueType]: else: output[f"VALUE_{value}"] = value continue - if value[0].isalpha(): + if value is None: + continue + if value and value[0].isalpha(): key = value.upper() else: key = f"VALUE_{i}" diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 604b1bd1d..9e856e26f 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -456,7 +456,7 @@ def test_get_imports(self, mocker): def test_values_from_list(self): from openapi_python_client.parser.properties import EnumProperty - data = ["abc", "123", "a23", "1bc", 4, -3, "a Thing WIth spaces"] + data = ["abc", "123", "a23", "1bc", 4, -3, "a Thing WIth spaces", "", None] result = EnumProperty.values_from_list(data) @@ -468,6 +468,7 @@ def test_values_from_list(self): "VALUE_4": 4, "VALUE_NEGATIVE_3": -3, "A_THING_WITH_SPACES": "a Thing WIth spaces", + "VALUE_7": "", } def test_values_from_list_duplicate(self): From cef60fec07b3179fd01af79206778b5230d618b6 Mon Sep 17 00:00:00 2001 From: Steve Strassmann Date: Fri, 11 Feb 2022 10:04:19 -0500 Subject: [PATCH 28/50] attrs dependencies (#105) --- openapi_python_client/templates/pyproject.toml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/templates/pyproject.toml b/openapi_python_client/templates/pyproject.toml index 97e1f543c..010e64bc5 100644 --- a/openapi_python_client/templates/pyproject.toml +++ b/openapi_python_client/templates/pyproject.toml @@ -15,7 +15,7 @@ include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] [tool.poetry.dependencies] python = "^3.6" httpx = "^0.15.0" -attrs = "^20.1.0" +attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" [tool.black] diff --git a/pyproject.toml b/pyproject.toml index 4d74fea82..c16090c62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ isort = "^5.0.5" pyyaml = "^5.3.1" importlib_metadata = {version = "^2.0.0", python = "<3.8"} pydantic = "^1.6.1" -attrs = "^20.1.0" +attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.1" httpx = ">=0.15.4,<0.17.0" autoflake = "^1.4" From 57f732babb5fe8e912dadfb166ace9fbcad8612f Mon Sep 17 00:00:00 2001 From: Rebecca Weinberger Date: Thu, 17 Feb 2022 12:33:42 -0800 Subject: [PATCH 29/50] fix: Support discriminators that map multiple keys to the same schema component BNCH-37105 (#108) --- .../parser/properties/__init__.py | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 9a7ce2c11..b26c05f93 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -432,15 +432,7 @@ def build_union_property( *, data: oai.Schema, name: str, required: bool, schemas: Schemas, parent_name: str ) -> Tuple[Union[UnionProperty, PropertyError], Schemas]: sub_properties: List[Property] = [] - inverted_mappings = {} - for k, v in (data.discriminator.mapping if data.discriminator else {}).items(): - class_name = Reference.from_ref(v).class_name - if class_name in inverted_mappings: - raise ArgumentError( - f"Mapping more than one name to a class is currently not supported (class: {class_name})." - ) - inverted_mappings[Reference.from_ref(v).class_name] = k - discriminator_mappings: Dict[str, Property] = {} + reference_name_to_subprop = {} for sub_prop_data in chain(data.anyOf, data.oneOf): sub_prop, schemas = property_from_data( name=name, required=required, data=sub_prop_data, schemas=schemas, parent_name=parent_name @@ -450,9 +442,13 @@ def build_union_property( sub_properties.append(sub_prop) if data.discriminator is not None: - discriminated_by = inverted_mappings.get(sub_prop.reference.class_name) - if discriminated_by is not None: - discriminator_mappings[discriminated_by] = sub_prop + reference_name_to_subprop[sub_prop.reference.class_name] = sub_prop + + discriminator_mappings: Dict[str, Property] = {} + if data.discriminator is not None: + for k, v in (data.discriminator.mapping if data.discriminator else {}).items(): + ref_class_name = Reference.from_ref(v).class_name + discriminator_mappings[k] = reference_name_to_subprop[ref_class_name] default = convert_chain((prop._type_string for prop in sub_properties), data.default) return ( From e01b09e64df05d84cf9d46716e0da6ccebd758b4 Mon Sep 17 00:00:00 2001 From: jschlaakhs Date: Mon, 4 Apr 2022 10:16:33 -0500 Subject: [PATCH 30/50] bumped importlib_metadata version to >=4.4 to fix a conflict with Sphinx documentation library in Benchling SDK (#112) --- poetry.lock | 972 ++++++++++++++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 591 insertions(+), 383 deletions(-) diff --git a/poetry.lock b/poetry.lock index cad5b1f82..36174ebc3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -16,17 +16,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "20.3.0" +version = "21.4.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] [[package]] name = "autoflake" @@ -64,19 +64,22 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "certifi" -version = "2020.6.20" +version = "2021.10.8" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = "*" [[package]] -name = "chardet" -version = "3.0.4" -description = "Universal encoding detector for Python 2 and 3" +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] [[package]] name = "click" @@ -107,22 +110,25 @@ immutables = ">=0.9" [[package]] name = "coverage" -version = "5.3" +version = "6.2" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.6" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] -toml = ["toml"] +toml = ["tomli"] [[package]] name = "dataclasses" -version = "0.6" +version = "0.8" description = "A backport of the dataclasses module for Python 3.6" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6, <3.7" [[package]] name = "dparse" @@ -142,29 +148,32 @@ pipenv = ["pipenv"] [[package]] name = "flake8" -version = "3.8.4" -description = "the modular source code checker: pep8 pyflakes and co" +version = "2.3.0" +description = "the modular source code checker: pep8, pyflakes and co" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = "*" [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.6.0a1,<2.7.0" -pyflakes = ">=2.2.0,<2.3.0" +mccabe = ">=0.2.1" +pep8 = ">=1.5.7" +pyflakes = ">=0.8.1" [[package]] name = "h11" -version = "0.9.0" +version = "0.13.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" + +[package.dependencies] +dataclasses = {version = "*", markers = "python_version < \"3.7\""} +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "httpcore" -version = "0.12.0" +version = "0.12.3" description = "A minimal low-level HTTP client." category = "main" optional = false @@ -197,38 +206,46 @@ http2 = ["h2 (>=3.0.0,<4.0.0)"] [[package]] name = "idna" -version = "2.10" +version = "3.3" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.5" [[package]] name = "immutables" -version = "0.14" +version = "0.17" description = "Immutable Collections" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} + +[package.extras] +test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)", "mypy (>=0.910)", "pytest (>=6.2.4,<6.3.0)"] [[package]] name = "importlib-metadata" -version = "2.0.0" +version = "4.8.3" description = "Read metadata from Python packages" category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6" [package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "rst.linker"] -testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" -version = "1.0.1" +version = "1.1.1" description = "iniconfig: brain-dead simple config-ini parsing" category = "dev" optional = false @@ -236,7 +253,7 @@ python-versions = "*" [[package]] name = "isort" -version = "5.6.4" +version = "5.8.0" description = "A Python utility / library to sort Python imports." category = "main" optional = false @@ -249,7 +266,7 @@ colors = ["colorama (>=0.4.3,<0.5.0)"] [[package]] name = "jinja2" -version = "2.11.2" +version = "2.11.3" description = "A very fast and expressive template engine." category = "main" optional = false @@ -263,19 +280,19 @@ i18n = ["Babel (>=0.8)"] [[package]] name = "markupsafe" -version = "1.1.1" +version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +python-versions = ">=3.6" [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "mslex" @@ -287,19 +304,22 @@ python-versions = ">=3.5" [[package]] name = "mypy" -version = "0.790" +version = "0.942" description = "Optional static typing for Python" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] -mypy-extensions = ">=0.4.3,<0.5.0" -typed-ast = ">=1.4.0,<1.5.0" -typing-extensions = ">=3.7.4" +mypy-extensions = ">=0.4.3" +tomli = ">=1.1.0" +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -311,41 +331,49 @@ python-versions = "*" [[package]] name = "packaging" -version = "20.4" +version = "21.3" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2" -six = "*" +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pathspec" -version = "0.8.0" +version = "0.9.0" description = "Utility library for gitignore style pattern matching of file paths." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "pep8" +version = "1.7.1" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = "*" [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "psutil" -version = "5.7.2" +version = "5.9.0" description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false @@ -356,23 +384,15 @@ test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] [[package]] name = "py" -version = "1.9.0" +version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pycodestyle" -version = "2.6.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pydantic" -version = "1.7.3" +version = "1.7.4" description = "Data validation and settings management using python 3.6 type hinting" category = "main" optional = false @@ -388,7 +408,7 @@ typing_extensions = ["typing-extensions (>=3.7.2)"] [[package]] name = "pyflakes" -version = "2.2.0" +version = "2.4.0" description = "passive checker of Python programs" category = "main" optional = false @@ -396,15 +416,18 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" -version = "2.4.7" +version = "3.0.7" description = "Python parsing module" category = "dev" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "6.2.1" +version = "7.0.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -417,35 +440,35 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0.0a1" +pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pytest-cov" -version = "2.10.1" +version = "3.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -coverage = ">=4.4" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-mock" -version = "3.4.0" +version = "3.6.1" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] pytest = ">=5.0" @@ -455,7 +478,7 @@ dev = ["pre-commit", "tox", "pytest-asyncio"] [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -477,41 +500,41 @@ six = ">=1.4.0" [[package]] name = "pyyaml" -version = "5.3.1" +version = "5.4.1" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "regex" -version = "2020.9.27" +version = "2022.3.15" description = "Alternative regular expression module, to replace re." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "requests" -version = "2.24.0" +version = "2.27.1" description = "Python HTTP for Humans." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.dependencies] certifi = ">=2017.4.17" -chardet = ">=3.0.2,<4" -idna = ">=2.5,<3" -urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" [package.extras] -security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] [[package]] name = "rfc3986" -version = "1.4.0" +version = "1.5.0" description = "Validating URI References per RFC 3986" category = "main" optional = false @@ -525,7 +548,7 @@ idna2008 = ["idna"] [[package]] name = "safety" -version = "1.10.0" +version = "1.10.3" description = "Checks installed dependencies for known vulnerabilities." category = "dev" optional = false @@ -539,7 +562,7 @@ requests = "*" [[package]] name = "shellingham" -version = "1.3.2" +version = "1.4.0" description = "Tool to Detect Surrounding Shell" category = "main" optional = false @@ -547,7 +570,7 @@ python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" [[package]] name = "six" -version = "1.15.0" +version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false @@ -555,7 +578,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "sniffio" -version = "1.1.0" +version = "1.2.0" description = "Sniff out which async library your code is running under" category = "main" optional = false @@ -574,32 +597,41 @@ python-versions = "*" [[package]] name = "taskipy" -version = "1.5.1" +version = "1.10.1" description = "tasks runner for python projects" category = "dev" optional = false python-versions = ">=3.6,<4.0" [package.dependencies] -mslex = ">=0.3.0,<0.4.0" +colorama = ">=0.4.4,<0.5.0" +mslex = {version = ">=0.3.0,<0.4.0", markers = "sys_platform == \"win32\""} psutil = ">=5.7.2,<6.0.0" -toml = ">=0.10.0,<0.11.0" +tomli = ">=1.2.3,<2.0.0" [[package]] name = "toml" -version = "0.10.1" +version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" category = "main" optional = false -python-versions = "*" +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "tomli" +version = "1.2.3" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" [[package]] name = "typed-ast" -version = "1.4.1" +version = "1.5.2" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "typer" @@ -620,41 +652,41 @@ doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown- [[package]] name = "typing-extensions" -version = "3.7.4.3" -description = "Backported and Experimental Type Hints for Python 3.5+" +version = "4.1.1" +description = "Backported and Experimental Type Hints for Python 3.6+" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.25.10" +version = "1.26.9" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "zipp" -version = "3.3.0" +version = "3.6.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.6" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "faf6d4bb989cd9c7a77088c0ba955b3f68755cf30281594dfef01ccf0f1b1dc5" +content-hash = "9ef9a5472b22d049a2d94a959d4e7b7c3cb120f1113fa47a38a78c555818002e" [metadata.files] appdirs = [ @@ -666,8 +698,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, - {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] autoflake = [ {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, @@ -676,12 +708,12 @@ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] certifi = [ - {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, - {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, ] -chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -695,371 +727,547 @@ contextvars = [ {file = "contextvars-2.4.tar.gz", hash = "sha256:f38c908aaa59c14335eeea12abea5f443646216c4e29380d7bf34d2018e2c39e"}, ] coverage = [ - {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, - {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, - {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"}, - {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"}, - {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"}, - {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"}, - {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"}, - {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"}, - {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"}, - {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"}, - {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"}, - {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"}, - {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"}, - {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"}, - {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"}, - {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"}, - {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"}, - {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"}, - {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"}, - {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"}, - {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"}, - {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"}, - {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"}, - {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"}, - {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"}, - {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"}, - {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"}, - {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"}, - {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"}, - {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"}, - {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"}, - {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"}, - {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, - {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, + {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, + {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, + {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, + {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, + {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, + {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, + {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, + {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, + {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, + {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, + {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, + {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, + {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, + {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, + {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, + {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, + {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, + {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, + {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, + {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, + {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, + {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, + {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, + {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, + {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, + {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, + {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, + {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, + {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, + {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, + {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, + {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, + {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, + {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, + {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, + {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, + {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, + {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, + {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, + {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, + {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, + {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, + {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, + {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, + {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, + {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, + {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, ] dataclasses = [ - {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, - {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, + {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, + {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, ] dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, ] flake8 = [ - {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, - {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, + {file = "flake8-2.3.0-py2.py3-none-any.whl", hash = "sha256:c99cc9716d6655d9c8bcb1e77632b8615bf0abd282d7abd9f5c2148cad7fc669"}, + {file = "flake8-2.3.0.tar.gz", hash = "sha256:5ee1a43ccd0716d6061521eec6937c983efa027793013e572712c4da55c7c83e"}, ] h11 = [ - {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, - {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, + {file = "h11-0.13.0-py3-none-any.whl", hash = "sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"}, + {file = "h11-0.13.0.tar.gz", hash = "sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06"}, ] httpcore = [ - {file = "httpcore-0.12.0-py3-none-any.whl", hash = "sha256:18c4afcbfe884b635e59739105aed1692e132bc5d31597109f3c1c97e4ec1cac"}, - {file = "httpcore-0.12.0.tar.gz", hash = "sha256:2526a38f31ac5967d38b7f593b5d8c4bd3fa82c21400402f866ba3312946acbf"}, + {file = "httpcore-0.12.3-py3-none-any.whl", hash = "sha256:93e822cd16c32016b414b789aeff4e855d0ccbfc51df563ee34d4dbadbb3bcdc"}, + {file = "httpcore-0.12.3.tar.gz", hash = "sha256:37ae835fb370049b2030c3290e12ed298bf1473c41bb72ca4aa78681eba9b7c9"}, ] httpx = [ {file = "httpx-0.16.1-py3-none-any.whl", hash = "sha256:9cffb8ba31fac6536f2c8cde30df859013f59e4bcc5b8d43901cb3654a8e0a5b"}, {file = "httpx-0.16.1.tar.gz", hash = "sha256:126424c279c842738805974687e0518a94c7ae8d140cd65b9c4f77ac46ffa537"}, ] idna = [ - {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, - {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] immutables = [ - {file = "immutables-0.14-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:860666fab142401a5535bf65cbd607b46bc5ed25b9d1eb053ca8ed9a1a1a80d6"}, - {file = "immutables-0.14-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ce01788878827c3f0331c254a4ad8d9721489a5e65cc43e19c80040b46e0d297"}, - {file = "immutables-0.14-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8797eed4042f4626b0bc04d9cf134208918eb0c937a8193a2c66df5041e62d2e"}, - {file = "immutables-0.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:33ce2f977da7b5e0dddd93744862404bdb316ffe5853ec853e53141508fa2e6a"}, - {file = "immutables-0.14-cp36-cp36m-win_amd64.whl", hash = "sha256:6c8eace4d98988c72bcb37c05e79aae756832738305ae9497670482a82db08bc"}, - {file = "immutables-0.14-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:ab6c18b7b2b2abc83e0edc57b0a38bf0915b271582a1eb8c7bed1c20398f8040"}, - {file = "immutables-0.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c099212fd6504513a50e7369fe281007c820cf9d7bb22a336486c63d77d6f0b2"}, - {file = "immutables-0.14-cp37-cp37m-win_amd64.whl", hash = "sha256:714aedbdeba4439d91cb5e5735cb10631fc47a7a69ea9cc8ecbac90322d50a4a"}, - {file = "immutables-0.14-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:1c11050c49e193a1ec9dda1747285333f6ba6a30bbeb2929000b9b1192097ec0"}, - {file = "immutables-0.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c453e12b95e1d6bb4909e8743f88b7f5c0c97b86a8bc0d73507091cb644e3c1e"}, - {file = "immutables-0.14-cp38-cp38-win_amd64.whl", hash = "sha256:ef9da20ec0f1c5853b5c8f8e3d9e1e15b8d98c259de4b7515d789a606af8745e"}, - {file = "immutables-0.14.tar.gz", hash = "sha256:a0a1cc238b678455145bae291d8426f732f5255537ed6a5b7645949704c70a78"}, + {file = "immutables-0.17-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cab10d65a29b2019fffd7a3924f6965a8f785e7bd409641ce36ab2d3335f88c4"}, + {file = "immutables-0.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f73088c9b8595ddfd45a5658f8cce0cb3ae6e5890458381fccba3ed3035081d4"}, + {file = "immutables-0.17-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef632832fa1acae6861d83572b866126f9e35706ab6e581ce6b175b3e0b7a3c4"}, + {file = "immutables-0.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0efdcec7b63859b41f794ffa0cd0d6dc87e77d1be4ff0ec23471a3a1e719235f"}, + {file = "immutables-0.17-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eca96f12bc1535657d24eae2c69816d0b22c4a4bc7f4753115e028a137e8dad"}, + {file = "immutables-0.17-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:01a25b1056754aa486afea5471ca348410d77f458477ccb6fa3baf2d3e3ff3d5"}, + {file = "immutables-0.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c41a6648f7355f1241da677c418edae56fdc45af19ad3540ca8a1e7a81606a7a"}, + {file = "immutables-0.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0b578bba11bd8ae55dee9536edf8d82be18463d15d4b4c9827e27eeeb73826bf"}, + {file = "immutables-0.17-cp310-cp310-win32.whl", hash = "sha256:a28682e115191e909673aedb9ccea3377da3a6a929f8bd86982a2a76bdfa89db"}, + {file = "immutables-0.17-cp310-cp310-win_amd64.whl", hash = "sha256:293ddb681502945f29b3065e688a962e191e752320040892316b9dd1e3b9c8c9"}, + {file = "immutables-0.17-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ec04fc7d9f76f26d82a5d9d1715df0409d0096309828fc46cd1a2067c7fbab95"}, + {file = "immutables-0.17-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f024f25e9fda42251a2b2167668ca70678c19fb3ab6ed509cef0b4b431d0ff73"}, + {file = "immutables-0.17-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b02083b2052cc201ac5cbd38f34a5da21fcd51016cb4ddd1fb43d7dc113eac17"}, + {file = "immutables-0.17-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea32db31afb82d8369e98f85c5b815ff81610a12fbc837830a34388f1b56f080"}, + {file = "immutables-0.17-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:898a9472d1dd3d17f291114395a1be65be035355fc65af0b2c88238f8fbeaa62"}, + {file = "immutables-0.17-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:736dd3d88d44da0ee48804792bd095c01a344c5d1b0f10beeb9ccb3a00b9c19d"}, + {file = "immutables-0.17-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:15ff4139720f79b902f435a25e3c00f9c8adcc41d79bed64b7e51ae36cfe9620"}, + {file = "immutables-0.17-cp36-cp36m-win32.whl", hash = "sha256:4f018a6c4c3689b82f763ad4f84dec6aa91c83981db7f6bafef963f036e5e815"}, + {file = "immutables-0.17-cp36-cp36m-win_amd64.whl", hash = "sha256:d7400a6753b292ac80102ed026efa8da2c3fedd50c443924cbe9b6448d3b19e4"}, + {file = "immutables-0.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f7a6e0380bddb99c46bb3f12ae5eee9a23d6a66d99bbf0fb10fa552f935c2e8d"}, + {file = "immutables-0.17-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7696c42d1f9a16ecda0ee46229848df8706973690b45e8a090d995d647a5ec57"}, + {file = "immutables-0.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:892b6a1619cd8c398fa70302c4cfa9768a694377639330e7a58cc7be111ab23e"}, + {file = "immutables-0.17-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89093d5a85357250b1d5ae218fdcfdbac4097cbb2d8b55004aa7a2ca2a00a09f"}, + {file = "immutables-0.17-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99a8bc6d0623300eb46beea74f7a5061968fb3efc4e072f23f6c0b21c588238d"}, + {file = "immutables-0.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:00380474f8e3b4a2eeb06ce694e0e3cb85a144919140a2b3116defb6c1587471"}, + {file = "immutables-0.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:078e3ed63be0ac36523b80bbabbfb1bb57e55009f4efb5650b0e3b3ed569c3f1"}, + {file = "immutables-0.17-cp37-cp37m-win32.whl", hash = "sha256:14905aecc62b318d86045dcf8d35ef2063803d9d331aeccd88958f03caadc7b0"}, + {file = "immutables-0.17-cp37-cp37m-win_amd64.whl", hash = "sha256:3774d403d1570105a1da2e00c38ce3f04065fd1deff04cf998f8d8e946d0ae13"}, + {file = "immutables-0.17-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e5a9caee1b99eccf1447056ae6bda77edd15c357421293e81fa1a4f28e83448a"}, + {file = "immutables-0.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fed1e1baf1de1bc94a0310da29814892064928d7d40ff5a3b86bcd11d5e7cfff"}, + {file = "immutables-0.17-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d7daa340d76747ba5a8f64816b48def74bd4be45a9508073b34fa954d099fba"}, + {file = "immutables-0.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4644c29fe07fb92ba84b26659708e1799fecaaf781214adf13edd8a4d7495a9"}, + {file = "immutables-0.17-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e9ea0e2a31db44fb01617ff875d4c26f962696e1c5ff11ed7767c2d8dedac4"}, + {file = "immutables-0.17-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:64100dfdb29fae2bc84748fff5d66dd6b3997806c717eeb75f7099aeee9b1878"}, + {file = "immutables-0.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5f933e5bf6f2c1afb24bc2fc8bea8b132096a4a6ba54f36be59787981f3e50ff"}, + {file = "immutables-0.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9508a087a47f9f9506adf2fa8383ab14c46a222b57eea8612bc4c2aa9a9550fe"}, + {file = "immutables-0.17-cp38-cp38-win32.whl", hash = "sha256:dfd2c63f15d1e5ea1ed2a05b7c602b5f61a64337415d299df20e103a57ae4906"}, + {file = "immutables-0.17-cp38-cp38-win_amd64.whl", hash = "sha256:301c539660c988c5b24051ccad1e36c040a916f1e58fa3e245e3122fc50dd28d"}, + {file = "immutables-0.17-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:563bc2ddbe75c10faa3b4b0206870653b44a231b97ed23cff8ab8aff503d922d"}, + {file = "immutables-0.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f621ea6130393cd14d0fbd35b306d4dc70bcd0fda550a8cd313db8015e34ca60"}, + {file = "immutables-0.17-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57c2d1b16b716bca70345db334dd6a861bf45c46cb11bb1801277f8a9012e864"}, + {file = "immutables-0.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a08e1a80bd8c5df72c2bf0af24a37ceec17e8ffdb850ed5a62d0bba1d4d86018"}, + {file = "immutables-0.17-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b99155ad112149d43208c611c6c42f19e16716526dacc0fcc16736d2f5d2e20"}, + {file = "immutables-0.17-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ed71e736f8fb82545d00c8969dbc167547c15e85729058edbed3c03b94fca86c"}, + {file = "immutables-0.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:19e4b8e5810dd7cab63fa700373f787a369d992166eabc23f4b962e5704d33c5"}, + {file = "immutables-0.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:305062012497d4c4a70fe35e20cef2c6f65744e721b04671092a63354799988d"}, + {file = "immutables-0.17-cp39-cp39-win32.whl", hash = "sha256:f5c6bd012384a8d6af7bb25675719214d76640fe6c336e2b5fba9eef1407ae6a"}, + {file = "immutables-0.17-cp39-cp39-win_amd64.whl", hash = "sha256:615ab26873a794559ccaf4e0e9afdb5aefad0867c15262ba64a55a12a5a41573"}, + {file = "immutables-0.17.tar.gz", hash = "sha256:ad894446355b6f5289a9c84fb46f7c47c6ef2b1bfbdd2be6cb177dbb7f1587ad"}, ] importlib-metadata = [ - {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"}, - {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"}, + {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, + {file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"}, ] iniconfig = [ - {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, - {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] isort = [ - {file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"}, - {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, + {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"}, + {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"}, ] jinja2 = [ - {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, - {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, + {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, + {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, ] markupsafe = [ - {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, - {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {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"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {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"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {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"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {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"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {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"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, + {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, ] mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mslex = [ {file = "mslex-0.3.0-py2.py3-none-any.whl", hash = "sha256:380cb14abf8fabf40e56df5c8b21a6d533dc5cbdcfe42406bbf08dda8f42e42a"}, {file = "mslex-0.3.0.tar.gz", hash = "sha256:4a1ac3f25025cad78ad2fe499dd16d42759f7a3801645399cce5c404415daa97"}, ] mypy = [ - {file = "mypy-0.790-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:bd03b3cf666bff8d710d633d1c56ab7facbdc204d567715cb3b9f85c6e94f669"}, - {file = "mypy-0.790-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:2170492030f6faa537647d29945786d297e4862765f0b4ac5930ff62e300d802"}, - {file = "mypy-0.790-cp35-cp35m-win_amd64.whl", hash = "sha256:e86bdace26c5fe9cf8cb735e7cedfe7850ad92b327ac5d797c656717d2ca66de"}, - {file = "mypy-0.790-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e97e9c13d67fbe524be17e4d8025d51a7dca38f90de2e462243ab8ed8a9178d1"}, - {file = "mypy-0.790-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0d34d6b122597d48a36d6c59e35341f410d4abfa771d96d04ae2c468dd201abc"}, - {file = "mypy-0.790-cp36-cp36m-win_amd64.whl", hash = "sha256:72060bf64f290fb629bd4a67c707a66fd88ca26e413a91384b18db3876e57ed7"}, - {file = "mypy-0.790-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eea260feb1830a627fb526d22fbb426b750d9f5a47b624e8d5e7e004359b219c"}, - {file = "mypy-0.790-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c614194e01c85bb2e551c421397e49afb2872c88b5830e3554f0519f9fb1c178"}, - {file = "mypy-0.790-cp37-cp37m-win_amd64.whl", hash = "sha256:0a0d102247c16ce93c97066443d11e2d36e6cc2a32d8ccc1f705268970479324"}, - {file = "mypy-0.790-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4e7bf7f1214826cf7333627cb2547c0db7e3078723227820d0a2490f117a01"}, - {file = "mypy-0.790-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:af4e9ff1834e565f1baa74ccf7ae2564ae38c8df2a85b057af1dbbc958eb6666"}, - {file = "mypy-0.790-cp38-cp38-win_amd64.whl", hash = "sha256:da56dedcd7cd502ccd3c5dddc656cb36113dd793ad466e894574125945653cea"}, - {file = "mypy-0.790-py3-none-any.whl", hash = "sha256:2842d4fbd1b12ab422346376aad03ff5d0805b706102e475e962370f874a5122"}, - {file = "mypy-0.790.tar.gz", hash = "sha256:2b21ba45ad9ef2e2eb88ce4aeadd0112d0f5026418324176fd494a6824b74975"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, + {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, + {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, + {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, + {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, + {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, + {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, + {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, + {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, + {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, + {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, + {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, + {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, + {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, + {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, + {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, + {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, + {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] packaging = [ - {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, - {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pathspec = [ - {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, - {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +pep8 = [ + {file = "pep8-1.7.1-py2.py3-none-any.whl", hash = "sha256:b22cfae5db09833bb9bd7c8463b53e1a9c9b39f12e304a8d0bba729c501827ee"}, + {file = "pep8-1.7.1.tar.gz", hash = "sha256:fe249b52e20498e59e0b5c5256aa52ee99fc295b26ec9eaa85776ffdb9fe6374"}, ] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] psutil = [ - {file = "psutil-5.7.2-cp27-none-win32.whl", hash = "sha256:f2018461733b23f308c298653c8903d32aaad7873d25e1d228765e91ae42c3f2"}, - {file = "psutil-5.7.2-cp27-none-win_amd64.whl", hash = "sha256:66c18ca7680a31bf16ee22b1d21b6397869dda8059dbdb57d9f27efa6615f195"}, - {file = "psutil-5.7.2-cp35-cp35m-win32.whl", hash = "sha256:5e9d0f26d4194479a13d5f4b3798260c20cecf9ac9a461e718eb59ea520a360c"}, - {file = "psutil-5.7.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4080869ed93cce662905b029a1770fe89c98787e543fa7347f075ade761b19d6"}, - {file = "psutil-5.7.2-cp36-cp36m-win32.whl", hash = "sha256:d8a82162f23c53b8525cf5f14a355f5d1eea86fa8edde27287dd3a98399e4fdf"}, - {file = "psutil-5.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0ee3c36428f160d2d8fce3c583a0353e848abb7de9732c50cf3356dd49ad63f8"}, - {file = "psutil-5.7.2-cp37-cp37m-win32.whl", hash = "sha256:ff1977ba1a5f71f89166d5145c3da1cea89a0fdb044075a12c720ee9123ec818"}, - {file = "psutil-5.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a5b120bb3c0c71dfe27551f9da2f3209a8257a178ed6c628a819037a8df487f1"}, - {file = "psutil-5.7.2-cp38-cp38-win32.whl", hash = "sha256:10512b46c95b02842c225f58fa00385c08fa00c68bac7da2d9a58ebe2c517498"}, - {file = "psutil-5.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:68d36986ded5dac7c2dcd42f2682af1db80d4bce3faa126a6145c1637e1b559f"}, - {file = "psutil-5.7.2.tar.gz", hash = "sha256:90990af1c3c67195c44c9a889184f84f5b2320dce3ee3acbd054e3ba0b4a7beb"}, + {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b"}, + {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618"}, + {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2"}, + {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd"}, + {file = "psutil-5.9.0-cp27-none-win32.whl", hash = "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3"}, + {file = "psutil-5.9.0-cp27-none-win_amd64.whl", hash = "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c"}, + {file = "psutil-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492"}, + {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3"}, + {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2"}, + {file = "psutil-5.9.0-cp310-cp310-win32.whl", hash = "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d"}, + {file = "psutil-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b"}, + {file = "psutil-5.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56"}, + {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203"}, + {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d"}, + {file = "psutil-5.9.0-cp36-cp36m-win32.whl", hash = "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64"}, + {file = "psutil-5.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94"}, + {file = "psutil-5.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0"}, + {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce"}, + {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5"}, + {file = "psutil-5.9.0-cp37-cp37m-win32.whl", hash = "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9"}, + {file = "psutil-5.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4"}, + {file = "psutil-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2"}, + {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d"}, + {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a"}, + {file = "psutil-5.9.0-cp38-cp38-win32.whl", hash = "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666"}, + {file = "psutil-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841"}, + {file = "psutil-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf"}, + {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07"}, + {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d"}, + {file = "psutil-5.9.0-cp39-cp39-win32.whl", hash = "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845"}, + {file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"}, + {file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"}, ] py = [ - {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, - {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, -] -pycodestyle = [ - {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, - {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pydantic = [ - {file = "pydantic-1.7.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c59ea046aea25be14dc22d69c97bee629e6d48d2b2ecb724d7fe8806bf5f61cd"}, - {file = "pydantic-1.7.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a4143c8d0c456a093387b96e0f5ee941a950992904d88bc816b4f0e72c9a0009"}, - {file = "pydantic-1.7.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:d8df4b9090b595511906fa48deda47af04e7d092318bfb291f4d45dfb6bb2127"}, - {file = "pydantic-1.7.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:514b473d264671a5c672dfb28bdfe1bf1afd390f6b206aa2ec9fed7fc592c48e"}, - {file = "pydantic-1.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:dba5c1f0a3aeea5083e75db9660935da90216f8a81b6d68e67f54e135ed5eb23"}, - {file = "pydantic-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59e45f3b694b05a69032a0d603c32d453a23f0de80844fb14d55ab0c6c78ff2f"}, - {file = "pydantic-1.7.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:5b24e8a572e4b4c18f614004dda8c9f2c07328cb5b6e314d6e1bbd536cb1a6c1"}, - {file = "pydantic-1.7.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:b2b054d095b6431cdda2f852a6d2f0fdec77686b305c57961b4c5dd6d863bf3c"}, - {file = "pydantic-1.7.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:025bf13ce27990acc059d0c5be46f416fc9b293f45363b3d19855165fee1874f"}, - {file = "pydantic-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6e3874aa7e8babd37b40c4504e3a94cc2023696ced5a0500949f3347664ff8e2"}, - {file = "pydantic-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e682f6442ebe4e50cb5e1cfde7dda6766fb586631c3e5569f6aa1951fd1a76ef"}, - {file = "pydantic-1.7.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:185e18134bec5ef43351149fe34fda4758e53d05bb8ea4d5928f0720997b79ef"}, - {file = "pydantic-1.7.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:f5b06f5099e163295b8ff5b1b71132ecf5866cc6e7f586d78d7d3fd6e8084608"}, - {file = "pydantic-1.7.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:24ca47365be2a5a3cc3f4a26dcc755bcdc9f0036f55dcedbd55663662ba145ec"}, - {file = "pydantic-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:d1fe3f0df8ac0f3a9792666c69a7cd70530f329036426d06b4f899c025aca74e"}, - {file = "pydantic-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f6864844b039805add62ebe8a8c676286340ba0c6d043ae5dea24114b82a319e"}, - {file = "pydantic-1.7.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ecb54491f98544c12c66ff3d15e701612fc388161fd455242447083350904730"}, - {file = "pydantic-1.7.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:ffd180ebd5dd2a9ac0da4e8b995c9c99e7c74c31f985ba090ee01d681b1c4b95"}, - {file = "pydantic-1.7.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8d72e814c7821125b16f1553124d12faba88e85405b0864328899aceaad7282b"}, - {file = "pydantic-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:475f2fa134cf272d6631072554f845d0630907fce053926ff634cc6bc45bf1af"}, - {file = "pydantic-1.7.3-py3-none-any.whl", hash = "sha256:38be427ea01a78206bcaf9a56f835784afcba9e5b88fbdce33bbbfbcd7841229"}, - {file = "pydantic-1.7.3.tar.gz", hash = "sha256:213125b7e9e64713d16d988d10997dabc6a1f73f3991e1ff8e35ebb1409c7dc9"}, + {file = "pydantic-1.7.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3c60039e84552442defbcb5d56711ef0e057028ca7bfc559374917408a88d84e"}, + {file = "pydantic-1.7.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6e7e314acb170e143c6f3912f93f2ec80a96aa2009ee681356b7ce20d57e5c62"}, + {file = "pydantic-1.7.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:8ef77cd17b73b5ba46788d040c0e820e49a2d80cfcd66fda3ba8be31094fd146"}, + {file = "pydantic-1.7.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:115d8aa6f257a1d469c66b6bfc7aaf04cd87c25095f24542065c68ebcb42fe63"}, + {file = "pydantic-1.7.4-cp36-cp36m-win_amd64.whl", hash = "sha256:66757d4e1eab69a3cfd3114480cc1d72b6dd847c4d30e676ae838c6740fdd146"}, + {file = "pydantic-1.7.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c92863263e4bd89e4f9cf1ab70d918170c51bd96305fe7b00853d80660acb26"}, + {file = "pydantic-1.7.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3b8154babf30a5e0fa3aa91f188356763749d9b30f7f211fafb247d4256d7877"}, + {file = "pydantic-1.7.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:80cc46378505f7ff202879dcffe4bfbf776c15675028f6e08d1d10bdfbb168ac"}, + {file = "pydantic-1.7.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:dda60d7878a5af2d8560c55c7c47a8908344aa78d32ec1c02d742ede09c534df"}, + {file = "pydantic-1.7.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4c1979d5cc3e14b35f0825caddea5a243dd6085e2a7539c006bc46997ef7a61a"}, + {file = "pydantic-1.7.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8857576600c32aa488f18d30833aa833b54a48e3bab3adb6de97e463af71f8f8"}, + {file = "pydantic-1.7.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1f86d4da363badb39426a0ff494bf1d8510cd2f7274f460eee37bdbf2fd495ec"}, + {file = "pydantic-1.7.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:3ea1256a9e782149381e8200119f3e2edea7cd6b123f1c79ab4bbefe4d9ba2c9"}, + {file = "pydantic-1.7.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:e28455b42a0465a7bf2cde5eab530389226ce7dc779de28d17b8377245982b1e"}, + {file = "pydantic-1.7.4-cp38-cp38-win_amd64.whl", hash = "sha256:47c5b1d44934375a3311891cabd450c150a31cf5c22e84aa172967bf186718be"}, + {file = "pydantic-1.7.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:00250e5123dd0b123ff72be0e1b69140e0b0b9e404d15be3846b77c6f1b1e387"}, + {file = "pydantic-1.7.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d24aa3f7f791a023888976b600f2f389d3713e4f23b7a4c88217d3fce61cdffc"}, + {file = "pydantic-1.7.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2c44a9afd4c4c850885436a4209376857989aaf0853c7b118bb2e628d4b78c4e"}, + {file = "pydantic-1.7.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:e87edd753da0ca1d44e308a1b1034859ffeab1f4a4492276bff9e1c3230db4fe"}, + {file = "pydantic-1.7.4-cp39-cp39-win_amd64.whl", hash = "sha256:a3026ee105b5360855e500b4abf1a1d0b034d88e75a2d0d66a4c35e60858e15b"}, + {file = "pydantic-1.7.4-py3-none-any.whl", hash = "sha256:a82385c6d5a77e3387e94612e3e34b77e13c39ff1295c26e3ba664e7b98073e2"}, + {file = "pydantic-1.7.4.tar.gz", hash = "sha256:0a1abcbd525fbb52da58c813d54c2ec706c31a91afdb75411a73dd1dec036595"}, ] pyflakes = [ - {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, - {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, + {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, + {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] pyparsing = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, + {file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"}, + {file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"}, ] pytest-cov = [ - {file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"}, - {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, ] pytest-mock = [ - {file = "pytest-mock-3.4.0.tar.gz", hash = "sha256:c3981f5edee6c4d1942250a60d9b39d38d5585398de1bfce057f925bdda720f4"}, - {file = "pytest_mock-3.4.0-py3-none-any.whl", hash = "sha256:c0fc979afac4aaba545cbd01e9c20736eb3fefb0a066558764b07d3de8f04ed3"}, + {file = "pytest-mock-3.6.1.tar.gz", hash = "sha256:40217a058c52a63f1042f0784f62009e976ba824c418cced42e88d5f40ab0e62"}, + {file = "pytest_mock-3.6.1-py3-none-any.whl", hash = "sha256:30c2f2cc9759e76eee674b81ea28c9f0b94f8f0445a1b87762cadf774f0df7e3"}, ] python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] python-multipart = [ {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, ] pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, - {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] regex = [ - {file = "regex-2020.9.27-cp27-cp27m-win32.whl", hash = "sha256:d23a18037313714fb3bb5a94434d3151ee4300bae631894b1ac08111abeaa4a3"}, - {file = "regex-2020.9.27-cp27-cp27m-win_amd64.whl", hash = "sha256:84e9407db1b2eb368b7ecc283121b5e592c9aaedbe8c78b1a2f1102eb2e21d19"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f18875ac23d9aa2f060838e8b79093e8bb2313dbaaa9f54c6d8e52a5df097be"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ae91972f8ac958039920ef6e8769277c084971a142ce2b660691793ae44aae6b"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9a02d0ae31d35e1ec12a4ea4d4cca990800f66a917d0fb997b20fbc13f5321fc"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ebbe29186a3d9b0c591e71b7393f1ae08c83cb2d8e517d2a822b8f7ec99dfd8b"}, - {file = "regex-2020.9.27-cp36-cp36m-win32.whl", hash = "sha256:4707f3695b34335afdfb09be3802c87fa0bc27030471dbc082f815f23688bc63"}, - {file = "regex-2020.9.27-cp36-cp36m-win_amd64.whl", hash = "sha256:9bc13e0d20b97ffb07821aa3e113f9998e84994fe4d159ffa3d3a9d1b805043b"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f1b3afc574a3db3b25c89161059d857bd4909a1269b0b3cb3c904677c8c4a3f7"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5533a959a1748a5c042a6da71fe9267a908e21eded7a4f373efd23a2cbdb0ecc"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:1fe0a41437bbd06063aa184c34804efa886bcc128222e9916310c92cd54c3b4c"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c570f6fa14b9c4c8a4924aaad354652366577b4f98213cf76305067144f7b100"}, - {file = "regex-2020.9.27-cp37-cp37m-win32.whl", hash = "sha256:eda4771e0ace7f67f58bc5b560e27fb20f32a148cbc993b0c3835970935c2707"}, - {file = "regex-2020.9.27-cp37-cp37m-win_amd64.whl", hash = "sha256:60b0e9e6dc45683e569ec37c55ac20c582973841927a85f2d8a7d20ee80216ab"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux1_i686.whl", hash = "sha256:088afc8c63e7bd187a3c70a94b9e50ab3f17e1d3f52a32750b5b77dbe99ef5ef"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eaf548d117b6737df379fdd53bdde4f08870e66d7ea653e230477f071f861121"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:41bb65f54bba392643557e617316d0d899ed5b4946dccee1cb6696152b29844b"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:8d69cef61fa50c8133382e61fd97439de1ae623fe943578e477e76a9d9471637"}, - {file = "regex-2020.9.27-cp38-cp38-win32.whl", hash = "sha256:f2388013e68e750eaa16ccbea62d4130180c26abb1d8e5d584b9baf69672b30f"}, - {file = "regex-2020.9.27-cp38-cp38-win_amd64.whl", hash = "sha256:4318d56bccfe7d43e5addb272406ade7a2274da4b70eb15922a071c58ab0108c"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux1_i686.whl", hash = "sha256:84cada8effefe9a9f53f9b0d2ba9b7b6f5edf8d2155f9fdbe34616e06ececf81"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:816064fc915796ea1f26966163f6845de5af78923dfcecf6551e095f00983650"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:5d892a4f1c999834eaa3c32bc9e8b976c5825116cde553928c4c8e7e48ebda67"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c9443124c67b1515e4fe0bb0aa18df640965e1030f468a2a5dc2589b26d130ad"}, - {file = "regex-2020.9.27-cp39-cp39-win32.whl", hash = "sha256:49f23ebd5ac073765ecbcf046edc10d63dcab2f4ae2bce160982cb30df0c0302"}, - {file = "regex-2020.9.27-cp39-cp39-win_amd64.whl", hash = "sha256:3d20024a70b97b4f9546696cbf2fd30bae5f42229fbddf8661261b1eaff0deb7"}, - {file = "regex-2020.9.27.tar.gz", hash = "sha256:a6f32aea4260dfe0e55dc9733ea162ea38f0ea86aa7d0f77b15beac5bf7b369d"}, + {file = "regex-2022.3.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:42eb13b93765c6698a5ab3bcd318d8c39bb42e5fa8a7fcf7d8d98923f3babdb1"}, + {file = "regex-2022.3.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9beb03ff6fe509d6455971c2489dceb31687b38781206bcec8e68bdfcf5f1db2"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0a5a1fdc9f148a8827d55b05425801acebeeefc9e86065c7ac8b8cc740a91ff"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb374a2a4dba7c4be0b19dc7b1adc50e6c2c26c3369ac629f50f3c198f3743a4"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c33ce0c665dd325200209340a88438ba7a470bd5f09f7424e520e1a3ff835b52"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04c09b9651fa814eeeb38e029dc1ae83149203e4eeb94e52bb868fadf64852bc"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab5d89cfaf71807da93c131bb7a19c3e19eaefd613d14f3bce4e97de830b15df"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e2630ae470d6a9f8e4967388c1eda4762706f5750ecf387785e0df63a4cc5af"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:df037c01d68d1958dad3463e2881d3638a0d6693483f58ad41001aa53a83fcea"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:940570c1a305bac10e8b2bc934b85a7709c649317dd16520471e85660275083a"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7f63877c87552992894ea1444378b9c3a1d80819880ae226bb30b04789c0828c"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3e265b388cc80c7c9c01bb4f26c9e536c40b2c05b7231fbb347381a2e1c8bf43"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:058054c7a54428d5c3e3739ac1e363dc9347d15e64833817797dc4f01fb94bb8"}, + {file = "regex-2022.3.15-cp310-cp310-win32.whl", hash = "sha256:76435a92e444e5b8f346aed76801db1c1e5176c4c7e17daba074fbb46cb8d783"}, + {file = "regex-2022.3.15-cp310-cp310-win_amd64.whl", hash = "sha256:174d964bc683b1e8b0970e1325f75e6242786a92a22cedb2a6ec3e4ae25358bd"}, + {file = "regex-2022.3.15-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6e1d8ed9e61f37881c8db383a124829a6e8114a69bd3377a25aecaeb9b3538f8"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b52771f05cff7517f7067fef19ffe545b1f05959e440d42247a17cd9bddae11b"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673f5a393d603c34477dbad70db30025ccd23996a2d0916e942aac91cc42b31a"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8923e1c5231549fee78ff9b2914fad25f2e3517572bb34bfaa3aea682a758683"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764e66a0e382829f6ad3bbce0987153080a511c19eb3d2f8ead3f766d14433ac"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd00859291658fe1fda48a99559fb34da891c50385b0bfb35b808f98956ef1e7"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa2ce79f3889720b46e0aaba338148a1069aea55fda2c29e0626b4db20d9fcb7"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:34bb30c095342797608727baf5c8aa122406aa5edfa12107b8e08eb432d4c5d7"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:25ecb1dffc5e409ca42f01a2b2437f93024ff1612c1e7983bad9ee191a5e8828"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:aa5eedfc2461c16a092a2fabc5895f159915f25731740c9152a1b00f4bcf629a"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:7d1a6e403ac8f1d91d8f51c441c3f99367488ed822bda2b40836690d5d0059f5"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:3e4d710ff6539026e49f15a3797c6b1053573c2b65210373ef0eec24480b900b"}, + {file = "regex-2022.3.15-cp36-cp36m-win32.whl", hash = "sha256:0100f0ded953b6b17f18207907159ba9be3159649ad2d9b15535a74de70359d3"}, + {file = "regex-2022.3.15-cp36-cp36m-win_amd64.whl", hash = "sha256:f320c070dea3f20c11213e56dbbd7294c05743417cde01392148964b7bc2d31a"}, + {file = "regex-2022.3.15-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fc8c7958d14e8270171b3d72792b609c057ec0fa17d507729835b5cff6b7f69a"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ca6dcd17f537e9f3793cdde20ac6076af51b2bd8ad5fe69fa54373b17b48d3c"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0214ff6dff1b5a4b4740cfe6e47f2c4c92ba2938fca7abbea1359036305c132f"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a98ae493e4e80b3ded6503ff087a8492db058e9c68de371ac3df78e88360b374"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b1cc70e31aacc152a12b39245974c8fccf313187eead559ee5966d50e1b5817"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4829db3737480a9d5bfb1c0320c4ee13736f555f53a056aacc874f140e98f64"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:303b15a3d32bf5fe5a73288c316bac5807587f193ceee4eb6d96ee38663789fa"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:dc7b7c16a519d924c50876fb152af661a20749dcbf653c8759e715c1a7a95b18"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ce3057777a14a9a1399b81eca6a6bfc9612047811234398b84c54aeff6d536ea"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:48081b6bff550fe10bcc20c01cf6c83dbca2ccf74eeacbfac240264775fd7ecf"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dcbb7665a9db9f8d7642171152c45da60e16c4f706191d66a1dc47ec9f820aed"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c155a1a80c5e7a8fa1d9bb1bf3c8a953532b53ab1196092749bafb9d3a7cbb60"}, + {file = "regex-2022.3.15-cp37-cp37m-win32.whl", hash = "sha256:04b5ee2b6d29b4a99d38a6469aa1db65bb79d283186e8460542c517da195a8f6"}, + {file = "regex-2022.3.15-cp37-cp37m-win_amd64.whl", hash = "sha256:797437e6024dc1589163675ae82f303103063a0a580c6fd8d0b9a0a6708da29e"}, + {file = "regex-2022.3.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8afcd1c2297bc989dceaa0379ba15a6df16da69493635e53431d2d0c30356086"}, + {file = "regex-2022.3.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0066a6631c92774391f2ea0f90268f0d82fffe39cb946f0f9c6b382a1c61a5e5"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8248f19a878c72d8c0a785a2cd45d69432e443c9f10ab924c29adda77b324ae"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d1f3ea0d1924feb4cf6afb2699259f658a08ac6f8f3a4a806661c2dfcd66db1"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:794a6bc66c43db8ed06698fc32aaeaac5c4812d9f825e9589e56f311da7becd9"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d1445824944e642ffa54c4f512da17a953699c563a356d8b8cbdad26d3b7598"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f553a1190ae6cd26e553a79f6b6cfba7b8f304da2071052fa33469da075ea625"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:75a5e6ce18982f0713c4bac0704bf3f65eed9b277edd3fb9d2b0ff1815943327"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f16cf7e4e1bf88fecf7f41da4061f181a6170e179d956420f84e700fb8a3fd6b"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dad3991f0678facca1a0831ec1ddece2eb4d1dd0f5150acb9440f73a3b863907"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:491fc754428514750ab21c2d294486223ce7385446f2c2f5df87ddbed32979ae"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6504c22c173bb74075d7479852356bb7ca80e28c8e548d4d630a104f231e04fb"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01c913cf573d1da0b34c9001a94977273b5ee2fe4cb222a5d5b320f3a9d1a835"}, + {file = "regex-2022.3.15-cp38-cp38-win32.whl", hash = "sha256:029e9e7e0d4d7c3446aa92474cbb07dafb0b2ef1d5ca8365f059998c010600e6"}, + {file = "regex-2022.3.15-cp38-cp38-win_amd64.whl", hash = "sha256:947a8525c0a95ba8dc873191f9017d1b1e3024d4dc757f694e0af3026e34044a"}, + {file = "regex-2022.3.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:591d4fba554f24bfa0421ba040cd199210a24301f923ed4b628e1e15a1001ff4"}, + {file = "regex-2022.3.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9809404528a999cf02a400ee5677c81959bc5cb938fdc696b62eb40214e3632"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f08a7e4d62ea2a45557f561eea87c907222575ca2134180b6974f8ac81e24f06"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a86cac984da35377ca9ac5e2e0589bd11b3aebb61801204bd99c41fac516f0d"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:286908cbe86b1a0240a867aecfe26a439b16a1f585d2de133540549831f8e774"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b7494df3fdcc95a1f76cf134d00b54962dd83189520fd35b8fcd474c0aa616d"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b1ceede92400b3acfebc1425937454aaf2c62cd5261a3fabd560c61e74f6da3"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0317eb6331146c524751354ebef76a7a531853d7207a4d760dfb5f553137a2a4"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c144405220c5ad3f5deab4c77f3e80d52e83804a6b48b6bed3d81a9a0238e4c"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5b2e24f3ae03af3d8e8e6d824c891fea0ca9035c5d06ac194a2700373861a15c"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f2c53f3af011393ab5ed9ab640fa0876757498aac188f782a0c620e33faa2a3d"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:060f9066d2177905203516c62c8ea0066c16c7342971d54204d4e51b13dfbe2e"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:530a3a16e57bd3ea0dff5ec2695c09632c9d6c549f5869d6cf639f5f7153fb9c"}, + {file = "regex-2022.3.15-cp39-cp39-win32.whl", hash = "sha256:78ce90c50d0ec970bd0002462430e00d1ecfd1255218d52d08b3a143fe4bde18"}, + {file = "regex-2022.3.15-cp39-cp39-win_amd64.whl", hash = "sha256:c5adc854764732dbd95a713f2e6c3e914e17f2ccdc331b9ecb777484c31f73b6"}, + {file = "regex-2022.3.15.tar.gz", hash = "sha256:0a7b75cc7bb4cc0334380053e4671c560e31272c9d2d5a6c4b8e9ae2c9bd0f82"}, ] requests = [ - {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, - {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] rfc3986 = [ - {file = "rfc3986-1.4.0-py2.py3-none-any.whl", hash = "sha256:af9147e9aceda37c91a05f4deb128d4b4b49d6b199775fd2d2927768abdc8f50"}, - {file = "rfc3986-1.4.0.tar.gz", hash = "sha256:112398da31a3344dc25dbf477d8df6cb34f9278a94fee2625d89e4514be8bb9d"}, + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, ] safety = [ - {file = "safety-1.10.0-py2.py3-none-any.whl", hash = "sha256:69437acf5dd617abd7086ccd0d50e813e67aa969bb9ca90f1847d5fbea047dcc"}, - {file = "safety-1.10.0.tar.gz", hash = "sha256:2ebc71b44666588d7898905d86d575933fcd5fa3c92d301ed12482602b1e928a"}, + {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, + {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] shellingham = [ - {file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"}, - {file = "shellingham-1.3.2.tar.gz", hash = "sha256:576c1982bea0ba82fb46c36feb951319d7f42214a82634233f58b40d858a751e"}, + {file = "shellingham-1.4.0-py2.py3-none-any.whl", hash = "sha256:536b67a0697f2e4af32ab176c00a50ac2899c5a05e0d8e2dadac8e58888283f9"}, + {file = "shellingham-1.4.0.tar.gz", hash = "sha256:4855c2458d6904829bd34c299f11fdeed7cfefbf8a2c522e4caea6cd76b3171e"}, ] six = [ - {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, - {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] sniffio = [ - {file = "sniffio-1.1.0-py3-none-any.whl", hash = "sha256:20ed6d5b46f8ae136d00b9dcb807615d83ed82ceea6b2058cecb696765246da5"}, - {file = "sniffio-1.1.0.tar.gz", hash = "sha256:8e3810100f69fe0edd463d02ad407112542a11ffdc29f67db2bf3771afb87a21"}, + {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, + {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, ] stringcase = [ {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, ] taskipy = [ - {file = "taskipy-1.5.1-py3-none-any.whl", hash = "sha256:2cf0080a8a5b6eb182c26ce323412c8bd63ea5b3477bfb4d0407bb77924abd04"}, - {file = "taskipy-1.5.1.tar.gz", hash = "sha256:aa803322e6286e4ade8156366e0f846f79959447f4a9bcd7eac59c7705bd3f0d"}, + {file = "taskipy-1.10.1-py3-none-any.whl", hash = "sha256:9b38333654da487b6d16de6fa330b7629d1935d1e74819ba4c5f17a1c372d37b"}, + {file = "taskipy-1.10.1.tar.gz", hash = "sha256:6fa0b11c43d103e376063e90be31d87b435aad50fb7dc1c9a2de9b60a85015ed"}, ] toml = [ - {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, - {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +tomli = [ + {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"}, + {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, ] typed-ast = [ - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, - {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, - {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, - {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, - {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, - {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, - {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, - {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, - {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, + {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, + {file = "typed_ast-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:676d051b1da67a852c0447621fdd11c4e104827417bf216092ec3e286f7da596"}, + {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc2542e83ac8399752bc16e0b35e038bdb659ba237f4222616b4e83fb9654985"}, + {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74cac86cc586db8dfda0ce65d8bcd2bf17b58668dfcc3652762f3ef0e6677e76"}, + {file = "typed_ast-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:18fe320f354d6f9ad3147859b6e16649a0781425268c4dde596093177660e71a"}, + {file = "typed_ast-1.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:31d8c6b2df19a777bc8826770b872a45a1f30cfefcfd729491baa5237faae837"}, + {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:963a0ccc9a4188524e6e6d39b12c9ca24cc2d45a71cfdd04a26d883c922b4b78"}, + {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e"}, + {file = "typed_ast-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:294a6903a4d087db805a7656989f613371915fc45c8cc0ddc5c5a0a8ad9bea4d"}, + {file = "typed_ast-1.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26a432dc219c6b6f38be20a958cbe1abffcc5492821d7e27f08606ef99e0dffd"}, + {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7407cfcad702f0b6c0e0f3e7ab876cd1d2c13b14ce770e412c0c4b9728a0f88"}, + {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f30ddd110634c2d7534b2d4e0e22967e88366b0d356b24de87419cc4410c41b7"}, + {file = "typed_ast-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8c08d6625bb258179b6e512f55ad20f9dfef019bbfbe3095247401e053a3ea30"}, + {file = "typed_ast-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:90904d889ab8e81a956f2c0935a523cc4e077c7847a836abee832f868d5c26a4"}, + {file = "typed_ast-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbebc31bf11762b63bf61aaae232becb41c5bf6b3461b80a4df7e791fabb3aca"}, + {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29dd9a3a9d259c9fa19d19738d021632d673f6ed9b35a739f48e5f807f264fb"}, + {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:58ae097a325e9bb7a684572d20eb3e1809802c5c9ec7108e85da1eb6c1a3331b"}, + {file = "typed_ast-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:da0a98d458010bf4fe535f2d1e367a2e2060e105978873c04c04212fb20543f7"}, + {file = "typed_ast-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33b4a19ddc9fc551ebabca9765d54d04600c4a50eda13893dadf67ed81d9a098"}, + {file = "typed_ast-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1098df9a0592dd4c8c0ccfc2e98931278a6c6c53cb3a3e2cf7e9ee3b06153344"}, + {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c47c3b43fe3a39ddf8de1d40dbbfca60ac8530a36c9b198ea5b9efac75c09e"}, + {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f290617f74a610849bd8f5514e34ae3d09eafd521dceaa6cf68b3f4414266d4e"}, + {file = "typed_ast-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:df05aa5b241e2e8045f5f4367a9f6187b09c4cdf8578bb219861c4e27c443db5"}, + {file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"}, ] typer = [ {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, ] typing-extensions = [ - {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, - {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, - {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, + {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, + {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] urllib3 = [ - {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, - {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] zipp = [ - {file = "zipp-3.3.0-py3-none-any.whl", hash = "sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"}, - {file = "zipp-3.3.0.tar.gz", hash = "sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b"}, + {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, + {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, ] diff --git a/pyproject.toml b/pyproject.toml index c16090c62..c4cb09773 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ shellingham = "^1.3.2" black = ">=20.8b1" isort = "^5.0.5" pyyaml = "^5.3.1" -importlib_metadata = {version = "^2.0.0", python = "<3.8"} +importlib_metadata = {version = ">=4.4", python = "<3.8"} pydantic = "^1.6.1" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.1" From 65510b5988204a4bf472480dd7d0eaed2da2058b Mon Sep 17 00:00:00 2001 From: Steve Strassmann Date: Tue, 5 Apr 2022 10:09:49 -0400 Subject: [PATCH 31/50] trivial: fix typo "ommitted" -> "omitted" --- tests/test_parser/test_openapi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_parser/test_openapi.py b/tests/test_parser/test_openapi.py index e3caafa9e..33fdb4658 100644 --- a/tests/test_parser/test_openapi.py +++ b/tests/test_parser/test_openapi.py @@ -278,11 +278,11 @@ def test__add_responses_error(self, mocker): ) assert response.errors == [ ParseError( - detail=f"Cannot parse response for status code 200, response will be ommitted from generated client", + detail=f"Cannot parse response for status code 200, response will be omitted from generated client", data=parse_error.data, ), ParseError( - detail=f"Cannot parse response for status code 404, response will be ommitted from generated client", + detail=f"Cannot parse response for status code 404, response will be omitted from generated client", data=parse_error.data, ), ] From d5085e48fc5fac7b81dbc2909614258b1a991c35 Mon Sep 17 00:00:00 2001 From: jschlaakhs Date: Tue, 5 Apr 2022 11:09:43 -0500 Subject: [PATCH 32/50] Remove unintended updates (#114) * bumped importlib_metadata version to >=4.4 to fix a conflict with Sphinx documentation library in Benchling SDK * fixed unintentional updates --- poetry.lock | 969 +++++++++++++++++++++------------------------------- 1 file changed, 391 insertions(+), 578 deletions(-) diff --git a/poetry.lock b/poetry.lock index 36174ebc3..0748d746d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -16,17 +16,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.4.0" +version = "20.3.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] [[package]] name = "autoflake" @@ -64,22 +64,19 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "certifi" -version = "2021.10.8" +version = "2020.6.20" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = "*" [[package]] -name = "charset-normalizer" -version = "2.0.12" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" category = "dev" optional = false -python-versions = ">=3.5.0" - -[package.extras] -unicode_backport = ["unicodedata2"] +python-versions = "*" [[package]] name = "click" @@ -110,25 +107,22 @@ immutables = ">=0.9" [[package]] name = "coverage" -version = "6.2" +version = "5.3" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.6" - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "extra == \"toml\""} +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -toml = ["tomli"] +toml = ["toml"] [[package]] name = "dataclasses" -version = "0.8" +version = "0.6" description = "A backport of the dataclasses module for Python 3.6" category = "main" optional = false -python-versions = ">=3.6, <3.7" +python-versions = "*" [[package]] name = "dparse" @@ -148,32 +142,29 @@ pipenv = ["pipenv"] [[package]] name = "flake8" -version = "2.3.0" -description = "the modular source code checker: pep8, pyflakes and co" +version = "3.8.4" +description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.dependencies] -mccabe = ">=0.2.1" -pep8 = ">=1.5.7" -pyflakes = ">=0.8.1" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" [[package]] name = "h11" -version = "0.13.0" +version = "0.9.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -dataclasses = {version = "*", markers = "python_version < \"3.7\""} -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} +python-versions = "*" [[package]] name = "httpcore" -version = "0.12.3" +version = "0.12.0" description = "A minimal low-level HTTP client." category = "main" optional = false @@ -206,25 +197,19 @@ http2 = ["h2 (>=3.0.0,<4.0.0)"] [[package]] name = "idna" -version = "3.3" +version = "2.10" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "immutables" -version = "0.17" +version = "0.14" description = "Immutable Collections" category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} - -[package.extras] -test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)", "mypy (>=0.910)", "pytest (>=6.2.4,<6.3.0)"] +python-versions = ">=3.5" [[package]] name = "importlib-metadata" @@ -245,7 +230,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [[package]] name = "iniconfig" -version = "1.1.1" +version = "1.0.1" description = "iniconfig: brain-dead simple config-ini parsing" category = "dev" optional = false @@ -253,7 +238,7 @@ python-versions = "*" [[package]] name = "isort" -version = "5.8.0" +version = "5.6.4" description = "A Python utility / library to sort Python imports." category = "main" optional = false @@ -266,7 +251,7 @@ colors = ["colorama (>=0.4.3,<0.5.0)"] [[package]] name = "jinja2" -version = "2.11.3" +version = "2.11.2" description = "A very fast and expressive template engine." category = "main" optional = false @@ -280,19 +265,19 @@ i18n = ["Babel (>=0.8)"] [[package]] name = "markupsafe" -version = "2.0.1" +version = "1.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" [[package]] name = "mccabe" -version = "0.7.0" +version = "0.6.1" description = "McCabe checker, plugin for flake8" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = "*" [[package]] name = "mslex" @@ -304,22 +289,19 @@ python-versions = ">=3.5" [[package]] name = "mypy" -version = "0.942" +version = "0.790" description = "Optional static typing for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.5" [package.dependencies] -mypy-extensions = ">=0.4.3" -tomli = ">=1.1.0" -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} -typing-extensions = ">=3.10" +mypy-extensions = ">=0.4.3,<0.5.0" +typed-ast = ">=1.4.0,<1.5.0" +typing-extensions = ">=3.7.4" [package.extras] dmypy = ["psutil (>=4.0)"] -python2 = ["typed-ast (>=1.4.0,<2)"] -reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -331,49 +313,41 @@ python-versions = "*" [[package]] name = "packaging" -version = "21.3" +version = "20.4" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +pyparsing = ">=2.0.2" +six = "*" [[package]] name = "pathspec" -version = "0.9.0" +version = "0.8.0" description = "Utility library for gitignore style pattern matching of file paths." category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[[package]] -name = "pep8" -version = "1.7.1" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = "*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pluggy" -version = "1.0.0" +version = "0.13.1" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] [[package]] name = "psutil" -version = "5.9.0" +version = "5.7.2" description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false @@ -384,15 +358,23 @@ test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] [[package]] name = "py" -version = "1.11.0" +version = "1.9.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.7.4" +version = "1.7.3" description = "Data validation and settings management using python 3.6 type hinting" category = "main" optional = false @@ -408,7 +390,7 @@ typing_extensions = ["typing-extensions (>=3.7.2)"] [[package]] name = "pyflakes" -version = "2.4.0" +version = "2.2.0" description = "passive checker of Python programs" category = "main" optional = false @@ -416,18 +398,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" -version = "3.0.7" +version = "2.4.7" description = "Python parsing module" category = "dev" optional = false -python-versions = ">=3.6" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "7.0.1" +version = "6.2.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -440,35 +419,35 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" +pluggy = ">=0.12,<1.0.0a1" py = ">=1.8.2" -tomli = ">=1.0.0" +toml = "*" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [[package]] name = "pytest-cov" -version = "3.0.0" +version = "2.10.1" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} +coverage = ">=4.4" pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-mock" -version = "3.6.1" +version = "3.4.0" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.5" [package.dependencies] pytest = ">=5.0" @@ -478,7 +457,7 @@ dev = ["pre-commit", "tox", "pytest-asyncio"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.8.1" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -500,37 +479,37 @@ six = ">=1.4.0" [[package]] name = "pyyaml" -version = "5.4.1" +version = "5.3.1" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "regex" -version = "2022.3.15" +version = "2020.9.27" description = "Alternative regular expression module, to replace re." category = "main" optional = false -python-versions = ">=3.6" +python-versions = "*" [[package]] name = "requests" -version = "2.27.1" +version = "2.24.0" description = "Python HTTP for Humans." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} -urllib3 = ">=1.21.1,<1.27" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" [package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] [[package]] name = "rfc3986" @@ -548,7 +527,7 @@ idna2008 = ["idna"] [[package]] name = "safety" -version = "1.10.3" +version = "1.10.0" description = "Checks installed dependencies for known vulnerabilities." category = "dev" optional = false @@ -562,7 +541,7 @@ requests = "*" [[package]] name = "shellingham" -version = "1.4.0" +version = "1.3.2" description = "Tool to Detect Surrounding Shell" category = "main" optional = false @@ -570,7 +549,7 @@ python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" [[package]] name = "six" -version = "1.16.0" +version = "1.15.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false @@ -578,7 +557,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "sniffio" -version = "1.2.0" +version = "1.1.0" description = "Sniff out which async library your code is running under" category = "main" optional = false @@ -597,41 +576,32 @@ python-versions = "*" [[package]] name = "taskipy" -version = "1.10.1" +version = "1.5.1" description = "tasks runner for python projects" category = "dev" optional = false python-versions = ">=3.6,<4.0" [package.dependencies] -colorama = ">=0.4.4,<0.5.0" -mslex = {version = ">=0.3.0,<0.4.0", markers = "sys_platform == \"win32\""} +mslex = ">=0.3.0,<0.4.0" psutil = ">=5.7.2,<6.0.0" -tomli = ">=1.2.3,<2.0.0" +toml = ">=0.10.0,<0.11.0" [[package]] name = "toml" -version = "0.10.2" +version = "0.10.1" description = "Python Library for Tom's Obvious, Minimal Language" category = "main" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tomli" -version = "1.2.3" -description = "A lil' TOML parser" -category = "dev" -optional = false -python-versions = ">=3.6" +python-versions = "*" [[package]] name = "typed-ast" -version = "1.5.2" +version = "1.4.1" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "main" optional = false -python-versions = ">=3.6" +python-versions = "*" [[package]] name = "typer" @@ -652,36 +622,36 @@ doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown- [[package]] name = "typing-extensions" -version = "4.1.1" -description = "Backported and Experimental Type Hints for Python 3.6+" +version = "3.7.4.3" +description = "Backported and Experimental Type Hints for Python 3.5+" category = "main" optional = false -python-versions = ">=3.6" +python-versions = "*" [[package]] name = "urllib3" -version = "1.26.9" +version = "1.25.10" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "zipp" -version = "3.6.0" +version = "3.3.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.6" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" @@ -698,8 +668,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, + {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] autoflake = [ {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, @@ -708,12 +678,12 @@ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, + {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, + {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, ] -charset-normalizer = [ - {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, - {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -727,547 +697,390 @@ contextvars = [ {file = "contextvars-2.4.tar.gz", hash = "sha256:f38c908aaa59c14335eeea12abea5f443646216c4e29380d7bf34d2018e2c39e"}, ] coverage = [ - {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, - {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, - {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, - {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, - {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, - {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, - {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, - {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, - {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, - {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, - {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, - {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, - {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, - {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, - {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, - {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, - {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, - {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, - {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, - {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"}, + {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"}, + {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"}, + {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"}, + {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"}, + {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"}, + {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"}, + {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"}, + {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"}, + {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"}, + {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"}, + {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"}, + {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"}, + {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"}, + {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"}, + {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"}, + {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"}, + {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, + {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, ] dataclasses = [ - {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, - {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, + {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, + {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, ] dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, ] flake8 = [ - {file = "flake8-2.3.0-py2.py3-none-any.whl", hash = "sha256:c99cc9716d6655d9c8bcb1e77632b8615bf0abd282d7abd9f5c2148cad7fc669"}, - {file = "flake8-2.3.0.tar.gz", hash = "sha256:5ee1a43ccd0716d6061521eec6937c983efa027793013e572712c4da55c7c83e"}, + {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, + {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, ] h11 = [ - {file = "h11-0.13.0-py3-none-any.whl", hash = "sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"}, - {file = "h11-0.13.0.tar.gz", hash = "sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06"}, + {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, + {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, ] httpcore = [ - {file = "httpcore-0.12.3-py3-none-any.whl", hash = "sha256:93e822cd16c32016b414b789aeff4e855d0ccbfc51df563ee34d4dbadbb3bcdc"}, - {file = "httpcore-0.12.3.tar.gz", hash = "sha256:37ae835fb370049b2030c3290e12ed298bf1473c41bb72ca4aa78681eba9b7c9"}, + {file = "httpcore-0.12.0-py3-none-any.whl", hash = "sha256:18c4afcbfe884b635e59739105aed1692e132bc5d31597109f3c1c97e4ec1cac"}, + {file = "httpcore-0.12.0.tar.gz", hash = "sha256:2526a38f31ac5967d38b7f593b5d8c4bd3fa82c21400402f866ba3312946acbf"}, ] httpx = [ {file = "httpx-0.16.1-py3-none-any.whl", hash = "sha256:9cffb8ba31fac6536f2c8cde30df859013f59e4bcc5b8d43901cb3654a8e0a5b"}, {file = "httpx-0.16.1.tar.gz", hash = "sha256:126424c279c842738805974687e0518a94c7ae8d140cd65b9c4f77ac46ffa537"}, ] idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] immutables = [ - {file = "immutables-0.17-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cab10d65a29b2019fffd7a3924f6965a8f785e7bd409641ce36ab2d3335f88c4"}, - {file = "immutables-0.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f73088c9b8595ddfd45a5658f8cce0cb3ae6e5890458381fccba3ed3035081d4"}, - {file = "immutables-0.17-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef632832fa1acae6861d83572b866126f9e35706ab6e581ce6b175b3e0b7a3c4"}, - {file = "immutables-0.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0efdcec7b63859b41f794ffa0cd0d6dc87e77d1be4ff0ec23471a3a1e719235f"}, - {file = "immutables-0.17-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eca96f12bc1535657d24eae2c69816d0b22c4a4bc7f4753115e028a137e8dad"}, - {file = "immutables-0.17-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:01a25b1056754aa486afea5471ca348410d77f458477ccb6fa3baf2d3e3ff3d5"}, - {file = "immutables-0.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c41a6648f7355f1241da677c418edae56fdc45af19ad3540ca8a1e7a81606a7a"}, - {file = "immutables-0.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0b578bba11bd8ae55dee9536edf8d82be18463d15d4b4c9827e27eeeb73826bf"}, - {file = "immutables-0.17-cp310-cp310-win32.whl", hash = "sha256:a28682e115191e909673aedb9ccea3377da3a6a929f8bd86982a2a76bdfa89db"}, - {file = "immutables-0.17-cp310-cp310-win_amd64.whl", hash = "sha256:293ddb681502945f29b3065e688a962e191e752320040892316b9dd1e3b9c8c9"}, - {file = "immutables-0.17-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ec04fc7d9f76f26d82a5d9d1715df0409d0096309828fc46cd1a2067c7fbab95"}, - {file = "immutables-0.17-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f024f25e9fda42251a2b2167668ca70678c19fb3ab6ed509cef0b4b431d0ff73"}, - {file = "immutables-0.17-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b02083b2052cc201ac5cbd38f34a5da21fcd51016cb4ddd1fb43d7dc113eac17"}, - {file = "immutables-0.17-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea32db31afb82d8369e98f85c5b815ff81610a12fbc837830a34388f1b56f080"}, - {file = "immutables-0.17-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:898a9472d1dd3d17f291114395a1be65be035355fc65af0b2c88238f8fbeaa62"}, - {file = "immutables-0.17-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:736dd3d88d44da0ee48804792bd095c01a344c5d1b0f10beeb9ccb3a00b9c19d"}, - {file = "immutables-0.17-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:15ff4139720f79b902f435a25e3c00f9c8adcc41d79bed64b7e51ae36cfe9620"}, - {file = "immutables-0.17-cp36-cp36m-win32.whl", hash = "sha256:4f018a6c4c3689b82f763ad4f84dec6aa91c83981db7f6bafef963f036e5e815"}, - {file = "immutables-0.17-cp36-cp36m-win_amd64.whl", hash = "sha256:d7400a6753b292ac80102ed026efa8da2c3fedd50c443924cbe9b6448d3b19e4"}, - {file = "immutables-0.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f7a6e0380bddb99c46bb3f12ae5eee9a23d6a66d99bbf0fb10fa552f935c2e8d"}, - {file = "immutables-0.17-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7696c42d1f9a16ecda0ee46229848df8706973690b45e8a090d995d647a5ec57"}, - {file = "immutables-0.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:892b6a1619cd8c398fa70302c4cfa9768a694377639330e7a58cc7be111ab23e"}, - {file = "immutables-0.17-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89093d5a85357250b1d5ae218fdcfdbac4097cbb2d8b55004aa7a2ca2a00a09f"}, - {file = "immutables-0.17-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99a8bc6d0623300eb46beea74f7a5061968fb3efc4e072f23f6c0b21c588238d"}, - {file = "immutables-0.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:00380474f8e3b4a2eeb06ce694e0e3cb85a144919140a2b3116defb6c1587471"}, - {file = "immutables-0.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:078e3ed63be0ac36523b80bbabbfb1bb57e55009f4efb5650b0e3b3ed569c3f1"}, - {file = "immutables-0.17-cp37-cp37m-win32.whl", hash = "sha256:14905aecc62b318d86045dcf8d35ef2063803d9d331aeccd88958f03caadc7b0"}, - {file = "immutables-0.17-cp37-cp37m-win_amd64.whl", hash = "sha256:3774d403d1570105a1da2e00c38ce3f04065fd1deff04cf998f8d8e946d0ae13"}, - {file = "immutables-0.17-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e5a9caee1b99eccf1447056ae6bda77edd15c357421293e81fa1a4f28e83448a"}, - {file = "immutables-0.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fed1e1baf1de1bc94a0310da29814892064928d7d40ff5a3b86bcd11d5e7cfff"}, - {file = "immutables-0.17-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d7daa340d76747ba5a8f64816b48def74bd4be45a9508073b34fa954d099fba"}, - {file = "immutables-0.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4644c29fe07fb92ba84b26659708e1799fecaaf781214adf13edd8a4d7495a9"}, - {file = "immutables-0.17-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e9ea0e2a31db44fb01617ff875d4c26f962696e1c5ff11ed7767c2d8dedac4"}, - {file = "immutables-0.17-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:64100dfdb29fae2bc84748fff5d66dd6b3997806c717eeb75f7099aeee9b1878"}, - {file = "immutables-0.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5f933e5bf6f2c1afb24bc2fc8bea8b132096a4a6ba54f36be59787981f3e50ff"}, - {file = "immutables-0.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9508a087a47f9f9506adf2fa8383ab14c46a222b57eea8612bc4c2aa9a9550fe"}, - {file = "immutables-0.17-cp38-cp38-win32.whl", hash = "sha256:dfd2c63f15d1e5ea1ed2a05b7c602b5f61a64337415d299df20e103a57ae4906"}, - {file = "immutables-0.17-cp38-cp38-win_amd64.whl", hash = "sha256:301c539660c988c5b24051ccad1e36c040a916f1e58fa3e245e3122fc50dd28d"}, - {file = "immutables-0.17-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:563bc2ddbe75c10faa3b4b0206870653b44a231b97ed23cff8ab8aff503d922d"}, - {file = "immutables-0.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f621ea6130393cd14d0fbd35b306d4dc70bcd0fda550a8cd313db8015e34ca60"}, - {file = "immutables-0.17-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57c2d1b16b716bca70345db334dd6a861bf45c46cb11bb1801277f8a9012e864"}, - {file = "immutables-0.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a08e1a80bd8c5df72c2bf0af24a37ceec17e8ffdb850ed5a62d0bba1d4d86018"}, - {file = "immutables-0.17-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b99155ad112149d43208c611c6c42f19e16716526dacc0fcc16736d2f5d2e20"}, - {file = "immutables-0.17-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ed71e736f8fb82545d00c8969dbc167547c15e85729058edbed3c03b94fca86c"}, - {file = "immutables-0.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:19e4b8e5810dd7cab63fa700373f787a369d992166eabc23f4b962e5704d33c5"}, - {file = "immutables-0.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:305062012497d4c4a70fe35e20cef2c6f65744e721b04671092a63354799988d"}, - {file = "immutables-0.17-cp39-cp39-win32.whl", hash = "sha256:f5c6bd012384a8d6af7bb25675719214d76640fe6c336e2b5fba9eef1407ae6a"}, - {file = "immutables-0.17-cp39-cp39-win_amd64.whl", hash = "sha256:615ab26873a794559ccaf4e0e9afdb5aefad0867c15262ba64a55a12a5a41573"}, - {file = "immutables-0.17.tar.gz", hash = "sha256:ad894446355b6f5289a9c84fb46f7c47c6ef2b1bfbdd2be6cb177dbb7f1587ad"}, + {file = "immutables-0.14-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:860666fab142401a5535bf65cbd607b46bc5ed25b9d1eb053ca8ed9a1a1a80d6"}, + {file = "immutables-0.14-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ce01788878827c3f0331c254a4ad8d9721489a5e65cc43e19c80040b46e0d297"}, + {file = "immutables-0.14-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8797eed4042f4626b0bc04d9cf134208918eb0c937a8193a2c66df5041e62d2e"}, + {file = "immutables-0.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:33ce2f977da7b5e0dddd93744862404bdb316ffe5853ec853e53141508fa2e6a"}, + {file = "immutables-0.14-cp36-cp36m-win_amd64.whl", hash = "sha256:6c8eace4d98988c72bcb37c05e79aae756832738305ae9497670482a82db08bc"}, + {file = "immutables-0.14-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:ab6c18b7b2b2abc83e0edc57b0a38bf0915b271582a1eb8c7bed1c20398f8040"}, + {file = "immutables-0.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c099212fd6504513a50e7369fe281007c820cf9d7bb22a336486c63d77d6f0b2"}, + {file = "immutables-0.14-cp37-cp37m-win_amd64.whl", hash = "sha256:714aedbdeba4439d91cb5e5735cb10631fc47a7a69ea9cc8ecbac90322d50a4a"}, + {file = "immutables-0.14-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:1c11050c49e193a1ec9dda1747285333f6ba6a30bbeb2929000b9b1192097ec0"}, + {file = "immutables-0.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c453e12b95e1d6bb4909e8743f88b7f5c0c97b86a8bc0d73507091cb644e3c1e"}, + {file = "immutables-0.14-cp38-cp38-win_amd64.whl", hash = "sha256:ef9da20ec0f1c5853b5c8f8e3d9e1e15b8d98c259de4b7515d789a606af8745e"}, + {file = "immutables-0.14.tar.gz", hash = "sha256:a0a1cc238b678455145bae291d8426f732f5255537ed6a5b7645949704c70a78"}, ] importlib-metadata = [ {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, {file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"}, ] iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, + {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, + {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, ] isort = [ - {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"}, - {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"}, + {file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"}, + {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, ] jinja2 = [ - {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, - {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, + {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, + {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {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"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {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"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {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"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {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"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {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"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, + {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] mccabe = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] mslex = [ {file = "mslex-0.3.0-py2.py3-none-any.whl", hash = "sha256:380cb14abf8fabf40e56df5c8b21a6d533dc5cbdcfe42406bbf08dda8f42e42a"}, {file = "mslex-0.3.0.tar.gz", hash = "sha256:4a1ac3f25025cad78ad2fe499dd16d42759f7a3801645399cce5c404415daa97"}, ] mypy = [ - {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, - {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, - {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, - {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, - {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, - {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, - {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, - {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, - {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, - {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, - {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, - {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, - {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, - {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, - {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, - {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, - {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, - {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, - {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, - {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, - {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, - {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, - {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, + {file = "mypy-0.790-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:bd03b3cf666bff8d710d633d1c56ab7facbdc204d567715cb3b9f85c6e94f669"}, + {file = "mypy-0.790-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:2170492030f6faa537647d29945786d297e4862765f0b4ac5930ff62e300d802"}, + {file = "mypy-0.790-cp35-cp35m-win_amd64.whl", hash = "sha256:e86bdace26c5fe9cf8cb735e7cedfe7850ad92b327ac5d797c656717d2ca66de"}, + {file = "mypy-0.790-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e97e9c13d67fbe524be17e4d8025d51a7dca38f90de2e462243ab8ed8a9178d1"}, + {file = "mypy-0.790-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0d34d6b122597d48a36d6c59e35341f410d4abfa771d96d04ae2c468dd201abc"}, + {file = "mypy-0.790-cp36-cp36m-win_amd64.whl", hash = "sha256:72060bf64f290fb629bd4a67c707a66fd88ca26e413a91384b18db3876e57ed7"}, + {file = "mypy-0.790-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eea260feb1830a627fb526d22fbb426b750d9f5a47b624e8d5e7e004359b219c"}, + {file = "mypy-0.790-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c614194e01c85bb2e551c421397e49afb2872c88b5830e3554f0519f9fb1c178"}, + {file = "mypy-0.790-cp37-cp37m-win_amd64.whl", hash = "sha256:0a0d102247c16ce93c97066443d11e2d36e6cc2a32d8ccc1f705268970479324"}, + {file = "mypy-0.790-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4e7bf7f1214826cf7333627cb2547c0db7e3078723227820d0a2490f117a01"}, + {file = "mypy-0.790-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:af4e9ff1834e565f1baa74ccf7ae2564ae38c8df2a85b057af1dbbc958eb6666"}, + {file = "mypy-0.790-cp38-cp38-win_amd64.whl", hash = "sha256:da56dedcd7cd502ccd3c5dddc656cb36113dd793ad466e894574125945653cea"}, + {file = "mypy-0.790-py3-none-any.whl", hash = "sha256:2842d4fbd1b12ab422346376aad03ff5d0805b706102e475e962370f874a5122"}, + {file = "mypy-0.790.tar.gz", hash = "sha256:2b21ba45ad9ef2e2eb88ce4aeadd0112d0f5026418324176fd494a6824b74975"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, ] pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, -] -pep8 = [ - {file = "pep8-1.7.1-py2.py3-none-any.whl", hash = "sha256:b22cfae5db09833bb9bd7c8463b53e1a9c9b39f12e304a8d0bba729c501827ee"}, - {file = "pep8-1.7.1.tar.gz", hash = "sha256:fe249b52e20498e59e0b5c5256aa52ee99fc295b26ec9eaa85776ffdb9fe6374"}, + {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, + {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, ] pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] psutil = [ - {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b"}, - {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618"}, - {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2"}, - {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd"}, - {file = "psutil-5.9.0-cp27-none-win32.whl", hash = "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3"}, - {file = "psutil-5.9.0-cp27-none-win_amd64.whl", hash = "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c"}, - {file = "psutil-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492"}, - {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3"}, - {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2"}, - {file = "psutil-5.9.0-cp310-cp310-win32.whl", hash = "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d"}, - {file = "psutil-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b"}, - {file = "psutil-5.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56"}, - {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203"}, - {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d"}, - {file = "psutil-5.9.0-cp36-cp36m-win32.whl", hash = "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64"}, - {file = "psutil-5.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94"}, - {file = "psutil-5.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0"}, - {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce"}, - {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5"}, - {file = "psutil-5.9.0-cp37-cp37m-win32.whl", hash = "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9"}, - {file = "psutil-5.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4"}, - {file = "psutil-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2"}, - {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d"}, - {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a"}, - {file = "psutil-5.9.0-cp38-cp38-win32.whl", hash = "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666"}, - {file = "psutil-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841"}, - {file = "psutil-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf"}, - {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07"}, - {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d"}, - {file = "psutil-5.9.0-cp39-cp39-win32.whl", hash = "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845"}, - {file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"}, - {file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"}, + {file = "psutil-5.7.2-cp27-none-win32.whl", hash = "sha256:f2018461733b23f308c298653c8903d32aaad7873d25e1d228765e91ae42c3f2"}, + {file = "psutil-5.7.2-cp27-none-win_amd64.whl", hash = "sha256:66c18ca7680a31bf16ee22b1d21b6397869dda8059dbdb57d9f27efa6615f195"}, + {file = "psutil-5.7.2-cp35-cp35m-win32.whl", hash = "sha256:5e9d0f26d4194479a13d5f4b3798260c20cecf9ac9a461e718eb59ea520a360c"}, + {file = "psutil-5.7.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4080869ed93cce662905b029a1770fe89c98787e543fa7347f075ade761b19d6"}, + {file = "psutil-5.7.2-cp36-cp36m-win32.whl", hash = "sha256:d8a82162f23c53b8525cf5f14a355f5d1eea86fa8edde27287dd3a98399e4fdf"}, + {file = "psutil-5.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0ee3c36428f160d2d8fce3c583a0353e848abb7de9732c50cf3356dd49ad63f8"}, + {file = "psutil-5.7.2-cp37-cp37m-win32.whl", hash = "sha256:ff1977ba1a5f71f89166d5145c3da1cea89a0fdb044075a12c720ee9123ec818"}, + {file = "psutil-5.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a5b120bb3c0c71dfe27551f9da2f3209a8257a178ed6c628a819037a8df487f1"}, + {file = "psutil-5.7.2-cp38-cp38-win32.whl", hash = "sha256:10512b46c95b02842c225f58fa00385c08fa00c68bac7da2d9a58ebe2c517498"}, + {file = "psutil-5.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:68d36986ded5dac7c2dcd42f2682af1db80d4bce3faa126a6145c1637e1b559f"}, + {file = "psutil-5.7.2.tar.gz", hash = "sha256:90990af1c3c67195c44c9a889184f84f5b2320dce3ee3acbd054e3ba0b4a7beb"}, ] py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, + {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, + {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, ] pydantic = [ - {file = "pydantic-1.7.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3c60039e84552442defbcb5d56711ef0e057028ca7bfc559374917408a88d84e"}, - {file = "pydantic-1.7.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6e7e314acb170e143c6f3912f93f2ec80a96aa2009ee681356b7ce20d57e5c62"}, - {file = "pydantic-1.7.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:8ef77cd17b73b5ba46788d040c0e820e49a2d80cfcd66fda3ba8be31094fd146"}, - {file = "pydantic-1.7.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:115d8aa6f257a1d469c66b6bfc7aaf04cd87c25095f24542065c68ebcb42fe63"}, - {file = "pydantic-1.7.4-cp36-cp36m-win_amd64.whl", hash = "sha256:66757d4e1eab69a3cfd3114480cc1d72b6dd847c4d30e676ae838c6740fdd146"}, - {file = "pydantic-1.7.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c92863263e4bd89e4f9cf1ab70d918170c51bd96305fe7b00853d80660acb26"}, - {file = "pydantic-1.7.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3b8154babf30a5e0fa3aa91f188356763749d9b30f7f211fafb247d4256d7877"}, - {file = "pydantic-1.7.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:80cc46378505f7ff202879dcffe4bfbf776c15675028f6e08d1d10bdfbb168ac"}, - {file = "pydantic-1.7.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:dda60d7878a5af2d8560c55c7c47a8908344aa78d32ec1c02d742ede09c534df"}, - {file = "pydantic-1.7.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4c1979d5cc3e14b35f0825caddea5a243dd6085e2a7539c006bc46997ef7a61a"}, - {file = "pydantic-1.7.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8857576600c32aa488f18d30833aa833b54a48e3bab3adb6de97e463af71f8f8"}, - {file = "pydantic-1.7.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1f86d4da363badb39426a0ff494bf1d8510cd2f7274f460eee37bdbf2fd495ec"}, - {file = "pydantic-1.7.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:3ea1256a9e782149381e8200119f3e2edea7cd6b123f1c79ab4bbefe4d9ba2c9"}, - {file = "pydantic-1.7.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:e28455b42a0465a7bf2cde5eab530389226ce7dc779de28d17b8377245982b1e"}, - {file = "pydantic-1.7.4-cp38-cp38-win_amd64.whl", hash = "sha256:47c5b1d44934375a3311891cabd450c150a31cf5c22e84aa172967bf186718be"}, - {file = "pydantic-1.7.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:00250e5123dd0b123ff72be0e1b69140e0b0b9e404d15be3846b77c6f1b1e387"}, - {file = "pydantic-1.7.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d24aa3f7f791a023888976b600f2f389d3713e4f23b7a4c88217d3fce61cdffc"}, - {file = "pydantic-1.7.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2c44a9afd4c4c850885436a4209376857989aaf0853c7b118bb2e628d4b78c4e"}, - {file = "pydantic-1.7.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:e87edd753da0ca1d44e308a1b1034859ffeab1f4a4492276bff9e1c3230db4fe"}, - {file = "pydantic-1.7.4-cp39-cp39-win_amd64.whl", hash = "sha256:a3026ee105b5360855e500b4abf1a1d0b034d88e75a2d0d66a4c35e60858e15b"}, - {file = "pydantic-1.7.4-py3-none-any.whl", hash = "sha256:a82385c6d5a77e3387e94612e3e34b77e13c39ff1295c26e3ba664e7b98073e2"}, - {file = "pydantic-1.7.4.tar.gz", hash = "sha256:0a1abcbd525fbb52da58c813d54c2ec706c31a91afdb75411a73dd1dec036595"}, + {file = "pydantic-1.7.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c59ea046aea25be14dc22d69c97bee629e6d48d2b2ecb724d7fe8806bf5f61cd"}, + {file = "pydantic-1.7.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a4143c8d0c456a093387b96e0f5ee941a950992904d88bc816b4f0e72c9a0009"}, + {file = "pydantic-1.7.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:d8df4b9090b595511906fa48deda47af04e7d092318bfb291f4d45dfb6bb2127"}, + {file = "pydantic-1.7.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:514b473d264671a5c672dfb28bdfe1bf1afd390f6b206aa2ec9fed7fc592c48e"}, + {file = "pydantic-1.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:dba5c1f0a3aeea5083e75db9660935da90216f8a81b6d68e67f54e135ed5eb23"}, + {file = "pydantic-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59e45f3b694b05a69032a0d603c32d453a23f0de80844fb14d55ab0c6c78ff2f"}, + {file = "pydantic-1.7.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:5b24e8a572e4b4c18f614004dda8c9f2c07328cb5b6e314d6e1bbd536cb1a6c1"}, + {file = "pydantic-1.7.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:b2b054d095b6431cdda2f852a6d2f0fdec77686b305c57961b4c5dd6d863bf3c"}, + {file = "pydantic-1.7.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:025bf13ce27990acc059d0c5be46f416fc9b293f45363b3d19855165fee1874f"}, + {file = "pydantic-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6e3874aa7e8babd37b40c4504e3a94cc2023696ced5a0500949f3347664ff8e2"}, + {file = "pydantic-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e682f6442ebe4e50cb5e1cfde7dda6766fb586631c3e5569f6aa1951fd1a76ef"}, + {file = "pydantic-1.7.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:185e18134bec5ef43351149fe34fda4758e53d05bb8ea4d5928f0720997b79ef"}, + {file = "pydantic-1.7.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:f5b06f5099e163295b8ff5b1b71132ecf5866cc6e7f586d78d7d3fd6e8084608"}, + {file = "pydantic-1.7.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:24ca47365be2a5a3cc3f4a26dcc755bcdc9f0036f55dcedbd55663662ba145ec"}, + {file = "pydantic-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:d1fe3f0df8ac0f3a9792666c69a7cd70530f329036426d06b4f899c025aca74e"}, + {file = "pydantic-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f6864844b039805add62ebe8a8c676286340ba0c6d043ae5dea24114b82a319e"}, + {file = "pydantic-1.7.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ecb54491f98544c12c66ff3d15e701612fc388161fd455242447083350904730"}, + {file = "pydantic-1.7.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:ffd180ebd5dd2a9ac0da4e8b995c9c99e7c74c31f985ba090ee01d681b1c4b95"}, + {file = "pydantic-1.7.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8d72e814c7821125b16f1553124d12faba88e85405b0864328899aceaad7282b"}, + {file = "pydantic-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:475f2fa134cf272d6631072554f845d0630907fce053926ff634cc6bc45bf1af"}, + {file = "pydantic-1.7.3-py3-none-any.whl", hash = "sha256:38be427ea01a78206bcaf9a56f835784afcba9e5b88fbdce33bbbfbcd7841229"}, + {file = "pydantic-1.7.3.tar.gz", hash = "sha256:213125b7e9e64713d16d988d10997dabc6a1f73f3991e1ff8e35ebb1409c7dc9"}, ] pyflakes = [ - {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, - {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, ] pyparsing = [ - {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, - {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"}, - {file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"}, + {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, + {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, ] pytest-cov = [ - {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, - {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, + {file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"}, + {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, ] pytest-mock = [ - {file = "pytest-mock-3.6.1.tar.gz", hash = "sha256:40217a058c52a63f1042f0784f62009e976ba824c418cced42e88d5f40ab0e62"}, - {file = "pytest_mock-3.6.1-py3-none-any.whl", hash = "sha256:30c2f2cc9759e76eee674b81ea28c9f0b94f8f0445a1b87762cadf774f0df7e3"}, + {file = "pytest-mock-3.4.0.tar.gz", hash = "sha256:c3981f5edee6c4d1942250a60d9b39d38d5585398de1bfce057f925bdda720f4"}, + {file = "pytest_mock-3.4.0-py3-none-any.whl", hash = "sha256:c0fc979afac4aaba545cbd01e9c20736eb3fefb0a066558764b07d3de8f04ed3"}, ] python-dateutil = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] python-multipart = [ {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, ] pyyaml = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, + {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] regex = [ - {file = "regex-2022.3.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:42eb13b93765c6698a5ab3bcd318d8c39bb42e5fa8a7fcf7d8d98923f3babdb1"}, - {file = "regex-2022.3.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9beb03ff6fe509d6455971c2489dceb31687b38781206bcec8e68bdfcf5f1db2"}, - {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0a5a1fdc9f148a8827d55b05425801acebeeefc9e86065c7ac8b8cc740a91ff"}, - {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb374a2a4dba7c4be0b19dc7b1adc50e6c2c26c3369ac629f50f3c198f3743a4"}, - {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c33ce0c665dd325200209340a88438ba7a470bd5f09f7424e520e1a3ff835b52"}, - {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04c09b9651fa814eeeb38e029dc1ae83149203e4eeb94e52bb868fadf64852bc"}, - {file = "regex-2022.3.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab5d89cfaf71807da93c131bb7a19c3e19eaefd613d14f3bce4e97de830b15df"}, - {file = "regex-2022.3.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e2630ae470d6a9f8e4967388c1eda4762706f5750ecf387785e0df63a4cc5af"}, - {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:df037c01d68d1958dad3463e2881d3638a0d6693483f58ad41001aa53a83fcea"}, - {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:940570c1a305bac10e8b2bc934b85a7709c649317dd16520471e85660275083a"}, - {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7f63877c87552992894ea1444378b9c3a1d80819880ae226bb30b04789c0828c"}, - {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3e265b388cc80c7c9c01bb4f26c9e536c40b2c05b7231fbb347381a2e1c8bf43"}, - {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:058054c7a54428d5c3e3739ac1e363dc9347d15e64833817797dc4f01fb94bb8"}, - {file = "regex-2022.3.15-cp310-cp310-win32.whl", hash = "sha256:76435a92e444e5b8f346aed76801db1c1e5176c4c7e17daba074fbb46cb8d783"}, - {file = "regex-2022.3.15-cp310-cp310-win_amd64.whl", hash = "sha256:174d964bc683b1e8b0970e1325f75e6242786a92a22cedb2a6ec3e4ae25358bd"}, - {file = "regex-2022.3.15-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6e1d8ed9e61f37881c8db383a124829a6e8114a69bd3377a25aecaeb9b3538f8"}, - {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b52771f05cff7517f7067fef19ffe545b1f05959e440d42247a17cd9bddae11b"}, - {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673f5a393d603c34477dbad70db30025ccd23996a2d0916e942aac91cc42b31a"}, - {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8923e1c5231549fee78ff9b2914fad25f2e3517572bb34bfaa3aea682a758683"}, - {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764e66a0e382829f6ad3bbce0987153080a511c19eb3d2f8ead3f766d14433ac"}, - {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd00859291658fe1fda48a99559fb34da891c50385b0bfb35b808f98956ef1e7"}, - {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa2ce79f3889720b46e0aaba338148a1069aea55fda2c29e0626b4db20d9fcb7"}, - {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:34bb30c095342797608727baf5c8aa122406aa5edfa12107b8e08eb432d4c5d7"}, - {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:25ecb1dffc5e409ca42f01a2b2437f93024ff1612c1e7983bad9ee191a5e8828"}, - {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:aa5eedfc2461c16a092a2fabc5895f159915f25731740c9152a1b00f4bcf629a"}, - {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:7d1a6e403ac8f1d91d8f51c441c3f99367488ed822bda2b40836690d5d0059f5"}, - {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:3e4d710ff6539026e49f15a3797c6b1053573c2b65210373ef0eec24480b900b"}, - {file = "regex-2022.3.15-cp36-cp36m-win32.whl", hash = "sha256:0100f0ded953b6b17f18207907159ba9be3159649ad2d9b15535a74de70359d3"}, - {file = "regex-2022.3.15-cp36-cp36m-win_amd64.whl", hash = "sha256:f320c070dea3f20c11213e56dbbd7294c05743417cde01392148964b7bc2d31a"}, - {file = "regex-2022.3.15-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fc8c7958d14e8270171b3d72792b609c057ec0fa17d507729835b5cff6b7f69a"}, - {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ca6dcd17f537e9f3793cdde20ac6076af51b2bd8ad5fe69fa54373b17b48d3c"}, - {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0214ff6dff1b5a4b4740cfe6e47f2c4c92ba2938fca7abbea1359036305c132f"}, - {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a98ae493e4e80b3ded6503ff087a8492db058e9c68de371ac3df78e88360b374"}, - {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b1cc70e31aacc152a12b39245974c8fccf313187eead559ee5966d50e1b5817"}, - {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4829db3737480a9d5bfb1c0320c4ee13736f555f53a056aacc874f140e98f64"}, - {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:303b15a3d32bf5fe5a73288c316bac5807587f193ceee4eb6d96ee38663789fa"}, - {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:dc7b7c16a519d924c50876fb152af661a20749dcbf653c8759e715c1a7a95b18"}, - {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ce3057777a14a9a1399b81eca6a6bfc9612047811234398b84c54aeff6d536ea"}, - {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:48081b6bff550fe10bcc20c01cf6c83dbca2ccf74eeacbfac240264775fd7ecf"}, - {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dcbb7665a9db9f8d7642171152c45da60e16c4f706191d66a1dc47ec9f820aed"}, - {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c155a1a80c5e7a8fa1d9bb1bf3c8a953532b53ab1196092749bafb9d3a7cbb60"}, - {file = "regex-2022.3.15-cp37-cp37m-win32.whl", hash = "sha256:04b5ee2b6d29b4a99d38a6469aa1db65bb79d283186e8460542c517da195a8f6"}, - {file = "regex-2022.3.15-cp37-cp37m-win_amd64.whl", hash = "sha256:797437e6024dc1589163675ae82f303103063a0a580c6fd8d0b9a0a6708da29e"}, - {file = "regex-2022.3.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8afcd1c2297bc989dceaa0379ba15a6df16da69493635e53431d2d0c30356086"}, - {file = "regex-2022.3.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0066a6631c92774391f2ea0f90268f0d82fffe39cb946f0f9c6b382a1c61a5e5"}, - {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8248f19a878c72d8c0a785a2cd45d69432e443c9f10ab924c29adda77b324ae"}, - {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d1f3ea0d1924feb4cf6afb2699259f658a08ac6f8f3a4a806661c2dfcd66db1"}, - {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:794a6bc66c43db8ed06698fc32aaeaac5c4812d9f825e9589e56f311da7becd9"}, - {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d1445824944e642ffa54c4f512da17a953699c563a356d8b8cbdad26d3b7598"}, - {file = "regex-2022.3.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f553a1190ae6cd26e553a79f6b6cfba7b8f304da2071052fa33469da075ea625"}, - {file = "regex-2022.3.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:75a5e6ce18982f0713c4bac0704bf3f65eed9b277edd3fb9d2b0ff1815943327"}, - {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f16cf7e4e1bf88fecf7f41da4061f181a6170e179d956420f84e700fb8a3fd6b"}, - {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dad3991f0678facca1a0831ec1ddece2eb4d1dd0f5150acb9440f73a3b863907"}, - {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:491fc754428514750ab21c2d294486223ce7385446f2c2f5df87ddbed32979ae"}, - {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6504c22c173bb74075d7479852356bb7ca80e28c8e548d4d630a104f231e04fb"}, - {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01c913cf573d1da0b34c9001a94977273b5ee2fe4cb222a5d5b320f3a9d1a835"}, - {file = "regex-2022.3.15-cp38-cp38-win32.whl", hash = "sha256:029e9e7e0d4d7c3446aa92474cbb07dafb0b2ef1d5ca8365f059998c010600e6"}, - {file = "regex-2022.3.15-cp38-cp38-win_amd64.whl", hash = "sha256:947a8525c0a95ba8dc873191f9017d1b1e3024d4dc757f694e0af3026e34044a"}, - {file = "regex-2022.3.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:591d4fba554f24bfa0421ba040cd199210a24301f923ed4b628e1e15a1001ff4"}, - {file = "regex-2022.3.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9809404528a999cf02a400ee5677c81959bc5cb938fdc696b62eb40214e3632"}, - {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f08a7e4d62ea2a45557f561eea87c907222575ca2134180b6974f8ac81e24f06"}, - {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a86cac984da35377ca9ac5e2e0589bd11b3aebb61801204bd99c41fac516f0d"}, - {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:286908cbe86b1a0240a867aecfe26a439b16a1f585d2de133540549831f8e774"}, - {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b7494df3fdcc95a1f76cf134d00b54962dd83189520fd35b8fcd474c0aa616d"}, - {file = "regex-2022.3.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b1ceede92400b3acfebc1425937454aaf2c62cd5261a3fabd560c61e74f6da3"}, - {file = "regex-2022.3.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0317eb6331146c524751354ebef76a7a531853d7207a4d760dfb5f553137a2a4"}, - {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c144405220c5ad3f5deab4c77f3e80d52e83804a6b48b6bed3d81a9a0238e4c"}, - {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5b2e24f3ae03af3d8e8e6d824c891fea0ca9035c5d06ac194a2700373861a15c"}, - {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f2c53f3af011393ab5ed9ab640fa0876757498aac188f782a0c620e33faa2a3d"}, - {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:060f9066d2177905203516c62c8ea0066c16c7342971d54204d4e51b13dfbe2e"}, - {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:530a3a16e57bd3ea0dff5ec2695c09632c9d6c549f5869d6cf639f5f7153fb9c"}, - {file = "regex-2022.3.15-cp39-cp39-win32.whl", hash = "sha256:78ce90c50d0ec970bd0002462430e00d1ecfd1255218d52d08b3a143fe4bde18"}, - {file = "regex-2022.3.15-cp39-cp39-win_amd64.whl", hash = "sha256:c5adc854764732dbd95a713f2e6c3e914e17f2ccdc331b9ecb777484c31f73b6"}, - {file = "regex-2022.3.15.tar.gz", hash = "sha256:0a7b75cc7bb4cc0334380053e4671c560e31272c9d2d5a6c4b8e9ae2c9bd0f82"}, + {file = "regex-2020.9.27-cp27-cp27m-win32.whl", hash = "sha256:d23a18037313714fb3bb5a94434d3151ee4300bae631894b1ac08111abeaa4a3"}, + {file = "regex-2020.9.27-cp27-cp27m-win_amd64.whl", hash = "sha256:84e9407db1b2eb368b7ecc283121b5e592c9aaedbe8c78b1a2f1102eb2e21d19"}, + {file = "regex-2020.9.27-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f18875ac23d9aa2f060838e8b79093e8bb2313dbaaa9f54c6d8e52a5df097be"}, + {file = "regex-2020.9.27-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ae91972f8ac958039920ef6e8769277c084971a142ce2b660691793ae44aae6b"}, + {file = "regex-2020.9.27-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9a02d0ae31d35e1ec12a4ea4d4cca990800f66a917d0fb997b20fbc13f5321fc"}, + {file = "regex-2020.9.27-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ebbe29186a3d9b0c591e71b7393f1ae08c83cb2d8e517d2a822b8f7ec99dfd8b"}, + {file = "regex-2020.9.27-cp36-cp36m-win32.whl", hash = "sha256:4707f3695b34335afdfb09be3802c87fa0bc27030471dbc082f815f23688bc63"}, + {file = "regex-2020.9.27-cp36-cp36m-win_amd64.whl", hash = "sha256:9bc13e0d20b97ffb07821aa3e113f9998e84994fe4d159ffa3d3a9d1b805043b"}, + {file = "regex-2020.9.27-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f1b3afc574a3db3b25c89161059d857bd4909a1269b0b3cb3c904677c8c4a3f7"}, + {file = "regex-2020.9.27-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5533a959a1748a5c042a6da71fe9267a908e21eded7a4f373efd23a2cbdb0ecc"}, + {file = "regex-2020.9.27-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:1fe0a41437bbd06063aa184c34804efa886bcc128222e9916310c92cd54c3b4c"}, + {file = "regex-2020.9.27-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c570f6fa14b9c4c8a4924aaad354652366577b4f98213cf76305067144f7b100"}, + {file = "regex-2020.9.27-cp37-cp37m-win32.whl", hash = "sha256:eda4771e0ace7f67f58bc5b560e27fb20f32a148cbc993b0c3835970935c2707"}, + {file = "regex-2020.9.27-cp37-cp37m-win_amd64.whl", hash = "sha256:60b0e9e6dc45683e569ec37c55ac20c582973841927a85f2d8a7d20ee80216ab"}, + {file = "regex-2020.9.27-cp38-cp38-manylinux1_i686.whl", hash = "sha256:088afc8c63e7bd187a3c70a94b9e50ab3f17e1d3f52a32750b5b77dbe99ef5ef"}, + {file = "regex-2020.9.27-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eaf548d117b6737df379fdd53bdde4f08870e66d7ea653e230477f071f861121"}, + {file = "regex-2020.9.27-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:41bb65f54bba392643557e617316d0d899ed5b4946dccee1cb6696152b29844b"}, + {file = "regex-2020.9.27-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:8d69cef61fa50c8133382e61fd97439de1ae623fe943578e477e76a9d9471637"}, + {file = "regex-2020.9.27-cp38-cp38-win32.whl", hash = "sha256:f2388013e68e750eaa16ccbea62d4130180c26abb1d8e5d584b9baf69672b30f"}, + {file = "regex-2020.9.27-cp38-cp38-win_amd64.whl", hash = "sha256:4318d56bccfe7d43e5addb272406ade7a2274da4b70eb15922a071c58ab0108c"}, + {file = "regex-2020.9.27-cp39-cp39-manylinux1_i686.whl", hash = "sha256:84cada8effefe9a9f53f9b0d2ba9b7b6f5edf8d2155f9fdbe34616e06ececf81"}, + {file = "regex-2020.9.27-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:816064fc915796ea1f26966163f6845de5af78923dfcecf6551e095f00983650"}, + {file = "regex-2020.9.27-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:5d892a4f1c999834eaa3c32bc9e8b976c5825116cde553928c4c8e7e48ebda67"}, + {file = "regex-2020.9.27-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c9443124c67b1515e4fe0bb0aa18df640965e1030f468a2a5dc2589b26d130ad"}, + {file = "regex-2020.9.27-cp39-cp39-win32.whl", hash = "sha256:49f23ebd5ac073765ecbcf046edc10d63dcab2f4ae2bce160982cb30df0c0302"}, + {file = "regex-2020.9.27-cp39-cp39-win_amd64.whl", hash = "sha256:3d20024a70b97b4f9546696cbf2fd30bae5f42229fbddf8661261b1eaff0deb7"}, + {file = "regex-2020.9.27.tar.gz", hash = "sha256:a6f32aea4260dfe0e55dc9733ea162ea38f0ea86aa7d0f77b15beac5bf7b369d"}, ] requests = [ - {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, - {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, ] rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, ] safety = [ - {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, - {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, + {file = "safety-1.10.0-py2.py3-none-any.whl", hash = "sha256:69437acf5dd617abd7086ccd0d50e813e67aa969bb9ca90f1847d5fbea047dcc"}, + {file = "safety-1.10.0.tar.gz", hash = "sha256:2ebc71b44666588d7898905d86d575933fcd5fa3c92d301ed12482602b1e928a"}, ] shellingham = [ - {file = "shellingham-1.4.0-py2.py3-none-any.whl", hash = "sha256:536b67a0697f2e4af32ab176c00a50ac2899c5a05e0d8e2dadac8e58888283f9"}, - {file = "shellingham-1.4.0.tar.gz", hash = "sha256:4855c2458d6904829bd34c299f11fdeed7cfefbf8a2c522e4caea6cd76b3171e"}, + {file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"}, + {file = "shellingham-1.3.2.tar.gz", hash = "sha256:576c1982bea0ba82fb46c36feb951319d7f42214a82634233f58b40d858a751e"}, ] six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] sniffio = [ - {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, - {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, + {file = "sniffio-1.1.0-py3-none-any.whl", hash = "sha256:20ed6d5b46f8ae136d00b9dcb807615d83ed82ceea6b2058cecb696765246da5"}, + {file = "sniffio-1.1.0.tar.gz", hash = "sha256:8e3810100f69fe0edd463d02ad407112542a11ffdc29f67db2bf3771afb87a21"}, ] stringcase = [ {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, ] taskipy = [ - {file = "taskipy-1.10.1-py3-none-any.whl", hash = "sha256:9b38333654da487b6d16de6fa330b7629d1935d1e74819ba4c5f17a1c372d37b"}, - {file = "taskipy-1.10.1.tar.gz", hash = "sha256:6fa0b11c43d103e376063e90be31d87b435aad50fb7dc1c9a2de9b60a85015ed"}, + {file = "taskipy-1.5.1-py3-none-any.whl", hash = "sha256:2cf0080a8a5b6eb182c26ce323412c8bd63ea5b3477bfb4d0407bb77924abd04"}, + {file = "taskipy-1.5.1.tar.gz", hash = "sha256:aa803322e6286e4ade8156366e0f846f79959447f4a9bcd7eac59c7705bd3f0d"}, ] toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"}, - {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, + {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, + {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, ] typed-ast = [ - {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, - {file = "typed_ast-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:676d051b1da67a852c0447621fdd11c4e104827417bf216092ec3e286f7da596"}, - {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc2542e83ac8399752bc16e0b35e038bdb659ba237f4222616b4e83fb9654985"}, - {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74cac86cc586db8dfda0ce65d8bcd2bf17b58668dfcc3652762f3ef0e6677e76"}, - {file = "typed_ast-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:18fe320f354d6f9ad3147859b6e16649a0781425268c4dde596093177660e71a"}, - {file = "typed_ast-1.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:31d8c6b2df19a777bc8826770b872a45a1f30cfefcfd729491baa5237faae837"}, - {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:963a0ccc9a4188524e6e6d39b12c9ca24cc2d45a71cfdd04a26d883c922b4b78"}, - {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e"}, - {file = "typed_ast-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:294a6903a4d087db805a7656989f613371915fc45c8cc0ddc5c5a0a8ad9bea4d"}, - {file = "typed_ast-1.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26a432dc219c6b6f38be20a958cbe1abffcc5492821d7e27f08606ef99e0dffd"}, - {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7407cfcad702f0b6c0e0f3e7ab876cd1d2c13b14ce770e412c0c4b9728a0f88"}, - {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f30ddd110634c2d7534b2d4e0e22967e88366b0d356b24de87419cc4410c41b7"}, - {file = "typed_ast-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8c08d6625bb258179b6e512f55ad20f9dfef019bbfbe3095247401e053a3ea30"}, - {file = "typed_ast-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:90904d889ab8e81a956f2c0935a523cc4e077c7847a836abee832f868d5c26a4"}, - {file = "typed_ast-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbebc31bf11762b63bf61aaae232becb41c5bf6b3461b80a4df7e791fabb3aca"}, - {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29dd9a3a9d259c9fa19d19738d021632d673f6ed9b35a739f48e5f807f264fb"}, - {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:58ae097a325e9bb7a684572d20eb3e1809802c5c9ec7108e85da1eb6c1a3331b"}, - {file = "typed_ast-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:da0a98d458010bf4fe535f2d1e367a2e2060e105978873c04c04212fb20543f7"}, - {file = "typed_ast-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33b4a19ddc9fc551ebabca9765d54d04600c4a50eda13893dadf67ed81d9a098"}, - {file = "typed_ast-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1098df9a0592dd4c8c0ccfc2e98931278a6c6c53cb3a3e2cf7e9ee3b06153344"}, - {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c47c3b43fe3a39ddf8de1d40dbbfca60ac8530a36c9b198ea5b9efac75c09e"}, - {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f290617f74a610849bd8f5514e34ae3d09eafd521dceaa6cf68b3f4414266d4e"}, - {file = "typed_ast-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:df05aa5b241e2e8045f5f4367a9f6187b09c4cdf8578bb219861c4e27c443db5"}, - {file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, + {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, + {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, ] typer = [ {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, ] typing-extensions = [ - {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, - {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, + {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, + {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, + {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, ] urllib3 = [ - {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, - {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, + {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, + {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, ] zipp = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, + {file = "zipp-3.3.0-py3-none-any.whl", hash = "sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"}, + {file = "zipp-3.3.0.tar.gz", hash = "sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b"}, ] From 53ba39c74a5b3f0f9fc7a20e442a8f7b19103ef9 Mon Sep 17 00:00:00 2001 From: miggyst Date: Tue, 5 Apr 2022 11:44:43 -0500 Subject: [PATCH 33/50] fix: Upgraded Jinja2 version to 3.x.x CEPLAT-477 (#113) * fix: Upgraded Jinja2 version to 3.x.x CEPLAT-477 * rebased and cleaned up poetry.lock --- poetry.lock | 167 +++++++++++++++---------------------------------- pyproject.toml | 4 +- setup.py | 2 +- 3 files changed, 53 insertions(+), 120 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0748d746d..a8397be29 100644 --- a/poetry.lock +++ b/poetry.lock @@ -50,7 +50,6 @@ python-versions = ">=3.6" [package.dependencies] appdirs = "*" click = ">=7.1.2" -dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} mypy-extensions = ">=0.4.3" pathspec = ">=0.6,<1" regex = ">=2020.1.8" @@ -94,17 +93,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[[package]] -name = "contextvars" -version = "2.4" -description = "PEP 567 Backport" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -immutables = ">=0.9" - [[package]] name = "coverage" version = "5.3" @@ -116,14 +104,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] toml = ["toml"] -[[package]] -name = "dataclasses" -version = "0.6" -description = "A backport of the dataclasses module for Python 3.6" -category = "main" -optional = false -python-versions = "*" - [[package]] name = "dparse" version = "0.5.1" @@ -203,14 +183,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[[package]] -name = "immutables" -version = "0.14" -description = "Immutable Collections" -category = "main" -optional = false -python-versions = ">=3.5" - [[package]] name = "importlib-metadata" version = "4.8.3" @@ -251,25 +223,25 @@ colors = ["colorama (>=0.4.3,<0.5.0)"] [[package]] name = "jinja2" -version = "2.11.2" +version = "3.1.1" description = "A very fast and expressive template engine." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] -MarkupSafe = ">=0.23" +MarkupSafe = ">=2.0" [package.extras] -i18n = ["Babel (>=0.8)"] +i18n = ["Babel (>=2.7)"] [[package]] name = "markupsafe" -version = "1.1.1" +version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +python-versions = ">=3.7" [[package]] name = "mccabe" @@ -380,9 +352,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.dependencies] -dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} - [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] @@ -563,9 +532,6 @@ category = "main" optional = false python-versions = ">=3.5" -[package.dependencies] -contextvars = {version = ">=2.1", markers = "python_version < \"3.7\""} - [[package]] name = "stringcase" version = "1.2.0" @@ -655,8 +621,8 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" -python-versions = "^3.6" -content-hash = "9ef9a5472b22d049a2d94a959d4e7b7c3cb120f1113fa47a38a78c555818002e" +python-versions = "^3.7" +content-hash = "7650dae573b617feba54f4b08abfcc25c3e07b9672e59a8e7f64a0a71016382d" [metadata.files] appdirs = [ @@ -693,9 +659,6 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] -contextvars = [ - {file = "contextvars-2.4.tar.gz", hash = "sha256:f38c908aaa59c14335eeea12abea5f443646216c4e29380d7bf34d2018e2c39e"}, -] coverage = [ {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, @@ -732,10 +695,6 @@ coverage = [ {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, ] -dataclasses = [ - {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, - {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, -] dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, @@ -760,20 +719,6 @@ idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] -immutables = [ - {file = "immutables-0.14-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:860666fab142401a5535bf65cbd607b46bc5ed25b9d1eb053ca8ed9a1a1a80d6"}, - {file = "immutables-0.14-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ce01788878827c3f0331c254a4ad8d9721489a5e65cc43e19c80040b46e0d297"}, - {file = "immutables-0.14-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8797eed4042f4626b0bc04d9cf134208918eb0c937a8193a2c66df5041e62d2e"}, - {file = "immutables-0.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:33ce2f977da7b5e0dddd93744862404bdb316ffe5853ec853e53141508fa2e6a"}, - {file = "immutables-0.14-cp36-cp36m-win_amd64.whl", hash = "sha256:6c8eace4d98988c72bcb37c05e79aae756832738305ae9497670482a82db08bc"}, - {file = "immutables-0.14-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:ab6c18b7b2b2abc83e0edc57b0a38bf0915b271582a1eb8c7bed1c20398f8040"}, - {file = "immutables-0.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c099212fd6504513a50e7369fe281007c820cf9d7bb22a336486c63d77d6f0b2"}, - {file = "immutables-0.14-cp37-cp37m-win_amd64.whl", hash = "sha256:714aedbdeba4439d91cb5e5735cb10631fc47a7a69ea9cc8ecbac90322d50a4a"}, - {file = "immutables-0.14-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:1c11050c49e193a1ec9dda1747285333f6ba6a30bbeb2929000b9b1192097ec0"}, - {file = "immutables-0.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c453e12b95e1d6bb4909e8743f88b7f5c0c97b86a8bc0d73507091cb644e3c1e"}, - {file = "immutables-0.14-cp38-cp38-win_amd64.whl", hash = "sha256:ef9da20ec0f1c5853b5c8f8e3d9e1e15b8d98c259de4b7515d789a606af8745e"}, - {file = "immutables-0.14.tar.gz", hash = "sha256:a0a1cc238b678455145bae291d8426f732f5255537ed6a5b7645949704c70a78"}, -] importlib-metadata = [ {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, {file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"}, @@ -787,62 +732,50 @@ isort = [ {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, ] jinja2 = [ - {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, - {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, + {file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, + {file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"}, ] markupsafe = [ - {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, - {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, diff --git a/pyproject.toml b/pyproject.toml index c4cb09773..241dd2a52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,8 +19,8 @@ packages = [ include = ["CHANGELOG.md", "openapi_python_client/py.typed"] [tool.poetry.dependencies] -python = "^3.6" -jinja2 = "^2.11.1" +python = "^3.7" +jinja2 = "^3.1.0" stringcase = "^1.2.0" typer = "^0.3" colorama = {version = "^0.4.3", markers = "sys_platform == 'win32'"} diff --git a/setup.py b/setup.py index c38ef4ea0..6dfdd9e1f 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ "black>=20.8b1", "httpx>=0.15.4,<0.17.0", "isort>=5.0.5,<6.0.0", - "jinja2>=2.11.1,<3.0.0", + "jinja2>=3.1.1,<4.0.0", "pydantic>=1.6.1,<2.0.0", "python-dateutil>=2.8.1,<3.0.0", "pyyaml>=5.3.1,<6.0.0", From c197208a2a2801a470f08cab2fb98c345b740758 Mon Sep 17 00:00:00 2001 From: Daniel Deutsch Date: Fri, 8 Apr 2022 15:00:09 -0400 Subject: [PATCH 34/50] chore: Loosen httpx dependency BNCH-38599 (#115) --- poetry.lock | 73 +++++++++++++++++++++++++++++++++++++++----------- pyproject.toml | 2 +- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/poetry.lock b/poetry.lock index a8397be29..f8f3ff211 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,21 @@ +[[package]] +name = "anyio" +version = "3.5.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] +test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=6.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] +trio = ["trio (>=0.16)"] + [[package]] name = "appdirs" version = "1.4.4" @@ -77,6 +95,17 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + [[package]] name = "click" version = "7.1.2" @@ -136,30 +165,33 @@ pyflakes = ">=2.2.0,<2.3.0" [[package]] name = "h11" -version = "0.9.0" +version = "0.12.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "httpcore" -version = "0.12.0" +version = "0.14.7" description = "A minimal low-level HTTP client." category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -h11 = "<1.0.0" +anyio = ">=3.0.0,<4.0.0" +certifi = "*" +h11 = ">=0.11,<0.13" sniffio = ">=1.0.0,<2.0.0" [package.extras] http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" -version = "0.16.1" +version = "0.22.0" description = "The next generation HTTP client." category = "main" optional = false @@ -167,13 +199,16 @@ python-versions = ">=3.6" [package.dependencies] certifi = "*" -httpcore = ">=0.12.0,<0.13.0" +charset-normalizer = "*" +httpcore = ">=0.14.5,<0.15.0" rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} sniffio = "*" [package.extras] -brotli = ["brotlipy (>=0.7.0,<0.8.0)"] -http2 = ["h2 (>=3.0.0,<4.0.0)"] +brotli = ["brotlicffi", "brotli"] +cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10.0.0,<11.0.0)", "pygments (>=2.0.0,<3.0.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "idna" @@ -622,9 +657,13 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "7650dae573b617feba54f4b08abfcc25c3e07b9672e59a8e7f64a0a71016382d" +content-hash = "465faade0fe4c4d54e69d3de573963a3515c8d057686b2847270956394f087f2" [metadata.files] +anyio = [ + {file = "anyio-3.5.0-py3-none-any.whl", hash = "sha256:b5fa16c5ff93fa1046f2eeb5bbff2dad4d3514d6cda61d02816dba34fa8c3c2e"}, + {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, +] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, @@ -651,6 +690,10 @@ chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, ] +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, +] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, @@ -704,16 +747,16 @@ flake8 = [ {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, ] h11 = [ - {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, - {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, + {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, + {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, ] httpcore = [ - {file = "httpcore-0.12.0-py3-none-any.whl", hash = "sha256:18c4afcbfe884b635e59739105aed1692e132bc5d31597109f3c1c97e4ec1cac"}, - {file = "httpcore-0.12.0.tar.gz", hash = "sha256:2526a38f31ac5967d38b7f593b5d8c4bd3fa82c21400402f866ba3312946acbf"}, + {file = "httpcore-0.14.7-py3-none-any.whl", hash = "sha256:47d772f754359e56dd9d892d9593b6f9870a37aeb8ba51e9a88b09b3d68cfade"}, + {file = "httpcore-0.14.7.tar.gz", hash = "sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"}, ] httpx = [ - {file = "httpx-0.16.1-py3-none-any.whl", hash = "sha256:9cffb8ba31fac6536f2c8cde30df859013f59e4bcc5b8d43901cb3654a8e0a5b"}, - {file = "httpx-0.16.1.tar.gz", hash = "sha256:126424c279c842738805974687e0518a94c7ae8d140cd65b9c4f77ac46ffa537"}, + {file = "httpx-0.22.0-py3-none-any.whl", hash = "sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"}, + {file = "httpx-0.22.0.tar.gz", hash = "sha256:d8e778f76d9bbd46af49e7f062467e3157a5a3d2ae4876a4bbfd8a51ed9c9cb4"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, diff --git a/pyproject.toml b/pyproject.toml index 241dd2a52..cad04c193 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ importlib_metadata = {version = ">=4.4", python = "<3.8"} pydantic = "^1.6.1" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.1" -httpx = ">=0.15.4,<0.17.0" +httpx = ">=0.15.4,<=0.22.0" autoflake = "^1.4" [tool.poetry.scripts] From a73037dd20bb522115e1f06f8132ba35de2242ae Mon Sep 17 00:00:00 2001 From: Daniel Deutsch Date: Fri, 8 Apr 2022 19:28:19 -0400 Subject: [PATCH 35/50] chore: Bump up httpx in template / generated pyproject.yaml BNCH-38599 (#116) --- openapi_python_client/templates/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_python_client/templates/pyproject.toml b/openapi_python_client/templates/pyproject.toml index 010e64bc5..fab9cbc8e 100644 --- a/openapi_python_client/templates/pyproject.toml +++ b/openapi_python_client/templates/pyproject.toml @@ -14,7 +14,7 @@ include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] [tool.poetry.dependencies] python = "^3.6" -httpx = "^0.15.0" +httpx = ">=0.15.4, <=0.22.0" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" From 5fe002cda290a35410499d14a0f74dc38c13d3bc Mon Sep 17 00:00:00 2001 From: Daniel Deutsch Date: Mon, 11 Apr 2022 12:06:13 -0400 Subject: [PATCH 36/50] chore: Bump up httpx in template / generated pyproject.yaml BNCH-38599 (#117) --- openapi_python_client/templates/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_python_client/templates/pyproject.toml b/openapi_python_client/templates/pyproject.toml index fab9cbc8e..33412b34b 100644 --- a/openapi_python_client/templates/pyproject.toml +++ b/openapi_python_client/templates/pyproject.toml @@ -14,7 +14,7 @@ include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] [tool.poetry.dependencies] python = "^3.6" -httpx = ">=0.15.4, <=0.22.0" +httpx = ">=0.15.0, <=0.22.0" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" From 97f39081089d7e6e46d715102b1cb838258fd5c8 Mon Sep 17 00:00:00 2001 From: miggyst Date: Fri, 22 Apr 2022 14:54:19 -0500 Subject: [PATCH 37/50] feat: Added support for text/yaml in OpenAPI to be used in benchling-api-client BNCH-37249 (#118) * feat: Added support for text/yaml in OpenAPI to be used in benchling-api-client BNCH-37249 * Fixed all tests * Added yaml parse * Added yaml body to mimic json object * Added logic for proper parsing * renamed yaml to be a json object on return package * Updated test for yaml parsing changes * Uses ruamel.yaml instead of yaml for parsing * Updated tests --- .../golden-record-custom/pyproject.toml | 4 +- end_to_end_tests/golden-record/pyproject.toml | 4 +- openapi_python_client/parser/openapi.py | 32 +++- openapi_python_client/parser/responses.py | 1 + .../templates/endpoint_macros.pyi | 18 +++ .../templates/endpoint_module.pyi | 9 +- .../property_templates/model_property.pyi | 6 + poetry.lock | 56 ++++++- pyproject.toml | 4 +- tests/test_parser/test_openapi.py | 41 ++++- .../test_parser/test_properties/test_init.py | 142 +++++++++++------- tests/test_parser/test_responses.py | 35 ++++- tests/test_templates/endpoint_module.py | 10 ++ tests/test_templates/test_endpoint_module.py | 3 + .../test_date_property/test_date_property.py | 3 + 15 files changed, 290 insertions(+), 78 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/pyproject.toml b/end_to_end_tests/golden-record-custom/pyproject.toml index 9f9f94914..09f4ff975 100644 --- a/end_to_end_tests/golden-record-custom/pyproject.toml +++ b/end_to_end_tests/golden-record-custom/pyproject.toml @@ -14,8 +14,8 @@ include = ["CHANGELOG.md", "custom_e2e/py.typed"] [tool.poetry.dependencies] python = "^3.6" -httpx = "^0.15.0" -attrs = "^20.1.0" +httpx = ">=0.15.0, <=0.22.0" +attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" [tool.black] diff --git a/end_to_end_tests/golden-record/pyproject.toml b/end_to_end_tests/golden-record/pyproject.toml index 6b7d0be67..9fa7ba3c0 100644 --- a/end_to_end_tests/golden-record/pyproject.toml +++ b/end_to_end_tests/golden-record/pyproject.toml @@ -14,8 +14,8 @@ include = ["CHANGELOG.md", "my_test_api_client/py.typed"] [tool.poetry.dependencies] python = "^3.6" -httpx = "^0.15.0" -attrs = "^20.1.0" +httpx = ">=0.15.0, <=0.22.0" +attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" [tool.black] diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index 3053ee305..a135b12cf 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -94,11 +94,29 @@ class Endpoint: path_parameters: List[Property] = field(default_factory=list) header_parameters: List[Property] = field(default_factory=list) responses: List[Response] = field(default_factory=list) + yaml_body: Optional[Property] = None form_body_reference: Optional[Reference] = None json_body: Optional[Property] = None multipart_body_reference: Optional[Reference] = None errors: List[ParseError] = field(default_factory=list) + @staticmethod + def parse_request_yaml_body( + *, body: oai.RequestBody, schemas: Schemas, parent_name: str + ) -> Tuple[Union[Property, PropertyError, None], Schemas]: + """ Return yaml_body """ + body_content = body.content + yaml_body = body_content.get("text/yaml") + if yaml_body is not None and yaml_body.media_type_schema is not None: + return property_from_data( + name="yaml_body", + required=True, + data=yaml_body.media_type_schema, + schemas=schemas, + parent_name=parent_name, + ) + return None, schemas + @staticmethod def parse_request_form_body(body: oai.RequestBody) -> Optional[Reference]: """ Return form_body_reference """ @@ -110,7 +128,7 @@ def parse_request_form_body(body: oai.RequestBody) -> Optional[Reference]: @staticmethod def parse_multipart_body(body: oai.RequestBody) -> Optional[Reference]: - """ Return form_body_reference """ + """ Return multipart_body_reference """ body_content = body.content json_body = body_content.get("multipart/form-data") if json_body is not None and isinstance(json_body.media_type_schema, oai.Reference): @@ -150,6 +168,12 @@ def _add_body( if isinstance(json_body, ParseError): return ParseError(detail=f"cannot parse body of endpoint {endpoint.name}", data=json_body.data), schemas + yaml_body, schemas = Endpoint.parse_request_yaml_body( + body=data.requestBody, schemas=schemas, parent_name=endpoint.name + ) + if isinstance(yaml_body, ParseError): + return ParseError(detail=f"cannot parse body of endpoint {endpoint.name}", data=yaml_body.data), schemas + endpoint.multipart_body_reference = Endpoint.parse_multipart_body(data.requestBody) if endpoint.form_body_reference: @@ -163,6 +187,10 @@ def _add_body( if json_body is not None: endpoint.json_body = json_body endpoint.relative_imports.update(endpoint.json_body.get_imports(prefix="...")) + if yaml_body is not None: + endpoint.yaml_body = yaml_body + endpoint.relative_imports.update(endpoint.yaml_body.get_imports(prefix="...")) + return endpoint, schemas @staticmethod @@ -177,7 +205,7 @@ def _add_responses(*, endpoint: "Endpoint", data: oai.Responses, schemas: Schema ParseError( detail=( f"Cannot parse response for status code {code}, " - f"response will be ommitted from generated client" + f"response will be omitted from generated client" ), data=response.data, ) diff --git a/openapi_python_client/parser/responses.py b/openapi_python_client/parser/responses.py index b59937cd8..88bcad16f 100644 --- a/openapi_python_client/parser/responses.py +++ b/openapi_python_client/parser/responses.py @@ -22,6 +22,7 @@ class Response: "application/json": "response.json()", "application/octet-stream": "response.content", "text/html": "response.text", + "text/yaml": "response.yaml", # Only used as an identifier, not the actual source } diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 6586ecd70..3103029bb 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -56,6 +56,17 @@ if {% if not property.required %}not isinstance({{ property_name }}, Unset) and {% endif %} {% endmacro %} +{% macro yaml_body(endpoint) %} +{% if endpoint.yaml_body %} + {% set property = endpoint.yaml_body %} + {% set destination = "yaml_" + property.python_name %} + {% if property.template %} + {% from "property_templates/" + property.template import transform %} +{{ transform(property, property.python_name, destination) }} + {% endif %} +{% endif %} +{% endmacro %} + {% macro return_type(endpoint) %} {% if endpoint.responses | length == 0 %} None @@ -83,6 +94,10 @@ client: Client, {% for parameter in endpoint.path_parameters %} {{ parameter.to_string() }}, {% endfor %} +{# Yaml body if any #} +{% if endpoint.yaml_body %} +yaml_body: {{ endpoint.yaml_body.get_type_string() }}, +{% endif %} {# Form data if any #} {% if endpoint.form_body_reference %} form_data: {{ endpoint.form_body_reference.class_name }}, @@ -110,6 +125,9 @@ client=client, {% for parameter in endpoint.path_parameters %} {{ parameter.python_name }}={{ parameter.python_name }}, {% endfor %} +{% if endpoint.yaml_body %} +yaml_body=yaml_body, +{% endif %} {% if endpoint.form_body_reference %} form_data=form_data, {% endif %} diff --git a/openapi_python_client/templates/endpoint_module.pyi b/openapi_python_client/templates/endpoint_module.pyi index 29dfadc46..b0a61c55e 100644 --- a/openapi_python_client/templates/endpoint_module.pyi +++ b/openapi_python_client/templates/endpoint_module.pyi @@ -2,6 +2,7 @@ from typing import Any, Dict, List, Optional, Union, cast import httpx from attr import asdict +from ruamel.yaml import YAML from ...client import AuthenticatedClient, Client from ...types import Response @@ -10,7 +11,7 @@ from ...types import Response {{ relative }} {% endfor %} -{% from "endpoint_macros.pyi" import header_params, query_params, json_body, return_type, arguments, client, kwargs, parse_response %} +{% from "endpoint_macros.pyi" import header_params, query_params, json_body, yaml_body, return_type, arguments, client, kwargs, parse_response %} {% set return_string = return_type(endpoint) %} {% set parsed_responses = (endpoint.responses | length > 0) and return_string != "None" %} @@ -33,6 +34,8 @@ def _get_kwargs( {{ json_body(endpoint) | indent(4) }} + {{ yaml_body(endpoint) | indent(4) }} + return { "url": url, "headers": headers, @@ -46,7 +49,9 @@ def _get_kwargs( {% endif %} {% if endpoint.json_body %} "json": {{ "json_" + endpoint.json_body.python_name }}, - {% endif %} + {%- elif endpoint.yaml_body %} + "json": {{ "yaml_" + endpoint.yaml_body.python_name }}, + {%- endif %} {% if endpoint.query_parameters %} "params": params, {% endif %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index 40a8a8b78..229823be9 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,6 +1,12 @@ {% macro construct(property, source, initial_value=None) %} {% if property.required and not property.nullable %} +{% if source == "response.yaml" %} +yaml = YAML(typ="base") +yaml_dict = yaml.load(response.text.encode('utf-8')) +{{ property.python_name }} = {{ property.reference.class_name }}.from_dict(yaml_dict) +{% else %} {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) +{% endif %} {% else %} {% if initial_value != None %} {{ property.python_name }} = {{ initial_value }} diff --git a/poetry.lock b/poetry.lock index f8f3ff211..4856bb4cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -529,6 +529,29 @@ idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} [package.extras] idna2008 = ["idna"] +[[package]] +name = "ruamel.yaml" +version = "0.17.21" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +category = "main" +optional = false +python-versions = ">=3" + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} + +[package.extras] +docs = ["ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel.yaml.clib" +version = "0.2.6" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "safety" version = "1.10.0" @@ -657,7 +680,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "465faade0fe4c4d54e69d3de573963a3515c8d057686b2847270956394f087f2" +content-hash = "b9beff0f1eb9aab0d72eb9c7a026d31c51ab58233dea92a640d45c24a2510ce8" [metadata.files] anyio = [ @@ -984,6 +1007,37 @@ rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, ] +"ruamel.yaml" = [ + {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, + {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, +] +"ruamel.yaml.clib" = [ + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, + {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, +] safety = [ {file = "safety-1.10.0-py2.py3-none-any.whl", hash = "sha256:69437acf5dd617abd7086ccd0d50e813e67aa969bb9ca90f1847d5fbea047dcc"}, {file = "safety-1.10.0.tar.gz", hash = "sha256:2ebc71b44666588d7898905d86d575933fcd5fa3c92d301ed12482602b1e928a"}, diff --git a/pyproject.toml b/pyproject.toml index cad04c193..0d3feda95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.1" httpx = ">=0.15.4,<=0.22.0" autoflake = "^1.4" +"ruamel.yaml" = "^0.17.21" [tool.poetry.scripts] openapi-python-client = "openapi_python_client.cli:app" @@ -57,7 +58,8 @@ isort .\ && mypy openapi_python_client\ && task unit\ """ -unit = "pytest --cov openapi_python_client tests --cov-report=term-missing" +code_coverage = "pytest --cov openapi_python_client tests --cov-report=term-missing" +unit = "pytest openapi_python_client tests" regen = "python -m end_to_end_tests.regen_golden_record" regen_custom = "python -m end_to_end_tests.regen_golden_record custom" e2e = "pytest openapi_python_client end_to_end_tests/test_end_to_end.py" diff --git a/tests/test_parser/test_openapi.py b/tests/test_parser/test_openapi.py index 33fdb4658..a3f7fab5b 100644 --- a/tests/test_parser/test_openapi.py +++ b/tests/test_parser/test_openapi.py @@ -66,6 +66,32 @@ def test_from_dict_invalid_schema(self, mocker): class TestEndpoint: + def test_parse_yaml_body(self, mocker): + from openapi_python_client.parser.openapi import Endpoint, Schemas + schema = mocker.MagicMock() + body = oai.RequestBody.construct( + content={"text/yaml": oai.MediaType.construct(media_type_schema=schema)} + ) + property_from_data = mocker.patch(f"{MODULE_NAME}.property_from_data") + schemas = Schemas() + + result = Endpoint.parse_request_yaml_body(body=body, schemas=schemas, parent_name="parent") + + property_from_data.assert_called_once_with( + name="yaml_body", required=True, data=schema, schemas=schemas, parent_name="parent" + ) + assert result == property_from_data.return_value + + def test_parse_yaml_body_no_data(self): + from openapi_python_client.parser.openapi import Endpoint, Schemas + + body = oai.RequestBody.construct(content={}) + schemas = Schemas() + + result = Endpoint.parse_request_yaml_body(body=body, schemas=schemas, parent_name="parent") + + assert result == (None, schemas) + def test_parse_request_form_body(self, mocker): ref = mocker.MagicMock() body = oai.RequestBody.construct( @@ -211,6 +237,12 @@ def test_add_body_happy(self, mocker): parse_request_json_body = mocker.patch.object( Endpoint, "parse_request_json_body", return_value=(json_body, parsed_schemas) ) + yaml_body = mocker.MagicMock(autospec=Property) + yaml_body_imports = mocker.MagicMock() + yaml_body.get_imports.return_value = {yaml_body_imports} + parse_request_yaml_body = mocker.patch.object( + Endpoint, "parse_request_yaml_body", return_value=(yaml_body, parsed_schemas) + ) import_string_from_reference = mocker.patch( f"{MODULE_NAME}.import_string_from_reference", side_effect=["import_1", "import_2"] ) @@ -233,6 +265,7 @@ def test_add_body_happy(self, mocker): assert response_schemas == parsed_schemas parse_request_form_body.assert_called_once_with(request_body) parse_request_json_body.assert_called_once_with(body=request_body, schemas=initial_schemas, parent_name="name") + parse_request_yaml_body.assert_called_once_with(body=request_body, schemas=parsed_schemas, parent_name="name") parse_multipart_body.assert_called_once_with(request_body) import_string_from_reference.assert_has_calls( [ @@ -240,8 +273,10 @@ def test_add_body_happy(self, mocker): mocker.call(multipart_body_reference, prefix="...models"), ] ) + yaml_body.get_imports.assert_called_once_with(prefix="...") json_body.get_imports.assert_called_once_with(prefix="...") - assert endpoint.relative_imports == {"import_1", "import_2", "import_3", json_body_imports} + assert endpoint.relative_imports == {"import_1", "import_2", "import_3", yaml_body_imports, json_body_imports} + assert endpoint.yaml_body == yaml_body assert endpoint.json_body == json_body assert endpoint.form_body_reference == form_body_reference assert endpoint.multipart_body_reference == multipart_body_reference @@ -312,12 +347,12 @@ def test__add_responses(self, mocker): response_1 = Response( status_code=200, source="source", - prop=DateTimeProperty(name="datetime", required=True, nullable=False, default=None), + prop=DateTimeProperty(name="datetime", required=True, nullable=False, default=None, description=None), ) response_2 = Response( status_code=404, source="source", - prop=DateProperty(name="date", required=True, nullable=False, default=None), + prop=DateProperty(name="date", required=True, nullable=False, default=None, description=None), ) response_from_data = mocker.patch( f"{MODULE_NAME}.response_from_data", side_effect=[(response_1, schemas_1), (response_2, schemas_2)] diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 9e856e26f..2c424007d 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -27,7 +27,7 @@ class TestProperty: (False, True, False, True, "TestType"), (False, True, True, False, "Optional[TestType]"), (False, True, True, True, "TestType"), - (True, False, False, False, "Union[Unset, None, TestType]"), + (True, False, False, False, "Union[Unset, TestType]"), (True, False, False, True, "TestType"), (True, False, True, False, "TestType"), (True, False, True, True, "TestType"), @@ -41,7 +41,7 @@ def test_get_type_string(self, mocker, query_parameter, nullable, required, no_o from openapi_python_client.parser.properties import Property mocker.patch.object(Property, "_type_string", "TestType") - p = Property(name="test", required=required, default=None, nullable=nullable) + p = Property(name="test", required=required, default=None, nullable=nullable, description=None) assert p.get_type_string(no_optional=no_optional, query_parameter=query_parameter) == expected @pytest.mark.parametrize( @@ -51,9 +51,9 @@ def test_get_type_string(self, mocker, query_parameter, nullable, required, no_o (False, None, True, "test: TestType"), (False, "Test", False, "test: Union[Unset, TestType] = Test"), (False, "Test", True, "test: TestType = Test"), - (True, None, False, "test: Union[Unset, None, TestType] = UNSET"), + (True, None, False, "test: Union[Unset, TestType] = UNSET"), (True, None, True, "test: TestType"), - (True, "Test", False, "test: Union[Unset, None, TestType] = Test"), + (True, "Test", False, "test: Union[Unset, TestType] = Test"), (True, "Test", True, "test: TestType = Test"), ], ) @@ -62,20 +62,20 @@ def test_to_string(self, mocker, query_parameter, default, required, expected): name = "test" mocker.patch.object(Property, "_type_string", "TestType") - p = Property(name=name, required=required, default=default, nullable=False) + p = Property(name=name, required=required, default=default, nullable=False, description=None) assert p.to_string(query_parameter=query_parameter) == expected def test_get_imports(self): from openapi_python_client.parser.properties import Property - p = Property(name="test", required=True, default=None, nullable=False) + p = Property(name="test", required=True, default=None, nullable=False, description=None) assert p.get_imports(prefix="") == set() - p = Property(name="test", required=False, default=None, nullable=False) + p = Property(name="test", required=False, default=None, nullable=False, description=None) assert p.get_imports(prefix="") == {"from types import UNSET, Unset", "from typing import Union"} - p = Property(name="test", required=False, default=None, nullable=True) + p = Property(name="test", required=False, default=None, nullable=True, description=None) assert p.get_imports(prefix="") == { "from types import UNSET, Unset", "from typing import Optional", @@ -87,19 +87,19 @@ class TestStringProperty: def test_get_type_string(self): from openapi_python_client.parser.properties import StringProperty - p = StringProperty(name="test", required=True, default=None, nullable=False) + p = StringProperty(name="test", required=True, default=None, nullable=False, description=None) base_type_string = f"str" assert p.get_type_string() == base_type_string - p = StringProperty(name="test", required=True, default=None, nullable=True) + p = StringProperty(name="test", required=True, default=None, nullable=True, description=None) assert p.get_type_string() == f"Optional[{base_type_string}]" - p = StringProperty(name="test", required=False, default=None, nullable=True) + p = StringProperty(name="test", required=False, default=None, nullable=True, description=None) assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" - p = StringProperty(name="test", required=False, default=None, nullable=False) + p = StringProperty(name="test", required=False, default=None, nullable=False, description=None) assert p.get_type_string() == f"Union[Unset, {base_type_string}]" @@ -107,14 +107,14 @@ class TestDateTimeProperty: def test_get_imports(self): from openapi_python_client.parser.properties import DateTimeProperty - p = DateTimeProperty(name="test", required=True, default=None, nullable=False) + p = DateTimeProperty(name="test", required=True, default=None, nullable=False, description=None) assert p.get_imports(prefix="...") == { "import datetime", "from typing import cast", "from dateutil.parser import isoparse", } - p = DateTimeProperty(name="test", required=False, default=None, nullable=False) + p = DateTimeProperty(name="test", required=False, default=None, nullable=False, description=None) assert p.get_imports(prefix="...") == { "import datetime", "from typing import cast", @@ -123,7 +123,7 @@ def test_get_imports(self): "from ...types import UNSET, Unset", } - p = DateTimeProperty(name="test", required=False, default=None, nullable=True) + p = DateTimeProperty(name="test", required=False, default=None, nullable=True, description=None) assert p.get_imports(prefix="...") == { "import datetime", "from typing import cast", @@ -138,14 +138,14 @@ class TestDateProperty: def test_get_imports(self): from openapi_python_client.parser.properties import DateProperty - p = DateProperty(name="test", required=True, default=None, nullable=False) + p = DateProperty(name="test", required=True, default=None, nullable=False, description=None) assert p.get_imports(prefix="...") == { "import datetime", "from typing import cast", "from dateutil.parser import isoparse", } - p = DateProperty(name="test", required=False, default=None, nullable=False) + p = DateProperty(name="test", required=False, default=None, nullable=False, description=None) assert p.get_imports(prefix="...") == { "import datetime", "from typing import cast", @@ -154,7 +154,7 @@ def test_get_imports(self): "from ...types import UNSET, Unset", } - p = DateProperty(name="test", required=False, default=None, nullable=True) + p = DateProperty(name="test", required=False, default=None, nullable=True, description=None) assert p.get_imports(prefix="...") == { "import datetime", "from typing import cast", @@ -170,13 +170,13 @@ def test_get_imports(self): from openapi_python_client.parser.properties import FileProperty prefix = "..." - p = FileProperty(name="test", required=True, default=None, nullable=False) + p = FileProperty(name="test", required=True, default=None, nullable=False, description=None) assert p.get_imports(prefix=prefix) == { "from io import BytesIO", "from ...types import File", } - p = FileProperty(name="test", required=False, default=None, nullable=False) + p = FileProperty(name="test", required=False, default=None, nullable=False, description=None) assert p.get_imports(prefix=prefix) == { "from io import BytesIO", "from ...types import File", @@ -184,7 +184,7 @@ def test_get_imports(self): "from ...types import UNSET, Unset", } - p = FileProperty(name="test", required=False, default=None, nullable=True) + p = FileProperty(name="test", required=False, default=None, nullable=True, description=None) assert p.get_imports(prefix=prefix) == { "from io import BytesIO", "from ...types import File", @@ -201,21 +201,21 @@ def test_get_type_string(self, mocker): inner_property = mocker.MagicMock() inner_type_string = mocker.MagicMock() inner_property.get_type_string.return_value = inner_type_string - p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=False) + p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=False, description=None) base_type_string = f"List[{inner_type_string}]" assert p.get_type_string() == base_type_string - p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=True) + p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=True, description=None) assert p.get_type_string() == f"Optional[{base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True) + p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True, description=None) assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False) + p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False, description=None) assert p.get_type_string() == f"Union[Unset, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string @@ -226,14 +226,14 @@ def test_get_type_imports(self, mocker): inner_import = mocker.MagicMock() inner_property.get_imports.return_value = {inner_import} prefix = "..." - p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=False) + p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=False, description=None) assert p.get_imports(prefix=prefix) == { inner_import, "from typing import cast, List", } - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False) + p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False, description=None) assert p.get_imports(prefix=prefix) == { inner_import, "from typing import cast, List", @@ -241,7 +241,7 @@ def test_get_type_imports(self, mocker): "from ...types import UNSET, Unset", } - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True) + p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True, description=None) assert p.get_imports(prefix=prefix) == { inner_import, "from typing import cast, List", @@ -255,22 +255,22 @@ class TestUnionProperty: @pytest.mark.parametrize( "query_parameter,nullable,required,no_optional,expected", [ - (False, False, False, False, "Union[Unset, inner_type_string_1, inner_type_string_2]"), - (False, False, False, True, "Union[inner_type_string_1, inner_type_string_2]"), - (False, False, True, False, "Union[inner_type_string_1, inner_type_string_2]"), - (False, False, True, True, "Union[inner_type_string_1, inner_type_string_2]"), - (False, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), - (False, True, False, True, "Union[inner_type_string_1, inner_type_string_2]"), - (False, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2]"), - (False, True, True, True, "Union[inner_type_string_1, inner_type_string_2]"), - (True, False, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), - (True, False, False, True, "Union[inner_type_string_1, inner_type_string_2]"), - (True, False, True, False, "Union[inner_type_string_1, inner_type_string_2]"), - (True, False, True, True, "Union[inner_type_string_1, inner_type_string_2]"), - (True, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2]"), - (True, True, False, True, "Union[inner_type_string_1, inner_type_string_2]"), - (True, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2]"), - (True, True, True, True, "Union[inner_type_string_1, inner_type_string_2]"), + (False, False, False, False, "Union[Unset, inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, False, False, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, False, True, False, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, False, True, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, True, False, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2, UnknownType]"), + (False, True, True, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, False, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, False, False, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, False, True, False, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, False, True, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, True, False, False, "Union[Unset, None, inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, True, False, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, True, True, False, "Union[None, inner_type_string_1, inner_type_string_2, UnknownType]"), + (True, True, True, True, "Union[inner_type_string_1, inner_type_string_2, UnknownType]"), ], ) def test_get_type_string(self, mocker, query_parameter, nullable, required, no_optional, expected): @@ -286,6 +286,9 @@ def test_get_type_string(self, mocker, query_parameter, nullable, required, no_o default=None, inner_properties=[inner_property_1, inner_property_2], nullable=nullable, + discriminator_property=None, + discriminator_mappings=None, + description=None, ) assert p.get_type_string(query_parameter=query_parameter, no_optional=no_optional) == expected @@ -306,6 +309,9 @@ def test_get_imports(self, mocker): default=None, inner_properties=[inner_property_1, inner_property_2], nullable=False, + description=None, + discriminator_mappings=None, + discriminator_property=None, ) assert p.get_imports(prefix=prefix) == { @@ -320,6 +326,9 @@ def test_get_imports(self, mocker): default=None, inner_properties=[inner_property_1, inner_property_2], nullable=False, + description=None, + discriminator_mappings=None, + discriminator_property=None, ) assert p.get_imports(prefix=prefix) == { inner_import_1, @@ -335,6 +344,9 @@ def test_get_imports(self, mocker): default=None, inner_properties=[inner_property_1, inner_property_2], nullable=True, + description=None, + discriminator_mappings=None, + discriminator_property=None, ) assert p.get_imports(prefix=prefix) == { inner_import_1, @@ -360,6 +372,7 @@ def test_get_type_string(self, mocker): nullable=False, reference=fake_reference, value_type=str, + description=None, ) base_type_string = f"MyTestEnum" @@ -374,6 +387,7 @@ def test_get_type_string(self, mocker): nullable=True, reference=fake_reference, value_type=str, + description=None, ) assert p.get_type_string() == f"Optional[{base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string @@ -386,6 +400,7 @@ def test_get_type_string(self, mocker): nullable=True, reference=fake_reference, value_type=str, + description=None, ) assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string @@ -398,6 +413,7 @@ def test_get_type_string(self, mocker): nullable=False, reference=fake_reference, value_type=str, + description=None, ) assert p.get_type_string() == f"Union[Unset, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string @@ -416,6 +432,7 @@ def test_get_imports(self, mocker): nullable=False, reference=fake_reference, value_type=str, + description=None, ) assert enum_property.get_imports(prefix=prefix) == { @@ -430,6 +447,7 @@ def test_get_imports(self, mocker): nullable=False, reference=fake_reference, value_type=str, + description=None, ) assert enum_property.get_imports(prefix=prefix) == { f"from {prefix}models.{fake_reference.module_name} import {fake_reference.class_name}", @@ -445,6 +463,7 @@ def test_get_imports(self, mocker): nullable=True, reference=fake_reference, value_type=str, + description=None, ) assert enum_property.get_imports(prefix=prefix) == { f"from {prefix}models.{fake_reference.module_name} import {fake_reference.class_name}", @@ -505,6 +524,7 @@ def test_property_from_data_str_enum(self, mocker): reference=Reference(class_name="ParentAnEnum", module_name="parent_an_enum"), value_type=str, default="ParentAnEnum.B", + description=None, ) assert schemas != new_schemas, "Provided Schemas was mutated" assert new_schemas.enums == { @@ -536,6 +556,7 @@ def test_property_from_data_int_enum(self, mocker): reference=Reference(class_name="ParentAnEnum", module_name="parent_an_enum"), value_type=int, default="ParentAnEnum.VALUE_3", + description=None, ) assert schemas != new_schemas, "Provided Schemas was mutated" assert new_schemas.enums == { @@ -556,6 +577,7 @@ def test_property_from_data_ref_enum(self): values={"A": "a"}, value_type=str, reference=Reference(class_name="MyEnum", module_name="my_enum"), + description=None, ) schemas = Schemas(enums={"MyEnum": existing_enum}) @@ -569,6 +591,7 @@ def test_property_from_data_ref_enum(self): values={"A": "a"}, value_type=str, reference=Reference(class_name="MyEnum", module_name="my_enum"), + description=None, ) assert schemas == new_schemas @@ -667,7 +690,7 @@ def test_property_from_data_simple_types(self, openapi_type, prop_type, python_t name=name, required=required, data=data, schemas=schemas, parent_name="parent" ) - assert p == prop_type(name=name, required=required, default=python_type(data.default), nullable=False) + assert p == prop_type(name=name, required=required, default=python_type(data.default), nullable=False, description=None) assert new_schemas == schemas # Test nullable values @@ -675,7 +698,7 @@ def test_property_from_data_simple_types(self, openapi_type, prop_type, python_t data.nullable = True p, _ = property_from_data(name=name, required=required, data=data, schemas=schemas, parent_name="parent") - assert p == prop_type(name=name, required=required, default=python_type(data.default), nullable=True) + assert p == prop_type(name=name, required=required, default=python_type(data.default), nullable=True, description=None) # Test bad default value data.default = "a" @@ -766,7 +789,7 @@ def test_property_from_data_no_valid_props_in_data(self): name="blah", required=True, data=data, schemas=schemas, parent_name="parent" ) - assert prop == NoneProperty(name="blah", required=True, nullable=False, default=None) + assert prop == NoneProperty(name="blah", required=True, nullable=False, default=None, description=None) assert new_schemas == schemas def test_property_from_data_validation_error(self, mocker): @@ -877,14 +900,17 @@ def test_property_from_data_union(self, mocker): p, s = property_from_data(name=name, required=required, data=data, schemas=Schemas(), parent_name="parent") - FloatProperty.assert_called_once_with(name=name, required=required, default=0.0, nullable=False) - IntProperty.assert_called_once_with(name=name, required=required, default=0, nullable=False) + FloatProperty.assert_called_once_with(name=name, required=required, default=0.0, nullable=False, description=None) + IntProperty.assert_called_once_with(name=name, required=required, default=0, nullable=False, description=None) UnionProperty.assert_called_once_with( name=name, required=required, default=None, inner_properties=[FloatProperty.return_value, IntProperty.return_value], nullable=False, + description=None, + discriminator_property=None, + discriminator_mappings={}, ) assert p == UnionProperty.return_value assert s == Schemas() @@ -914,7 +940,7 @@ def test__string_based_property_no_format(self): p = _string_based_property(name=name, required=required, data=data) - assert p == StringProperty(name=name, required=required, nullable=True, default="'\\\\\"hello world\\\\\"'") + assert p == StringProperty(name=name, required=required, nullable=True, default="'\\\\\"hello world\\\\\"'", description=None) data.pattern = "abcdef" data.nullable = False @@ -925,7 +951,7 @@ def test__string_based_property_no_format(self): data=data, ) assert p == StringProperty( - name=name, required=required, nullable=False, default="'\\\\\"hello world\\\\\"'", pattern="abcdef" + name=name, required=required, nullable=False, default="'\\\\\"hello world\\\\\"'", pattern="abcdef", description=None ) def test__string_based_property_datetime_format(self): @@ -940,7 +966,7 @@ def test__string_based_property_datetime_format(self): p = _string_based_property(name=name, required=required, data=data) assert p == DateTimeProperty( - name=name, required=required, nullable=True, default="isoparse('2020-11-06T12:00:00')" + name=name, required=required, nullable=True, default="isoparse('2020-11-06T12:00:00')", description=None ) # Test bad default @@ -957,7 +983,7 @@ def test__string_based_property_date_format(self): p = _string_based_property(name=name, required=required, data=data) - assert p == DateProperty(name=name, required=required, nullable=True, default="isoparse('2020-11-06').date()") + assert p == DateProperty(name=name, required=required, nullable=True, default="isoparse('2020-11-06').date()", description=None) # Test bad default data.default = "a" @@ -972,7 +998,7 @@ def test__string_based_property_binary_format(self): data = oai.Schema.construct(type="string", schema_format="binary", nullable=True, default="a") p = _string_based_property(name=name, required=required, data=data) - assert p == FileProperty(name=name, required=required, nullable=True, default=None) + assert p == FileProperty(name=name, required=required, nullable=True, default=None, description=None) def test__string_based_property_unsupported_format(self, mocker): from openapi_python_client.parser.properties import StringProperty, _string_based_property @@ -983,7 +1009,7 @@ def test__string_based_property_unsupported_format(self, mocker): p = _string_based_property(name=name, required=required, data=data) - assert p == StringProperty(name=name, required=required, nullable=True, default=None) + assert p == StringProperty(name=name, required=required, nullable=True, default=None, description=None) def test_build_schemas(mocker): @@ -1062,7 +1088,7 @@ def test_build_enums(mocker): (False, False), ( oai.Schema.construct(type="string"), - StringProperty(name="AdditionalProperty", required=True, nullable=False, default=None), + StringProperty(name="AdditionalProperty", required=True, nullable=False, default=None,description=None), ), ], ) @@ -1102,8 +1128,8 @@ def test_build_model_property(additional_properties_schema, expected_additional_ default=None, reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), references=[], - required_properties=[StringProperty(name="req", required=True, nullable=False, default=None)], - optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None)], + required_properties=[StringProperty(name="req", required=True, nullable=False, default=None, description=None)], + optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None, description=None)], description=data.description, relative_imports={ "from dateutil.parser import isoparse", diff --git a/tests/test_parser/test_responses.py b/tests/test_parser/test_responses.py index eb20fb338..cbefbf593 100644 --- a/tests/test_parser/test_responses.py +++ b/tests/test_parser/test_responses.py @@ -9,12 +9,12 @@ def test_response_from_data_no_content(): from openapi_python_client.parser.responses import Response, response_from_data response, schemas = response_from_data( - status_code=200, data=oai.Response.construct(description=""), schemas=Schemas(), parent_name="parent" + status_code=200, data=oai.Response.construct(description="description"), schemas=Schemas(), parent_name="parent" ) assert response == Response( status_code=200, - prop=NoneProperty(name="response_200", default=None, nullable=False, required=True), + prop=NoneProperty(name="response_200", default=None, nullable=False, required=True, description=None), source="None", ) @@ -22,7 +22,7 @@ def test_response_from_data_no_content(): def test_response_from_data_unsupported_content_type(): from openapi_python_client.parser.responses import response_from_data - data = oai.Response.construct(description="", content={"blah": None}) + data = oai.Response.construct(description="description", content={"blah": None}) response, schemas = response_from_data(status_code=200, data=data, schemas=Schemas(), parent_name="parent") assert response == ParseError(data=data, detail="Unsupported content_type {'blah': None}") @@ -33,10 +33,9 @@ def test_response_from_data_no_content_schema(): data = oai.Response.construct(description="", content={"application/json": oai.MediaType.construct()}) response, schemas = response_from_data(status_code=200, data=data, schemas=Schemas(), parent_name="parent") - assert response == Response( status_code=200, - prop=NoneProperty(name="response_200", default=None, nullable=False, required=True), + prop=NoneProperty(name="response_200", default=None, nullable=False, required=True, description=None), source="None", ) @@ -46,7 +45,7 @@ def test_response_from_data_property_error(mocker): property_from_data = mocker.patch.object(responses, "property_from_data", return_value=(PropertyError(), Schemas())) data = oai.Response.construct( - description="", content={"application/json": oai.MediaType.construct(media_type_schema="something")} + description="description", content={"application/json": oai.MediaType.construct(media_type_schema="something")} ) response, schemas = responses.response_from_data( status_code=400, data=data, schemas=Schemas(), parent_name="parent" @@ -61,7 +60,7 @@ def test_response_from_data_property_error(mocker): def test_response_from_data_property(mocker): from openapi_python_client.parser import responses - prop = StringProperty(name="prop", required=True, nullable=False, default=None) + prop = StringProperty(name="prop", required=True, nullable=False, default=None, description=None) property_from_data = mocker.patch.object(responses, "property_from_data", return_value=(prop, Schemas())) data = oai.Response.construct( description="", content={"application/json": oai.MediaType.construct(media_type_schema="something")} @@ -78,3 +77,25 @@ def test_response_from_data_property(mocker): property_from_data.assert_called_once_with( name="response_400", required=True, data="something", schemas=Schemas(), parent_name="parent" ) + + +def test_response_from_data_property_of_type_text_yaml(mocker): + from openapi_python_client.parser import responses + + prop = StringProperty(name="prop", required=True, nullable=False, default=None, description=None) + property_from_data = mocker.patch.object(responses, "property_from_data", return_value=(prop, Schemas())) + data = oai.Response.construct( + description="", content={"text/yaml": oai.MediaType.construct(media_type_schema="something")} + ) + response, schemas = responses.response_from_data( + status_code=400, data=data, schemas=Schemas(), parent_name="parent" + ) + + assert response == responses.Response( + status_code=400, + prop=prop, + source="response.yaml", + ) + property_from_data.assert_called_once_with( + name="response_400", required=True, data="something", schemas=Schemas(), parent_name="parent" + ) diff --git a/tests/test_templates/endpoint_module.py b/tests/test_templates/endpoint_module.py index def57a78f..84a7d13f9 100644 --- a/tests/test_templates/endpoint_module.py +++ b/tests/test_templates/endpoint_module.py @@ -2,6 +2,7 @@ import httpx from attr import asdict +from ruamel.yaml import YAML from ...client import AuthenticatedClient, Client from ...types import Response @@ -13,6 +14,7 @@ def _get_kwargs( *, client: AuthenticatedClient, + yaml_body: Json, form_data: FormBody, multipart_data: MultiPartBody, json_body: Json, @@ -54,12 +56,14 @@ def _build_response(*, response: httpx.Response) -> Response[Union[str, int]]: def sync_detailed( *, client: AuthenticatedClient, + yaml_body: Json, form_data: FormBody, multipart_data: MultiPartBody, json_body: Json, ) -> Response[Union[str, int]]: kwargs = _get_kwargs( client=client, + yaml_body=yaml_body, form_data=form_data, multipart_data=multipart_data, json_body=json_body, @@ -75,6 +79,7 @@ def sync_detailed( def sync( *, client: AuthenticatedClient, + yaml_body: Json, form_data: FormBody, multipart_data: MultiPartBody, json_body: Json, @@ -83,6 +88,7 @@ def sync( return sync_detailed( client=client, + yaml_body=yaml_body, form_data=form_data, multipart_data=multipart_data, json_body=json_body, @@ -92,12 +98,14 @@ def sync( async def asyncio_detailed( *, client: AuthenticatedClient, + yaml_body: Json, form_data: FormBody, multipart_data: MultiPartBody, json_body: Json, ) -> Response[Union[str, int]]: kwargs = _get_kwargs( client=client, + yaml_body=yaml_body, form_data=form_data, multipart_data=multipart_data, json_body=json_body, @@ -112,6 +120,7 @@ async def asyncio_detailed( async def asyncio( *, client: AuthenticatedClient, + yaml_body: Json, form_data: FormBody, multipart_data: MultiPartBody, json_body: Json, @@ -121,6 +130,7 @@ async def asyncio( return ( await asyncio_detailed( client=client, + yaml_body=yaml_body, form_data=form_data, multipart_data=multipart_data, json_body=json_body, diff --git a/tests/test_templates/test_endpoint_module.py b/tests/test_templates/test_endpoint_module.py index 082ca84b3..b15f5a973 100644 --- a/tests/test_templates/test_endpoint_module.py +++ b/tests/test_templates/test_endpoint_module.py @@ -20,6 +20,8 @@ def test_async_module(template, mocker): header_param.name = "headerParam" header_param.to_string.return_value = "header_param_1: str" + yaml_body = mocker.MagicMock(template=None, python_name="yaml_body") + yaml_body.get_type_string.return_value = "Json" form_body_reference = mocker.MagicMock(class_name="FormBody") multipart_body_reference = mocker.MagicMock(class_name="MultiPartBody") json_body = mocker.MagicMock(template=None, python_name="json_body") @@ -37,6 +39,7 @@ def test_async_module(template, mocker): requires_security=True, path_parameters=[], query_parameters=[], + yaml_body=yaml_body, form_body_reference=form_body_reference, multipart_body_reference=multipart_body_reference, json_body=json_body, diff --git a/tests/test_templates/test_property_templates/test_date_property/test_date_property.py b/tests/test_templates/test_property_templates/test_date_property/test_date_property.py index 3a8ad435f..5f6ee6921 100644 --- a/tests/test_templates/test_property_templates/test_date_property/test_date_property.py +++ b/tests/test_templates/test_property_templates/test_date_property/test_date_property.py @@ -11,6 +11,7 @@ def test_required_not_nullable(): required=True, nullable=False, default=None, + description=None, ) here = Path(__file__).parent templates_dir = here.parent.parent.parent.parent / "openapi_python_client" / "templates" @@ -33,6 +34,7 @@ def test_required_nullable(): required=True, nullable=True, default=None, + description=None, ) here = Path(__file__).parent templates_dir = here.parent.parent.parent.parent / "openapi_python_client" / "templates" @@ -55,6 +57,7 @@ def test_optional_nullable(): required=False, nullable=True, default=None, + description=None, ) here = Path(__file__).parent templates_dir = here.parent.parent.parent.parent / "openapi_python_client" / "templates" From 50ee7954c552527ebb3297c045ed308ce4085fcd Mon Sep 17 00:00:00 2001 From: miggyst Date: Thu, 28 Apr 2022 15:18:43 -0500 Subject: [PATCH 38/50] fix: Fixed parsing logic for yaml files to use PyYaml instead of ruamel.yaml BNCH-37249 (#120) --- .../templates/endpoint_module.pyi | 2 +- .../property_templates/model_property.pyi | 3 +- poetry.lock | 56 +------------------ pyproject.toml | 1 - tests/test_templates/endpoint_module.py | 2 +- 5 files changed, 4 insertions(+), 60 deletions(-) diff --git a/openapi_python_client/templates/endpoint_module.pyi b/openapi_python_client/templates/endpoint_module.pyi index b0a61c55e..5869a584a 100644 --- a/openapi_python_client/templates/endpoint_module.pyi +++ b/openapi_python_client/templates/endpoint_module.pyi @@ -2,7 +2,7 @@ from typing import Any, Dict, List, Optional, Union, cast import httpx from attr import asdict -from ruamel.yaml import YAML +import yaml from ...client import AuthenticatedClient, Client from ...types import Response diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index 229823be9..ee819f8a6 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,8 +1,7 @@ {% macro construct(property, source, initial_value=None) %} {% if property.required and not property.nullable %} {% if source == "response.yaml" %} -yaml = YAML(typ="base") -yaml_dict = yaml.load(response.text.encode('utf-8')) +yaml_dict = yaml.safe_load(response.text.encode("utf-8")) {{ property.python_name }} = {{ property.reference.class_name }}.from_dict(yaml_dict) {% else %} {{ property.python_name }} = {{ property.reference.class_name }}.from_dict({{ source }}) diff --git a/poetry.lock b/poetry.lock index 4856bb4cf..01f7422ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -529,29 +529,6 @@ idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} [package.extras] idna2008 = ["idna"] -[[package]] -name = "ruamel.yaml" -version = "0.17.21" -description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -category = "main" -optional = false -python-versions = ">=3" - -[package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} - -[package.extras] -docs = ["ryd"] -jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] - -[[package]] -name = "ruamel.yaml.clib" -version = "0.2.6" -description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -category = "main" -optional = false -python-versions = ">=3.5" - [[package]] name = "safety" version = "1.10.0" @@ -680,7 +657,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "b9beff0f1eb9aab0d72eb9c7a026d31c51ab58233dea92a640d45c24a2510ce8" +content-hash = "9e61dbf52e9e1cd125ba652572a3b18b8af996b3b724beb3ca3c39e51e35efb5" [metadata.files] anyio = [ @@ -1007,37 +984,6 @@ rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, ] -"ruamel.yaml" = [ - {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, - {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, -] -"ruamel.yaml.clib" = [ - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, - {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, -] safety = [ {file = "safety-1.10.0-py2.py3-none-any.whl", hash = "sha256:69437acf5dd617abd7086ccd0d50e813e67aa969bb9ca90f1847d5fbea047dcc"}, {file = "safety-1.10.0.tar.gz", hash = "sha256:2ebc71b44666588d7898905d86d575933fcd5fa3c92d301ed12482602b1e928a"}, diff --git a/pyproject.toml b/pyproject.toml index 0d3feda95..eca2a06b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,6 @@ attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.1" httpx = ">=0.15.4,<=0.22.0" autoflake = "^1.4" -"ruamel.yaml" = "^0.17.21" [tool.poetry.scripts] openapi-python-client = "openapi_python_client.cli:app" diff --git a/tests/test_templates/endpoint_module.py b/tests/test_templates/endpoint_module.py index 84a7d13f9..82cf93e9b 100644 --- a/tests/test_templates/endpoint_module.py +++ b/tests/test_templates/endpoint_module.py @@ -2,7 +2,7 @@ import httpx from attr import asdict -from ruamel.yaml import YAML +import yaml from ...client import AuthenticatedClient, Client from ...types import Response From c286ac95727c016a57ee6f8e9bfc2dc28e737ab5 Mon Sep 17 00:00:00 2001 From: miggyst Date: Thu, 19 May 2022 10:07:54 -0500 Subject: [PATCH 39/50] chore: Ran gen-setuppy to update openapi setup.py BNCH-42828 (#127) * chore: Ran gen-setuppy to update openapi setup.py BNCH-42828 * Updated readme * Added note on package version * Added a sed statement to update package name on build --- README.md | 12 ++++ openapi_python_client/parser/openapi.py | 2 +- .../parser/properties/__init__.py | 13 ++-- openapi_python_client/parser/responses.py | 2 +- .../templates/endpoint_module.pyi | 2 +- pyproject.toml | 7 ++- setup.py | 16 ++--- tests/test_parser/test_openapi.py | 5 +- .../test_parser/test_properties/test_init.py | 61 ++++++++++++++----- tests/test_templates/endpoint_module.py | 2 +- 10 files changed, 82 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 711c79f72..80f02dcfa 100644 --- a/README.md +++ b/README.md @@ -146,5 +146,17 @@ Example: package_version_override: 1.2.3 ``` +## How to publish changes +Quip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package) + +After changes are made to this package, to publish a new version of this package: +* Bump the version on pyproject.toml +* Install `gnu-sed` (assuming that you're running on a mac) by running `brew install gnu-sed` + * macOS uses BSD sed, which is similar to Linux's GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag +* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH +* Run `poetry run task gen-setuppy` which updates setup.py +* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish) + + [changelog.md]: CHANGELOG.md [poetry]: https://python-poetry.org/ diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index a135b12cf..993c3c94a 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -102,7 +102,7 @@ class Endpoint: @staticmethod def parse_request_yaml_body( - *, body: oai.RequestBody, schemas: Schemas, parent_name: str + *, body: oai.RequestBody, schemas: Schemas, parent_name: str ) -> Tuple[Union[Property, PropertyError, None], Schemas]: """ Return yaml_body """ body_content = body.content diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index b26c05f93..2176c9033 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -443,7 +443,7 @@ def build_union_property( sub_properties.append(sub_prop) if data.discriminator is not None: reference_name_to_subprop[sub_prop.reference.class_name] = sub_prop - + discriminator_mappings: Dict[str, Property] = {} if data.discriminator is not None: for k, v in (data.discriminator.mapping if data.discriminator else {}).items(): @@ -571,13 +571,10 @@ def _property_from_data( elif data.type == "object" or data.allOf: return build_model_property(data=data, name=name, schemas=schemas, required=required, parent_name=parent_name) elif not data.type: - return NoneProperty( - name=name, - required=required, - nullable=False, - default=None, - description=data.description - ), schemas + return ( + NoneProperty(name=name, required=required, nullable=False, default=None, description=data.description), + schemas, + ) return PropertyError(data=data, detail=f"unknown type {data.type}"), schemas diff --git a/openapi_python_client/parser/responses.py b/openapi_python_client/parser/responses.py index 88bcad16f..3fa203a51 100644 --- a/openapi_python_client/parser/responses.py +++ b/openapi_python_client/parser/responses.py @@ -22,7 +22,7 @@ class Response: "application/json": "response.json()", "application/octet-stream": "response.content", "text/html": "response.text", - "text/yaml": "response.yaml", # Only used as an identifier, not the actual source + "text/yaml": "response.yaml", # Only used as an identifier, not the actual source } diff --git a/openapi_python_client/templates/endpoint_module.pyi b/openapi_python_client/templates/endpoint_module.pyi index 5869a584a..fe64bc15c 100644 --- a/openapi_python_client/templates/endpoint_module.pyi +++ b/openapi_python_client/templates/endpoint_module.pyi @@ -1,8 +1,8 @@ from typing import Any, Dict, List, Optional, Union, cast import httpx -from attr import asdict import yaml +from attr import asdict from ...client import AuthenticatedClient, Client from ...types import Response diff --git a/pyproject.toml b/pyproject.toml index eca2a06b4..3fba4ee1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,8 @@ [tool.poetry] name = "openapi-python-client" -version = "0.7.3" +# Our versions have diverged and have no relation to upstream code changes +# Henceforth, openapi-python-package will be maintained internally +version = "1.0.0" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" @@ -71,7 +73,8 @@ gen-setuppy = """ poetry build \ && tar --strip-components=1 -xvf "$(ls -1 dist/*tar.gz | tail -1)" '*/setup.py' \ && isort setup.py \ -&& black setup.py +&& black setup.py \ +&& sed -i 's/"openapi-python-client"/"benchling-openapi-python-client"/' setup.py """ [tool.black] diff --git a/setup.py b/setup.py index 6dfdd9e1f..ef23ffcd0 100644 --- a/setup.py +++ b/setup.py @@ -12,12 +12,12 @@ package_data = {"": ["*"], "openapi_python_client.templates": ["property_templates/*"]} install_requires = [ - "attrs>=20.1.0,<21.0.0", + "attrs>=20.1.0,<22.0", "autoflake>=1.4,<2.0", "black>=20.8b1", - "httpx>=0.15.4,<0.17.0", + "httpx>=0.15.4,<=0.22.0", "isort>=5.0.5,<6.0.0", - "jinja2>=3.1.1,<4.0.0", + "jinja2>=3.1.0,<4.0.0", "pydantic>=1.6.1,<2.0.0", "python-dateutil>=2.8.1,<3.0.0", "pyyaml>=5.3.1,<6.0.0", @@ -27,17 +27,17 @@ ] extras_require = { - ':python_version < "3.8"': ["importlib_metadata>=2.0.0,<3.0.0"], + ':python_version < "3.8"': ["importlib_metadata>=4.4"], ':sys_platform == "win32"': ["colorama>=0.4.3,<0.5.0"], } entry_points = {"console_scripts": ["openapi-python-client = openapi_python_client.cli:app"]} setup_kwargs = { - "name": "openapi-python-client", - "version": "0.7.0", + "name": "benchling-openapi-python-client", + "version": "1.0.0", "description": "Generate modern Python clients from OpenAPI", - "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', + "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", "author_email": "danthony@triaxtec.com", "maintainer": None, @@ -48,7 +48,7 @@ "install_requires": install_requires, "extras_require": extras_require, "entry_points": entry_points, - "python_requires": ">=3.6,<4.0", + "python_requires": ">=3.7,<4.0", } diff --git a/tests/test_parser/test_openapi.py b/tests/test_parser/test_openapi.py index a3f7fab5b..619fbebee 100644 --- a/tests/test_parser/test_openapi.py +++ b/tests/test_parser/test_openapi.py @@ -68,10 +68,9 @@ def test_from_dict_invalid_schema(self, mocker): class TestEndpoint: def test_parse_yaml_body(self, mocker): from openapi_python_client.parser.openapi import Endpoint, Schemas + schema = mocker.MagicMock() - body = oai.RequestBody.construct( - content={"text/yaml": oai.MediaType.construct(media_type_schema=schema)} - ) + body = oai.RequestBody.construct(content={"text/yaml": oai.MediaType.construct(media_type_schema=schema)}) property_from_data = mocker.patch(f"{MODULE_NAME}.property_from_data") schemas = Schemas() diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 2c424007d..be3dc3ae1 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -201,21 +201,29 @@ def test_get_type_string(self, mocker): inner_property = mocker.MagicMock() inner_type_string = mocker.MagicMock() inner_property.get_type_string.return_value = inner_type_string - p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=False, description=None) + p = ListProperty( + name="test", required=True, default=None, inner_property=inner_property, nullable=False, description=None + ) base_type_string = f"List[{inner_type_string}]" assert p.get_type_string() == base_type_string - p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=True, description=None) + p = ListProperty( + name="test", required=True, default=None, inner_property=inner_property, nullable=True, description=None + ) assert p.get_type_string() == f"Optional[{base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True, description=None) + p = ListProperty( + name="test", required=False, default=None, inner_property=inner_property, nullable=True, description=None + ) assert p.get_type_string() == f"Union[Unset, None, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False, description=None) + p = ListProperty( + name="test", required=False, default=None, inner_property=inner_property, nullable=False, description=None + ) assert p.get_type_string() == f"Union[Unset, {base_type_string}]" assert p.get_type_string(no_optional=True) == base_type_string @@ -226,14 +234,18 @@ def test_get_type_imports(self, mocker): inner_import = mocker.MagicMock() inner_property.get_imports.return_value = {inner_import} prefix = "..." - p = ListProperty(name="test", required=True, default=None, inner_property=inner_property, nullable=False, description=None) + p = ListProperty( + name="test", required=True, default=None, inner_property=inner_property, nullable=False, description=None + ) assert p.get_imports(prefix=prefix) == { inner_import, "from typing import cast, List", } - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=False, description=None) + p = ListProperty( + name="test", required=False, default=None, inner_property=inner_property, nullable=False, description=None + ) assert p.get_imports(prefix=prefix) == { inner_import, "from typing import cast, List", @@ -241,7 +253,9 @@ def test_get_type_imports(self, mocker): "from ...types import UNSET, Unset", } - p = ListProperty(name="test", required=False, default=None, inner_property=inner_property, nullable=True, description=None) + p = ListProperty( + name="test", required=False, default=None, inner_property=inner_property, nullable=True, description=None + ) assert p.get_imports(prefix=prefix) == { inner_import, "from typing import cast, List", @@ -690,7 +704,9 @@ def test_property_from_data_simple_types(self, openapi_type, prop_type, python_t name=name, required=required, data=data, schemas=schemas, parent_name="parent" ) - assert p == prop_type(name=name, required=required, default=python_type(data.default), nullable=False, description=None) + assert p == prop_type( + name=name, required=required, default=python_type(data.default), nullable=False, description=None + ) assert new_schemas == schemas # Test nullable values @@ -698,7 +714,9 @@ def test_property_from_data_simple_types(self, openapi_type, prop_type, python_t data.nullable = True p, _ = property_from_data(name=name, required=required, data=data, schemas=schemas, parent_name="parent") - assert p == prop_type(name=name, required=required, default=python_type(data.default), nullable=True, description=None) + assert p == prop_type( + name=name, required=required, default=python_type(data.default), nullable=True, description=None + ) # Test bad default value data.default = "a" @@ -900,7 +918,9 @@ def test_property_from_data_union(self, mocker): p, s = property_from_data(name=name, required=required, data=data, schemas=Schemas(), parent_name="parent") - FloatProperty.assert_called_once_with(name=name, required=required, default=0.0, nullable=False, description=None) + FloatProperty.assert_called_once_with( + name=name, required=required, default=0.0, nullable=False, description=None + ) IntProperty.assert_called_once_with(name=name, required=required, default=0, nullable=False, description=None) UnionProperty.assert_called_once_with( name=name, @@ -940,7 +960,9 @@ def test__string_based_property_no_format(self): p = _string_based_property(name=name, required=required, data=data) - assert p == StringProperty(name=name, required=required, nullable=True, default="'\\\\\"hello world\\\\\"'", description=None) + assert p == StringProperty( + name=name, required=required, nullable=True, default="'\\\\\"hello world\\\\\"'", description=None + ) data.pattern = "abcdef" data.nullable = False @@ -951,7 +973,12 @@ def test__string_based_property_no_format(self): data=data, ) assert p == StringProperty( - name=name, required=required, nullable=False, default="'\\\\\"hello world\\\\\"'", pattern="abcdef", description=None + name=name, + required=required, + nullable=False, + default="'\\\\\"hello world\\\\\"'", + pattern="abcdef", + description=None, ) def test__string_based_property_datetime_format(self): @@ -983,7 +1010,9 @@ def test__string_based_property_date_format(self): p = _string_based_property(name=name, required=required, data=data) - assert p == DateProperty(name=name, required=required, nullable=True, default="isoparse('2020-11-06').date()", description=None) + assert p == DateProperty( + name=name, required=required, nullable=True, default="isoparse('2020-11-06').date()", description=None + ) # Test bad default data.default = "a" @@ -1088,7 +1117,7 @@ def test_build_enums(mocker): (False, False), ( oai.Schema.construct(type="string"), - StringProperty(name="AdditionalProperty", required=True, nullable=False, default=None,description=None), + StringProperty(name="AdditionalProperty", required=True, nullable=False, default=None, description=None), ), ], ) @@ -1129,7 +1158,9 @@ def test_build_model_property(additional_properties_schema, expected_additional_ reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), references=[], required_properties=[StringProperty(name="req", required=True, nullable=False, default=None, description=None)], - optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None, description=None)], + optional_properties=[ + DateTimeProperty(name="opt", required=False, nullable=False, default=None, description=None) + ], description=data.description, relative_imports={ "from dateutil.parser import isoparse", diff --git a/tests/test_templates/endpoint_module.py b/tests/test_templates/endpoint_module.py index 82cf93e9b..0d5c2096f 100644 --- a/tests/test_templates/endpoint_module.py +++ b/tests/test_templates/endpoint_module.py @@ -1,8 +1,8 @@ from typing import Any, Dict, List, Optional, Union, cast import httpx -from attr import asdict import yaml +from attr import asdict from ...client import AuthenticatedClient, Client from ...types import Response From 6606024baddc4264e830dc8b8c3d263bd71b75eb Mon Sep 17 00:00:00 2001 From: William Bowen Date: Wed, 7 Sep 2022 14:06:45 -0800 Subject: [PATCH 40/50] chore: Upgrade project dependencies for generated client BNCH-43401 (#137) --- .../templates/pyproject.toml | 6 +- poetry.lock | 712 +++++++----------- pyproject.toml | 4 +- 3 files changed, 279 insertions(+), 443 deletions(-) diff --git a/openapi_python_client/templates/pyproject.toml b/openapi_python_client/templates/pyproject.toml index 33412b34b..4513cea68 100644 --- a/openapi_python_client/templates/pyproject.toml +++ b/openapi_python_client/templates/pyproject.toml @@ -13,14 +13,14 @@ include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] [tool.poetry.dependencies] -python = "^3.6" -httpx = ">=0.15.0, <=0.22.0" +python = "^3.7" +httpx = ">=0.23.0" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" [tool.black] line-length = 120 -target_version = ['py36', 'py37', 'py38'] +target_version = ['py37', 'py38', 'py39'] exclude = ''' ( /( diff --git a/poetry.lock b/poetry.lock index 01f7422ae..6945e3a1d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,6 +1,6 @@ [[package]] name = "anyio" -version = "3.5.0" +version = "3.6.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" category = "main" optional = false @@ -13,7 +13,7 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] -test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=6.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] +test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] trio = ["trio (>=0.16)"] [[package]] @@ -24,84 +24,71 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "atomicwrites" -version = "1.4.0" -description = "Atomic file writes." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "attrs" -version = "20.3.0" +version = "21.4.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] [[package]] name = "autoflake" -version = "1.4" +version = "1.5.3" description = "Removes unused imports and unused variables" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] pyflakes = ">=1.1.0" +toml = ">=0.10.2" [[package]] name = "black" -version = "20.8b1" +version = "21.6b0" description = "The uncompromising code formatter." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.6.2" [package.dependencies] appdirs = "*" click = ">=7.1.2" mypy-extensions = ">=0.4.3" -pathspec = ">=0.6,<1" +pathspec = ">=0.8.1,<1" regex = ">=2020.1.8" toml = ">=0.10.1" -typed-ast = ">=1.4.0" -typing-extensions = ">=3.7.4" +typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] +python2 = ["typed-ast (>=1.4.2)"] +uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2020.6.20" +version = "2022.6.15" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false -python-versions = "*" - -[[package]] -name = "chardet" -version = "3.0.4" -description = "Universal encoding detector for Python 2 and 3" -category = "dev" -optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "charset-normalizer" -version = "2.0.12" +version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" +category = "dev" optional = false -python-versions = ">=3.5.0" +python-versions = ">=3.6.0" [package.extras] unicode_backport = ["unicodedata2"] @@ -116,7 +103,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.5" description = "Cross-platform colored terminal text." category = "main" optional = false @@ -124,18 +111,21 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "5.3" +version = "6.4.4" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.7" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] -toml = ["toml"] +toml = ["tomli"] [[package]] name = "dparse" -version = "0.5.1" +version = "0.5.2" description = "A parser for Python dependency files" category = "dev" optional = false @@ -143,25 +133,25 @@ python-versions = ">=3.5" [package.dependencies] packaging = "*" -pyyaml = "*" toml = "*" [package.extras] pipenv = ["pipenv"] +conda = ["pyyaml"] [[package]] name = "flake8" -version = "3.8.4" +version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.6.0a1,<2.7.0" -pyflakes = ">=2.2.0,<2.3.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "h11" @@ -173,11 +163,11 @@ python-versions = ">=3.6" [[package]] name = "httpcore" -version = "0.14.7" +version = "0.15.0" description = "A minimal low-level HTTP client." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] anyio = ">=3.0.0,<4.0.0" @@ -191,53 +181,52 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" -version = "0.22.0" +version = "0.23.0" description = "The next generation HTTP client." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] certifi = "*" -charset-normalizer = "*" -httpcore = ">=0.14.5,<0.15.0" +httpcore = ">=0.15.0,<0.16.0" rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} sniffio = "*" [package.extras] brotli = ["brotlicffi", "brotli"] -cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10.0.0,<11.0.0)", "pygments (>=2.0.0,<3.0.0)"] +cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10,<13)", "pygments (>=2.0.0,<3.0.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "idna" -version = "2.10" +version = "3.3" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.5" [[package]] name = "importlib-metadata" -version = "4.8.3" +version = "4.12.0" description = "Read metadata from Python packages" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" -version = "1.0.1" +version = "1.1.1" description = "iniconfig: brain-dead simple config-ini parsing" category = "dev" optional = false @@ -245,20 +234,21 @@ python-versions = "*" [[package]] name = "isort" -version = "5.6.4" +version = "5.10.1" description = "A Python utility / library to sort Python imports." category = "main" optional = false -python-versions = ">=3.6,<4.0" +python-versions = ">=3.6.1,<4.0" [package.extras] pipfile_deprecated_finder = ["pipreqs", "requirementslib"] requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] +plugins = ["setuptools"] [[package]] name = "jinja2" -version = "3.1.1" +version = "3.1.2" description = "A very fast and expressive template engine." category = "main" optional = false @@ -296,19 +286,22 @@ python-versions = ">=3.5" [[package]] name = "mypy" -version = "0.790" +version = "0.971" description = "Optional static typing for Python" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] -mypy-extensions = ">=0.4.3,<0.5.0" -typed-ast = ">=1.4.0,<1.5.0" -typing-extensions = ">=3.7.4" +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -320,60 +313,60 @@ python-versions = "*" [[package]] name = "packaging" -version = "20.4" +version = "21.3" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2" -six = "*" +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pathspec" -version = "0.8.0" +version = "0.10.1" description = "Utility library for gitignore style pattern matching of file paths." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "psutil" -version = "5.7.2" +version = "5.9.2" description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] -test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] +test = ["ipaddress", "mock", "enum34", "pywin32", "wmi"] [[package]] name = "py" -version = "1.9.0" +version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" -version = "2.6.0" +version = "2.7.0" description = "Python style guide checker" category = "dev" optional = false @@ -381,20 +374,22 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.7.3" -description = "Data validation and settings management using python 3.6 type hinting" +version = "1.10.2" +description = "Data validation and settings management using python type hints" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" + +[package.dependencies] +typing-extensions = ">=4.1.0" [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -typing_extensions = ["typing-extensions (>=3.7.2)"] [[package]] name = "pyflakes" -version = "2.2.0" +version = "2.3.1" description = "passive checker of Python programs" category = "main" optional = false @@ -402,56 +397,58 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" -version = "2.4.7" -description = "Python parsing module" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "dev" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.6.8" + +[package.extras] +diagrams = ["railroad-diagrams", "jinja2"] [[package]] name = "pytest" -version = "6.2.1" +version = "7.1.3" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0.0a1" +pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pytest-cov" -version = "2.10.1" +version = "3.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -coverage = ">=4.4" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] +testing = ["virtualenv", "pytest-xdist", "six", "process-tests", "hunter", "fields"] [[package]] name = "pytest-mock" -version = "3.4.0" +version = "3.8.2" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [package.dependencies] pytest = ">=5.0" @@ -461,7 +458,7 @@ dev = ["pre-commit", "tox", "pytest-asyncio"] [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -483,37 +480,37 @@ six = ">=1.4.0" [[package]] name = "pyyaml" -version = "5.3.1" +version = "5.4.1" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "regex" -version = "2020.9.27" +version = "2022.8.17" description = "Alternative regular expression module, to replace re." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "requests" -version = "2.24.0" +version = "2.28.1" description = "Python HTTP for Humans." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" -chardet = ">=3.0.2,<4" -idna = ">=2.5,<3" -urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<1.27" [package.extras] -security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rfc3986" @@ -531,7 +528,7 @@ idna2008 = ["idna"] [[package]] name = "safety" -version = "1.10.0" +version = "1.10.3" description = "Checks installed dependencies for known vulnerabilities." category = "dev" optional = false @@ -545,15 +542,15 @@ requests = "*" [[package]] name = "shellingham" -version = "1.3.2" +version = "1.5.0" description = "Tool to Detect Surrounding Shell" category = "main" optional = false -python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" +python-versions = ">=3.4" [[package]] name = "six" -version = "1.15.0" +version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false @@ -561,11 +558,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "sniffio" -version = "1.1.0" +version = "1.3.0" description = "Sniff out which async library your code is running under" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [[package]] name = "stringcase" @@ -577,32 +574,41 @@ python-versions = "*" [[package]] name = "taskipy" -version = "1.5.1" +version = "1.10.3" description = "tasks runner for python projects" category = "dev" optional = false python-versions = ">=3.6,<4.0" [package.dependencies] -mslex = ">=0.3.0,<0.4.0" +colorama = ">=0.4.4,<0.5.0" +mslex = {version = ">=0.3.0,<0.4.0", markers = "sys_platform == \"win32\""} psutil = ">=5.7.2,<6.0.0" -toml = ">=0.10.0,<0.11.0" +tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} [[package]] name = "toml" -version = "0.10.1" +version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" category = "main" optional = false -python-versions = "*" +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" [[package]] name = "typed-ast" -version = "1.4.1" +version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "typer" @@ -616,167 +622,105 @@ python-versions = ">=3.6" click = ">=7.1.1,<7.2.0" [package.extras] -test = ["pytest-xdist (>=1.32.0,<2.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "mypy (==0.782)", "black (>=19.10b0,<20.0b0)", "isort (>=5.0.6,<6.0.0)", "shellingham (>=1.3.0,<2.0.0)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "coverage (>=5.2,<6.0)"] -all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"] -dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)"] -doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown-include (>=0.5.1,<0.6.0)"] +test = ["isort (>=5.0.6,<6.0.0)", "black (>=19.10b0,<20.0b0)", "mypy (==0.782)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "coverage (>=5.2,<6.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest (>=4.4.0,<5.4.0)", "shellingham (>=1.3.0,<2.0.0)"] +doc = ["markdown-include (>=0.5.1,<0.6.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "mkdocs (>=1.1.2,<2.0.0)"] +dev = ["flake8 (>=3.8.3,<4.0.0)", "autoflake (>=1.3.1,<2.0.0)"] +all = ["shellingham (>=1.3.0,<2.0.0)", "colorama (>=0.4.3,<0.5.0)"] [[package]] name = "typing-extensions" -version = "3.7.4.3" -description = "Backported and Experimental Type Hints for Python 3.5+" +version = "4.3.0" +description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [[package]] name = "urllib3" -version = "1.25.10" +version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "zipp" -version = "3.3.0" +version = "3.8.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "9e61dbf52e9e1cd125ba652572a3b18b8af996b3b724beb3ca3c39e51e35efb5" +content-hash = "eae24c8ae9afd3a05a10b592b5ce2bb5c1769c26c9ea7038b69b4cdf92f946a0" [metadata.files] anyio = [ - {file = "anyio-3.5.0-py3-none-any.whl", hash = "sha256:b5fa16c5ff93fa1046f2eeb5bbff2dad4d3514d6cda61d02816dba34fa8c3c2e"}, - {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, + {file = "anyio-3.6.1-py3-none-any.whl", hash = "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"}, + {file = "anyio-3.6.1.tar.gz", hash = "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b"}, ] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] attrs = [ - {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, - {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, -] -autoflake = [ - {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, -] -black = [ - {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] +autoflake = [] +black = [] certifi = [ - {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, - {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, -] -chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, - {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, -] -click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, ] +charset-normalizer = [] +click = [] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, -] -coverage = [ - {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, - {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, - {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"}, - {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"}, - {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"}, - {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"}, - {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"}, - {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"}, - {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"}, - {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"}, - {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"}, - {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"}, - {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"}, - {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"}, - {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"}, - {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"}, - {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"}, - {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"}, - {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"}, - {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"}, - {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"}, - {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"}, - {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"}, - {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"}, - {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"}, - {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"}, - {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"}, - {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"}, - {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"}, - {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"}, - {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"}, - {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"}, - {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, - {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, -] -dparse = [ - {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, - {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] +coverage = [] +dparse = [] flake8 = [ - {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, - {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] h11 = [ {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, ] -httpcore = [ - {file = "httpcore-0.14.7-py3-none-any.whl", hash = "sha256:47d772f754359e56dd9d892d9593b6f9870a37aeb8ba51e9a88b09b3d68cfade"}, - {file = "httpcore-0.14.7.tar.gz", hash = "sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"}, -] -httpx = [ - {file = "httpx-0.22.0-py3-none-any.whl", hash = "sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"}, - {file = "httpx-0.22.0.tar.gz", hash = "sha256:d8e778f76d9bbd46af49e7f062467e3157a5a3d2ae4876a4bbfd8a51ed9c9cb4"}, -] +httpcore = [] +httpx = [] idna = [ - {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, - {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, - {file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"}, + {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"}, + {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"}, ] iniconfig = [ - {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, - {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] isort = [ - {file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"}, - {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] jinja2 = [ - {file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, - {file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"}, + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] markupsafe = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, @@ -828,235 +772,127 @@ mslex = [ {file = "mslex-0.3.0-py2.py3-none-any.whl", hash = "sha256:380cb14abf8fabf40e56df5c8b21a6d533dc5cbdcfe42406bbf08dda8f42e42a"}, {file = "mslex-0.3.0.tar.gz", hash = "sha256:4a1ac3f25025cad78ad2fe499dd16d42759f7a3801645399cce5c404415daa97"}, ] -mypy = [ - {file = "mypy-0.790-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:bd03b3cf666bff8d710d633d1c56ab7facbdc204d567715cb3b9f85c6e94f669"}, - {file = "mypy-0.790-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:2170492030f6faa537647d29945786d297e4862765f0b4ac5930ff62e300d802"}, - {file = "mypy-0.790-cp35-cp35m-win_amd64.whl", hash = "sha256:e86bdace26c5fe9cf8cb735e7cedfe7850ad92b327ac5d797c656717d2ca66de"}, - {file = "mypy-0.790-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e97e9c13d67fbe524be17e4d8025d51a7dca38f90de2e462243ab8ed8a9178d1"}, - {file = "mypy-0.790-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0d34d6b122597d48a36d6c59e35341f410d4abfa771d96d04ae2c468dd201abc"}, - {file = "mypy-0.790-cp36-cp36m-win_amd64.whl", hash = "sha256:72060bf64f290fb629bd4a67c707a66fd88ca26e413a91384b18db3876e57ed7"}, - {file = "mypy-0.790-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eea260feb1830a627fb526d22fbb426b750d9f5a47b624e8d5e7e004359b219c"}, - {file = "mypy-0.790-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c614194e01c85bb2e551c421397e49afb2872c88b5830e3554f0519f9fb1c178"}, - {file = "mypy-0.790-cp37-cp37m-win_amd64.whl", hash = "sha256:0a0d102247c16ce93c97066443d11e2d36e6cc2a32d8ccc1f705268970479324"}, - {file = "mypy-0.790-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4e7bf7f1214826cf7333627cb2547c0db7e3078723227820d0a2490f117a01"}, - {file = "mypy-0.790-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:af4e9ff1834e565f1baa74ccf7ae2564ae38c8df2a85b057af1dbbc958eb6666"}, - {file = "mypy-0.790-cp38-cp38-win_amd64.whl", hash = "sha256:da56dedcd7cd502ccd3c5dddc656cb36113dd793ad466e894574125945653cea"}, - {file = "mypy-0.790-py3-none-any.whl", hash = "sha256:2842d4fbd1b12ab422346376aad03ff5d0805b706102e475e962370f874a5122"}, - {file = "mypy-0.790.tar.gz", hash = "sha256:2b21ba45ad9ef2e2eb88ce4aeadd0112d0f5026418324176fd494a6824b74975"}, -] +mypy = [] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -packaging = [ - {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, - {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, -] -pathspec = [ - {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, - {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, -] +packaging = [] +pathspec = [] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, -] -psutil = [ - {file = "psutil-5.7.2-cp27-none-win32.whl", hash = "sha256:f2018461733b23f308c298653c8903d32aaad7873d25e1d228765e91ae42c3f2"}, - {file = "psutil-5.7.2-cp27-none-win_amd64.whl", hash = "sha256:66c18ca7680a31bf16ee22b1d21b6397869dda8059dbdb57d9f27efa6615f195"}, - {file = "psutil-5.7.2-cp35-cp35m-win32.whl", hash = "sha256:5e9d0f26d4194479a13d5f4b3798260c20cecf9ac9a461e718eb59ea520a360c"}, - {file = "psutil-5.7.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4080869ed93cce662905b029a1770fe89c98787e543fa7347f075ade761b19d6"}, - {file = "psutil-5.7.2-cp36-cp36m-win32.whl", hash = "sha256:d8a82162f23c53b8525cf5f14a355f5d1eea86fa8edde27287dd3a98399e4fdf"}, - {file = "psutil-5.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0ee3c36428f160d2d8fce3c583a0353e848abb7de9732c50cf3356dd49ad63f8"}, - {file = "psutil-5.7.2-cp37-cp37m-win32.whl", hash = "sha256:ff1977ba1a5f71f89166d5145c3da1cea89a0fdb044075a12c720ee9123ec818"}, - {file = "psutil-5.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a5b120bb3c0c71dfe27551f9da2f3209a8257a178ed6c628a819037a8df487f1"}, - {file = "psutil-5.7.2-cp38-cp38-win32.whl", hash = "sha256:10512b46c95b02842c225f58fa00385c08fa00c68bac7da2d9a58ebe2c517498"}, - {file = "psutil-5.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:68d36986ded5dac7c2dcd42f2682af1db80d4bce3faa126a6145c1637e1b559f"}, - {file = "psutil-5.7.2.tar.gz", hash = "sha256:90990af1c3c67195c44c9a889184f84f5b2320dce3ee3acbd054e3ba0b4a7beb"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] +psutil = [] py = [ - {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, - {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ - {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, - {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, -] -pydantic = [ - {file = "pydantic-1.7.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c59ea046aea25be14dc22d69c97bee629e6d48d2b2ecb724d7fe8806bf5f61cd"}, - {file = "pydantic-1.7.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a4143c8d0c456a093387b96e0f5ee941a950992904d88bc816b4f0e72c9a0009"}, - {file = "pydantic-1.7.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:d8df4b9090b595511906fa48deda47af04e7d092318bfb291f4d45dfb6bb2127"}, - {file = "pydantic-1.7.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:514b473d264671a5c672dfb28bdfe1bf1afd390f6b206aa2ec9fed7fc592c48e"}, - {file = "pydantic-1.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:dba5c1f0a3aeea5083e75db9660935da90216f8a81b6d68e67f54e135ed5eb23"}, - {file = "pydantic-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59e45f3b694b05a69032a0d603c32d453a23f0de80844fb14d55ab0c6c78ff2f"}, - {file = "pydantic-1.7.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:5b24e8a572e4b4c18f614004dda8c9f2c07328cb5b6e314d6e1bbd536cb1a6c1"}, - {file = "pydantic-1.7.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:b2b054d095b6431cdda2f852a6d2f0fdec77686b305c57961b4c5dd6d863bf3c"}, - {file = "pydantic-1.7.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:025bf13ce27990acc059d0c5be46f416fc9b293f45363b3d19855165fee1874f"}, - {file = "pydantic-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6e3874aa7e8babd37b40c4504e3a94cc2023696ced5a0500949f3347664ff8e2"}, - {file = "pydantic-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e682f6442ebe4e50cb5e1cfde7dda6766fb586631c3e5569f6aa1951fd1a76ef"}, - {file = "pydantic-1.7.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:185e18134bec5ef43351149fe34fda4758e53d05bb8ea4d5928f0720997b79ef"}, - {file = "pydantic-1.7.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:f5b06f5099e163295b8ff5b1b71132ecf5866cc6e7f586d78d7d3fd6e8084608"}, - {file = "pydantic-1.7.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:24ca47365be2a5a3cc3f4a26dcc755bcdc9f0036f55dcedbd55663662ba145ec"}, - {file = "pydantic-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:d1fe3f0df8ac0f3a9792666c69a7cd70530f329036426d06b4f899c025aca74e"}, - {file = "pydantic-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f6864844b039805add62ebe8a8c676286340ba0c6d043ae5dea24114b82a319e"}, - {file = "pydantic-1.7.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ecb54491f98544c12c66ff3d15e701612fc388161fd455242447083350904730"}, - {file = "pydantic-1.7.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:ffd180ebd5dd2a9ac0da4e8b995c9c99e7c74c31f985ba090ee01d681b1c4b95"}, - {file = "pydantic-1.7.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8d72e814c7821125b16f1553124d12faba88e85405b0864328899aceaad7282b"}, - {file = "pydantic-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:475f2fa134cf272d6631072554f845d0630907fce053926ff634cc6bc45bf1af"}, - {file = "pydantic-1.7.3-py3-none-any.whl", hash = "sha256:38be427ea01a78206bcaf9a56f835784afcba9e5b88fbdce33bbbfbcd7841229"}, - {file = "pydantic-1.7.3.tar.gz", hash = "sha256:213125b7e9e64713d16d988d10997dabc6a1f73f3991e1ff8e35ebb1409c7dc9"}, + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, ] +pydantic = [] pyflakes = [ - {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, - {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pyparsing = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, -] -pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, -] -pytest-cov = [ - {file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"}, - {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, -] -pytest-mock = [ - {file = "pytest-mock-3.4.0.tar.gz", hash = "sha256:c3981f5edee6c4d1942250a60d9b39d38d5585398de1bfce057f925bdda720f4"}, - {file = "pytest_mock-3.4.0-py3-none-any.whl", hash = "sha256:c0fc979afac4aaba545cbd01e9c20736eb3fefb0a066558764b07d3de8f04ed3"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] +pytest = [] +pytest-cov = [] +pytest-mock = [] python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, -] -python-multipart = [ - {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] +python-multipart = [] pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, - {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, -] -regex = [ - {file = "regex-2020.9.27-cp27-cp27m-win32.whl", hash = "sha256:d23a18037313714fb3bb5a94434d3151ee4300bae631894b1ac08111abeaa4a3"}, - {file = "regex-2020.9.27-cp27-cp27m-win_amd64.whl", hash = "sha256:84e9407db1b2eb368b7ecc283121b5e592c9aaedbe8c78b1a2f1102eb2e21d19"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f18875ac23d9aa2f060838e8b79093e8bb2313dbaaa9f54c6d8e52a5df097be"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ae91972f8ac958039920ef6e8769277c084971a142ce2b660691793ae44aae6b"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9a02d0ae31d35e1ec12a4ea4d4cca990800f66a917d0fb997b20fbc13f5321fc"}, - {file = "regex-2020.9.27-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ebbe29186a3d9b0c591e71b7393f1ae08c83cb2d8e517d2a822b8f7ec99dfd8b"}, - {file = "regex-2020.9.27-cp36-cp36m-win32.whl", hash = "sha256:4707f3695b34335afdfb09be3802c87fa0bc27030471dbc082f815f23688bc63"}, - {file = "regex-2020.9.27-cp36-cp36m-win_amd64.whl", hash = "sha256:9bc13e0d20b97ffb07821aa3e113f9998e84994fe4d159ffa3d3a9d1b805043b"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f1b3afc574a3db3b25c89161059d857bd4909a1269b0b3cb3c904677c8c4a3f7"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5533a959a1748a5c042a6da71fe9267a908e21eded7a4f373efd23a2cbdb0ecc"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:1fe0a41437bbd06063aa184c34804efa886bcc128222e9916310c92cd54c3b4c"}, - {file = "regex-2020.9.27-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c570f6fa14b9c4c8a4924aaad354652366577b4f98213cf76305067144f7b100"}, - {file = "regex-2020.9.27-cp37-cp37m-win32.whl", hash = "sha256:eda4771e0ace7f67f58bc5b560e27fb20f32a148cbc993b0c3835970935c2707"}, - {file = "regex-2020.9.27-cp37-cp37m-win_amd64.whl", hash = "sha256:60b0e9e6dc45683e569ec37c55ac20c582973841927a85f2d8a7d20ee80216ab"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux1_i686.whl", hash = "sha256:088afc8c63e7bd187a3c70a94b9e50ab3f17e1d3f52a32750b5b77dbe99ef5ef"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eaf548d117b6737df379fdd53bdde4f08870e66d7ea653e230477f071f861121"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:41bb65f54bba392643557e617316d0d899ed5b4946dccee1cb6696152b29844b"}, - {file = "regex-2020.9.27-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:8d69cef61fa50c8133382e61fd97439de1ae623fe943578e477e76a9d9471637"}, - {file = "regex-2020.9.27-cp38-cp38-win32.whl", hash = "sha256:f2388013e68e750eaa16ccbea62d4130180c26abb1d8e5d584b9baf69672b30f"}, - {file = "regex-2020.9.27-cp38-cp38-win_amd64.whl", hash = "sha256:4318d56bccfe7d43e5addb272406ade7a2274da4b70eb15922a071c58ab0108c"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux1_i686.whl", hash = "sha256:84cada8effefe9a9f53f9b0d2ba9b7b6f5edf8d2155f9fdbe34616e06ececf81"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:816064fc915796ea1f26966163f6845de5af78923dfcecf6551e095f00983650"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:5d892a4f1c999834eaa3c32bc9e8b976c5825116cde553928c4c8e7e48ebda67"}, - {file = "regex-2020.9.27-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c9443124c67b1515e4fe0bb0aa18df640965e1030f468a2a5dc2589b26d130ad"}, - {file = "regex-2020.9.27-cp39-cp39-win32.whl", hash = "sha256:49f23ebd5ac073765ecbcf046edc10d63dcab2f4ae2bce160982cb30df0c0302"}, - {file = "regex-2020.9.27-cp39-cp39-win_amd64.whl", hash = "sha256:3d20024a70b97b4f9546696cbf2fd30bae5f42229fbddf8661261b1eaff0deb7"}, - {file = "regex-2020.9.27.tar.gz", hash = "sha256:a6f32aea4260dfe0e55dc9733ea162ea38f0ea86aa7d0f77b15beac5bf7b369d"}, -] + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, +] +regex = [] requests = [ - {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, - {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, ] -safety = [ - {file = "safety-1.10.0-py2.py3-none-any.whl", hash = "sha256:69437acf5dd617abd7086ccd0d50e813e67aa969bb9ca90f1847d5fbea047dcc"}, - {file = "safety-1.10.0.tar.gz", hash = "sha256:2ebc71b44666588d7898905d86d575933fcd5fa3c92d301ed12482602b1e928a"}, -] -shellingham = [ - {file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"}, - {file = "shellingham-1.3.2.tar.gz", hash = "sha256:576c1982bea0ba82fb46c36feb951319d7f42214a82634233f58b40d858a751e"}, -] +safety = [] +shellingham = [] six = [ - {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, - {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, -] -sniffio = [ - {file = "sniffio-1.1.0-py3-none-any.whl", hash = "sha256:20ed6d5b46f8ae136d00b9dcb807615d83ed82ceea6b2058cecb696765246da5"}, - {file = "sniffio-1.1.0.tar.gz", hash = "sha256:8e3810100f69fe0edd463d02ad407112542a11ffdc29f67db2bf3771afb87a21"}, -] -stringcase = [ - {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, -] -taskipy = [ - {file = "taskipy-1.5.1-py3-none-any.whl", hash = "sha256:2cf0080a8a5b6eb182c26ce323412c8bd63ea5b3477bfb4d0407bb77924abd04"}, - {file = "taskipy-1.5.1.tar.gz", hash = "sha256:aa803322e6286e4ade8156366e0f846f79959447f4a9bcd7eac59c7705bd3f0d"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +sniffio = [] +stringcase = [] +taskipy = [] toml = [ - {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, - {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, -] -typed-ast = [ - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, - {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, - {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, - {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, - {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, - {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, - {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, - {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, - {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, -] -typer = [ - {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, - {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -typing-extensions = [ - {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, - {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, - {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, -] -urllib3 = [ - {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, - {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, -] -zipp = [ - {file = "zipp-3.3.0-py3-none-any.whl", hash = "sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"}, - {file = "zipp-3.3.0.tar.gz", hash = "sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b"}, +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +typed-ast = [ + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, +] +typer = [] +typing-extensions = [] +urllib3 = [] +zipp = [] diff --git a/pyproject.toml b/pyproject.toml index 3fba4ee1b..1dae230a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "openapi-python-client" # Our versions have diverged and have no relation to upstream code changes # Henceforth, openapi-python-package will be maintained internally -version = "1.0.0" +version = "1.0.1" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" @@ -34,7 +34,7 @@ importlib_metadata = {version = ">=4.4", python = "<3.8"} pydantic = "^1.6.1" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.1" -httpx = ">=0.15.4,<=0.22.0" +httpx = ">=0.23.0" autoflake = "^1.4" [tool.poetry.scripts] From 8cfef6567baded48fe8876b2508732bafc91c0e1 Mon Sep 17 00:00:00 2001 From: William Bowen Date: Wed, 7 Sep 2022 16:13:22 -0800 Subject: [PATCH 41/50] chore: Update setup.py with new version info for publishing BNCH-43401 (#140) --- setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index ef23ffcd0..42f8345e9 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ "attrs>=20.1.0,<22.0", "autoflake>=1.4,<2.0", "black>=20.8b1", - "httpx>=0.15.4,<=0.22.0", + "httpx>=0.23.0", "isort>=5.0.5,<6.0.0", "jinja2>=3.1.0,<4.0.0", "pydantic>=1.6.1,<2.0.0", @@ -34,8 +34,8 @@ entry_points = {"console_scripts": ["openapi-python-client = openapi_python_client.cli:app"]} setup_kwargs = { - "name": "benchling-openapi-python-client", - "version": "1.0.0", + "name": "openapi-python-client", + "version": "1.0.1", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", From 4fdbe269cab9b4d7581d200046d9f50cd0ad5bbc Mon Sep 17 00:00:00 2001 From: William Bowen Date: Wed, 7 Sep 2022 17:34:24 -0800 Subject: [PATCH 42/50] chore: Fix sed expression and restore setup.py package name BNCH-43401 (#141) --- pyproject.toml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1dae230a9..aaad8bced 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ poetry build \ && tar --strip-components=1 -xvf "$(ls -1 dist/*tar.gz | tail -1)" '*/setup.py' \ && isort setup.py \ && black setup.py \ -&& sed -i 's/"openapi-python-client"/"benchling-openapi-python-client"/' setup.py +&& sed -i '' 's/"openapi-python-client"/"benchling-openapi-python-client"/' setup.py """ [tool.black] diff --git a/setup.py b/setup.py index 42f8345e9..34eaa2773 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ entry_points = {"console_scripts": ["openapi-python-client = openapi_python_client.cli:app"]} setup_kwargs = { - "name": "openapi-python-client", + "name": "benchling-openapi-python-client", "version": "1.0.1", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', From 351b9fed233b69ab188b4415b6ee16d777304849 Mon Sep 17 00:00:00 2001 From: William Bowen Date: Fri, 9 Sep 2022 11:40:06 -0800 Subject: [PATCH 43/50] chore: Revert Python version changes to attempt to fix packaging issue BNCH-43401 (#142) --- openapi_python_client/templates/pyproject.toml | 4 ++-- pyproject.toml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openapi_python_client/templates/pyproject.toml b/openapi_python_client/templates/pyproject.toml index 4513cea68..1766d26a5 100644 --- a/openapi_python_client/templates/pyproject.toml +++ b/openapi_python_client/templates/pyproject.toml @@ -13,14 +13,14 @@ include = ["CHANGELOG.md", "{{ package_name }}/py.typed"] [tool.poetry.dependencies] -python = "^3.7" +python = "^3.6" httpx = ">=0.23.0" attrs = ">=20.1.0, <22.0" python-dateutil = "^2.8.0" [tool.black] line-length = 120 -target_version = ['py37', 'py38', 'py39'] +target_version = ['py36', 'py37', 'py38'] exclude = ''' ( /( diff --git a/pyproject.toml b/pyproject.toml index aaad8bced..2fdb88f95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "openapi-python-client" # Our versions have diverged and have no relation to upstream code changes # Henceforth, openapi-python-package will be maintained internally -version = "1.0.1" +version = "1.0.2" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" diff --git a/setup.py b/setup.py index 34eaa2773..918c2f6f2 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup_kwargs = { "name": "benchling-openapi-python-client", - "version": "1.0.1", + "version": "1.0.2", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", From 46e4d85a6191b00b175dc41b64e592a6eae70669 Mon Sep 17 00:00:00 2001 From: William Bowen Date: Tue, 13 Sep 2022 13:07:29 -0800 Subject: [PATCH 44/50] fix: Allow __version__ to be ignored for package mismatch BNCH-43401 (#144) --- openapi_python_client/__init__.py | 8 +++++++- pyproject.toml | 2 +- setup.py | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index 152bce66e..c6f1b884a 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -22,7 +22,13 @@ else: from importlib.metadata import version # type: ignore -__version__ = version(__package__) + +# Benchling renames the package to avoid publishing naming collision +# This can lead to importlib.metadata.PackageNotFoundError: openapi_python_client +try: + __version__ = version(__package__) +except Exception: + pass TEMPLATE_FILTERS = { diff --git a/pyproject.toml b/pyproject.toml index 2fdb88f95..57b01d851 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "openapi-python-client" # Our versions have diverged and have no relation to upstream code changes # Henceforth, openapi-python-package will be maintained internally -version = "1.0.2" +version = "1.0.3" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" diff --git a/setup.py b/setup.py index 918c2f6f2..f801cd654 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup_kwargs = { "name": "benchling-openapi-python-client", - "version": "1.0.2", + "version": "1.0.3", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", From cebe643104df3279d2b73d67f3513bf0a4d67e87 Mon Sep 17 00:00:00 2001 From: Steve Strassmann Date: Thu, 6 Oct 2022 17:11:04 -0400 Subject: [PATCH 45/50] Feat/detect discriminator bnch 49688 (#143) * add discriminator * initialize discriminator mappings * getter for discriminator python_name * remove unused method * fix discriminator.mapping null case * more inline discriminator properties * add discriminator_property.pyi * move discriminator property over to aurelia * handle unknowntype for discriminator properties * walk oneOf as well as anyOf references * add parsing of toplevel UnionProperty * support toplevel unionProperty * add nested parameter to construct macro --- openapi_python_client/.flake8 | 3 ++ openapi_python_client/__init__.py | 16 +++++++--- .../parser/properties/__init__.py | 32 +++++++++++++++++-- .../parser/properties/model_property.py | 19 +++++++++-- .../property_templates/date_property.pyi | 2 +- .../property_templates/datetime_property.pyi | 2 +- .../property_templates/dict_property.pyi | 2 +- .../property_templates/enum_property.pyi | 2 +- .../property_templates/file_property.pyi | 2 +- .../property_templates/list_property.pyi | 2 +- .../property_templates/model_property.pyi | 4 ++- .../property_templates/none_property.pyi | 2 +- .../property_templates/union_property.pyi | 4 ++- pyproject.toml | 2 +- 14 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 openapi_python_client/.flake8 diff --git a/openapi_python_client/.flake8 b/openapi_python_client/.flake8 new file mode 100644 index 000000000..b601d1408 --- /dev/null +++ b/openapi_python_client/.flake8 @@ -0,0 +1,3 @@ +[flake8] +per-file-ignores = + parser/properties/__init__.py: E402 diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index c6f1b884a..e4d3ac85e 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -15,6 +15,7 @@ from .parser import GeneratorData, import_string_from_reference from .parser.errors import GeneratorError +from .parser.properties import UnionProperty from .utils import snake_case if sys.version_info.minor < 8: # version did not exist before 3.8, need to use a backport @@ -46,7 +47,6 @@ class Project: def __init__(self, *, openapi: GeneratorData, custom_template_path: Optional[Path] = None) -> None: self.openapi: GeneratorData = openapi - package_loader = PackageLoader(__package__) loader: BaseLoader if custom_template_path is not None: @@ -174,10 +174,18 @@ def _build_models(self) -> None: imports = [] model_template = self.env.get_template("model.pyi") + union_property_template = self.env.get_template("polymorphic_model.pyi") + for model in self.openapi.models.values(): - module_path = models_dir / f"{model.reference.module_name}.py" - module_path.write_text(model_template.render(model=model)) - imports.append(import_string_from_reference(model.reference)) + if isinstance(model, UnionProperty): + template = union_property_template + else: + template = model_template + + module_path = models_dir / f"{model.module_name}.py" + module_path.write_text(template.render(model=model)) + if not isinstance(model, UnionProperty): + imports.append(import_string_from_reference(model.reference)) # Generate enums str_enum_template = self.env.get_template("str_enum.pyi") diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 2176c9033..2d6174c40 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -1,3 +1,5 @@ +_property = property # isort: skip + from itertools import chain from typing import Any, ClassVar, Dict, Generic, Iterable, Iterator, List, Optional, Set, Tuple, TypeVar, Union @@ -160,10 +162,11 @@ class UnionProperty(Property): """ A property representing a Union (anyOf) of other properties """ inner_properties: List[Property] + relative_imports: Set[str] = set() template: ClassVar[str] = "union_property.pyi" has_properties_without_templates: bool = attr.ib(init=False) - discriminator_property: Optional[str] - discriminator_mappings: Dict[str, Property] + discriminator_property: Optional[str] = None + discriminator_mappings: Dict[str, Property] = {} def __attrs_post_init__(self) -> None: super().__attrs_post_init__() @@ -181,6 +184,14 @@ def _get_inner_type_strings(self, json: bool = False) -> List[str]: def get_base_type_string(self, json: bool = False) -> str: return f"Union[{', '.join(self._get_inner_type_strings(json=json))}]" + def resolve_references(self, components, schemas): + self.relative_imports.update(self.get_imports(prefix="..")) + return schemas + + @_property + def module_name(self): + return self.python_name + def get_type_strings_in_union( self, no_optional: bool = False, query_parameter: bool = False, json: bool = False ) -> List[str]: @@ -284,6 +295,14 @@ def build_model_property( Used to infer the type name if a `title` property is not available. schemas: Existing Schemas which have already been processed (to check name conflicts) """ + if data.anyOf or data.oneOf: + prop, schemas = build_union_property( + data=data, name=name, required=required, schemas=schemas, parent_name=parent_name + ) + if not isinstance(prop, PropertyError): + schemas = attr.evolve(schemas, models={**schemas.models, prop.name: prop}) + return prop, schemas + required_set = set(data.required or []) required_properties: List[Property] = [] optional_properties: List[Property] = [] @@ -317,6 +336,11 @@ def build_model_property( optional_properties.append(prop) relative_imports.update(prop.get_imports(prefix="..")) + discriminator_mappings: Dict[str, Property] = {} + if data.discriminator is not None: + for k, v in (data.discriminator.mapping or {}).items(): + discriminator_mappings[k] = Reference.from_ref(v) + additional_properties: Union[bool, Property, PropertyError] if data.additionalProperties is None: additional_properties = True @@ -347,6 +371,8 @@ def build_model_property( description=data.description or "", default=None, nullable=data.nullable, + discriminator_property=data.discriminator.propertyName if data.discriminator else None, + discriminator_mappings=discriminator_mappings, required=required, name=name, additional_properties=additional_properties, @@ -446,7 +472,7 @@ def build_union_property( discriminator_mappings: Dict[str, Property] = {} if data.discriminator is not None: - for k, v in (data.discriminator.mapping if data.discriminator else {}).items(): + for k, v in (data.discriminator.mapping or {}).items(): ref_class_name = Reference.from_ref(v).class_name discriminator_mappings[k] = reference_name_to_subprop[ref_class_name] diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index c4c203a5d..8a22df007 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections.abc import Iterable -from typing import TYPE_CHECKING, ClassVar, Dict, List, Set, Union +from typing import TYPE_CHECKING, ClassVar, Dict, List, Optional, Set, Union import attr @@ -22,6 +22,9 @@ class ModelProperty(Property): references: List[oai.Reference] required_properties: List[Property] optional_properties: List[Property] + discriminator_property: Optional[str] + discriminator_mappings: Dict[str, Property] + description: str relative_imports: Set[str] additional_properties: Union[bool, Property] @@ -30,6 +33,10 @@ class ModelProperty(Property): template: ClassVar[str] = "model_property.pyi" json_is_dict: ClassVar[bool] = True + @property + def module_name(self): + return self.reference.module_name + def resolve_references( self, components: Dict[str, Union[oai.Reference, oai.Schema]], schemas: Schemas ) -> Union[Schemas, PropertyError]: @@ -44,7 +51,7 @@ def resolve_references( assert isinstance(referenced_prop, oai.Schema) for p, val in (referenced_prop.properties or {}).items(): props[p] = (val, source_name) - for sub_prop in referenced_prop.allOf or []: + for sub_prop in referenced_prop.allOf or referenced_prop.anyOf or referenced_prop.oneOf or []: if isinstance(sub_prop, oai.Reference): self.references.append(sub_prop) else: @@ -71,9 +78,17 @@ def resolve_references( self.optional_properties.append(prop) self.relative_imports.update(prop.get_imports(prefix="..")) + for _, value in self.discriminator_mappings.items(): + self.relative_imports.add(f"from ..models.{value.module_name} import {value.class_name}") + return schemas def get_base_type_string(self) -> str: + if getattr(self, "discriminator_mappings", None): + discriminator_types = ", ".join( + [ref.class_name for ref in self.discriminator_mappings.values()] + ["UnknownType"] + ) + return f"Union[{discriminator_types}]" return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index 528a9961b..209de81e0 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value="None") %} +{% macro construct(property, source, initial_value="None", nested=False) %} {% if property.required and not property.nullable %} {{ property.python_name }} = isoparse({{ source }}).date() {% else %} diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index 5442c75fe..6254d7bac 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value="None") %} +{% macro construct(property, source, initial_value="None", nested=False) %} {% if property.required %} {% if property.nullable %} {{ property.python_name }} = {{ source }} diff --git a/openapi_python_client/templates/property_templates/dict_property.pyi b/openapi_python_client/templates/property_templates/dict_property.pyi index c4a853d72..4f45fd2e2 100644 --- a/openapi_python_client/templates/property_templates/dict_property.pyi +++ b/openapi_python_client/templates/property_templates/dict_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value="None") %} +{% macro construct(property, source, initial_value="None", nested=False) %} {% if property.required %} {{ property.python_name }} = {{ source }} {% else %} diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 4c33ba051..6d71cf602 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value="None") %} +{% macro construct(property, source, initial_value="None", nested=False) %} {% if property.required %} {{ property.python_name }} = {{ property.reference.class_name }}({{ source }}) {% else %} diff --git a/openapi_python_client/templates/property_templates/file_property.pyi b/openapi_python_client/templates/property_templates/file_property.pyi index 1758c07f6..90d850a32 100644 --- a/openapi_python_client/templates/property_templates/file_property.pyi +++ b/openapi_python_client/templates/property_templates/file_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value=None) %} +{% macro construct(property, source, initial_value=None, nested=False) %} {{ property.python_name }} = File( payload = BytesIO({{ source }}) ) diff --git a/openapi_python_client/templates/property_templates/list_property.pyi b/openapi_python_client/templates/property_templates/list_property.pyi index 0705e9d93..f5f3d5592 100644 --- a/openapi_python_client/templates/property_templates/list_property.pyi +++ b/openapi_python_client/templates/property_templates/list_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value="[]") %} +{% macro construct(property, source, initial_value="[]", nested=False) %} {% set inner_property = property.inner_property %} {% if inner_property.template %} {% set inner_source = inner_property.python_name + "_data" %} diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index ee819f8a6..91f4bba13 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -1,4 +1,6 @@ -{% macro construct(property, source, initial_value=None) %} +{# This file is shadowed by the template with the same name + # in aurelia/packages/api_client_generation/templates #} +{% macro construct(property, source, initial_value=None, nested=False) %} {% if property.required and not property.nullable %} {% if source == "response.yaml" %} yaml_dict = yaml.safe_load(response.text.encode("utf-8")) diff --git a/openapi_python_client/templates/property_templates/none_property.pyi b/openapi_python_client/templates/property_templates/none_property.pyi index 235530c8b..a2dee93ca 100644 --- a/openapi_python_client/templates/property_templates/none_property.pyi +++ b/openapi_python_client/templates/property_templates/none_property.pyi @@ -1,4 +1,4 @@ -{% macro construct(property, source, initial_value="None") %} +{% macro construct(property, source, initial_value="None", nested=False) %} {{ property.python_name }} = {{ initial_value }} {% endmacro %} diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 179dd4ae3..e12540d9d 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -1,4 +1,6 @@ -{% macro construct(property, source, initial_value=None) %} +{# This file is shadowed by the template with the same name + # in aurelia/packages/api_client_generation/templates #} +{% macro construct(property, source, initial_value=None, nested=False) %} def _parse_{{ property.python_name }}(data: {{ property.get_type_string(json=True) }}) -> {{ property.get_type_string() }}: {{ property.python_name }}: {{ property.get_type_string() }} {% if "None" in property.get_type_strings_in_union(json=True) %} diff --git a/pyproject.toml b/pyproject.toml index 57b01d851..b742765d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "openapi-python-client" # Our versions have diverged and have no relation to upstream code changes # Henceforth, openapi-python-package will be maintained internally -version = "1.0.3" +version = "1.0.4" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" From 469f25cd8fc256479591662eacae85b77f8320ed Mon Sep 17 00:00:00 2001 From: Steve Strassmann Date: Mon, 10 Oct 2022 15:57:12 -0400 Subject: [PATCH 46/50] bump version (#155) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f801cd654..c7c897488 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup_kwargs = { "name": "benchling-openapi-python-client", - "version": "1.0.3", + "version": "1.0.4", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", From c380c1e963ac2c9628120f7ecf5a864af80ba4c4 Mon Sep 17 00:00:00 2001 From: Steve Strassmann Date: Tue, 11 Oct 2022 10:00:28 -0400 Subject: [PATCH 47/50] dedupe union typestrings (#157) --- openapi_python_client/parser/properties/__init__.py | 3 ++- pyproject.toml | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 2d6174c40..36625b260 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -179,7 +179,8 @@ def _get_inner_type_strings(self, json: bool = False) -> List[str]: if not json: inner_types.append("UnknownType") unique_inner_types = list(dict.fromkeys(inner_types)) - return unique_inner_types + filter_self_types = [name for name in unique_inner_types if name != self.name] + return filter_self_types def get_base_type_string(self, json: bool = False) -> str: return f"Union[{', '.join(self._get_inner_type_strings(json=json))}]" diff --git a/pyproject.toml b/pyproject.toml index b742765d3..95831012f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "openapi-python-client" # Our versions have diverged and have no relation to upstream code changes # Henceforth, openapi-python-package will be maintained internally -version = "1.0.4" +version = "1.0.5" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" diff --git a/setup.py b/setup.py index c7c897488..2c2b9158f 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup_kwargs = { "name": "benchling-openapi-python-client", - "version": "1.0.4", + "version": "1.0.5", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", From 8d504f6717ebbb8fc3ed4704d5becc407303c198 Mon Sep 17 00:00:00 2001 From: George Murray Date: Tue, 18 Oct 2022 08:55:53 -0700 Subject: [PATCH 48/50] feat: Rev attrs package CUST-3710 Rev the attrs package to unblock 22 in SDK. --- poetry.lock | 161 ++++++++++++++++++++++--------------------------- pyproject.toml | 2 +- 2 files changed, 73 insertions(+), 90 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6945e3a1d..6fe3d048d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -26,21 +26,21 @@ python-versions = "*" [[package]] name = "attrs" -version = "21.4.0" +version = "22.1.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] [[package]] name = "autoflake" -version = "1.5.3" +version = "1.7.5" description = "Removes unused imports and unused variables" category = "main" optional = false @@ -48,7 +48,7 @@ python-versions = ">=3.7" [package.dependencies] pyflakes = ">=1.1.0" -toml = ">=0.10.2" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} [[package]] name = "black" @@ -76,7 +76,7 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2022.6.15" +version = "2022.9.24" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -111,7 +111,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.4.4" +version = "6.5.0" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -125,7 +125,7 @@ toml = ["tomli"] [[package]] name = "dparse" -version = "0.5.2" +version = "0.6.2" description = "A parser for Python dependency files" category = "dev" optional = false @@ -141,17 +141,16 @@ conda = ["pyyaml"] [[package]] name = "flake8" -version = "3.9.2" -description = "the modular source code checker: pep8 pyflakes and co" +version = "2.3.0" +description = "the modular source code checker: pep8, pyflakes and co" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = "*" [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.7.0,<2.8.0" -pyflakes = ">=2.3.0,<2.4.0" +mccabe = ">=0.2.1" +pep8 = ">=1.5.7" +pyflakes = ">=0.8.1" [[package]] name = "h11" @@ -201,7 +200,7 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "idna" -version = "3.3" +version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false @@ -209,7 +208,7 @@ python-versions = ">=3.5" [[package]] name = "importlib-metadata" -version = "4.12.0" +version = "5.0.0" description = "Read metadata from Python packages" category = "main" optional = false @@ -220,9 +219,9 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -270,11 +269,11 @@ python-versions = ">=3.7" [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "mslex" @@ -286,11 +285,11 @@ python-versions = ">=3.5" [[package]] name = "mypy" -version = "0.971" +version = "0.982" description = "Optional static typing for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] mypy-extensions = ">=0.4.3" @@ -330,6 +329,14 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "pep8" +version = "1.7.1" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pluggy" version = "1.0.0" @@ -364,14 +371,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[[package]] -name = "pycodestyle" -version = "2.7.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "pydantic" version = "1.10.2" @@ -389,11 +388,11 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyflakes" -version = "2.3.1" +version = "2.5.0" description = "passive checker of Python programs" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "pyparsing" @@ -429,7 +428,7 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2. [[package]] name = "pytest-cov" -version = "3.0.0" +version = "4.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false @@ -440,11 +439,11 @@ coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["virtualenv", "pytest-xdist", "six", "process-tests", "hunter", "fields"] +testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-mock" -version = "3.8.2" +version = "3.10.0" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false @@ -488,7 +487,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "regex" -version = "2022.8.17" +version = "2022.9.13" description = "Alternative regular expression module, to replace re." category = "main" optional = false @@ -598,7 +597,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -622,14 +621,14 @@ python-versions = ">=3.6" click = ">=7.1.1,<7.2.0" [package.extras] -test = ["isort (>=5.0.6,<6.0.0)", "black (>=19.10b0,<20.0b0)", "mypy (==0.782)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "coverage (>=5.2,<6.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest (>=4.4.0,<5.4.0)", "shellingham (>=1.3.0,<2.0.0)"] -doc = ["markdown-include (>=0.5.1,<0.6.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "mkdocs (>=1.1.2,<2.0.0)"] -dev = ["flake8 (>=3.8.3,<4.0.0)", "autoflake (>=1.3.1,<2.0.0)"] -all = ["shellingham (>=1.3.0,<2.0.0)", "colorama (>=0.4.3,<0.5.0)"] +test = ["pytest-xdist (>=1.32.0,<2.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "mypy (==0.782)", "black (>=19.10b0,<20.0b0)", "isort (>=5.0.6,<6.0.0)", "shellingham (>=1.3.0,<2.0.0)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "coverage (>=5.2,<6.0)"] +all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"] +dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)"] +doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown-include (>=0.5.1,<0.6.0)"] [[package]] name = "typing-extensions" -version = "4.3.0" +version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -650,20 +649,20 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "zipp" -version = "3.8.1" +version = "3.9.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] +docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "eae24c8ae9afd3a05a10b592b5ce2bb5c1769c26c9ea7038b69b4cdf92f946a0" +content-hash = "f852408a0681affc04125fdef3479d4734bc970a0254296383efb0484067d56c" [metadata.files] anyio = [ @@ -674,42 +673,30 @@ appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] -attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] +attrs = [] autoflake = [] black = [] -certifi = [ - {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, - {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, -] +certifi = [] charset-normalizer = [] -click = [] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] colorama = [ {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] coverage = [] dparse = [] -flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] +flake8 = [] h11 = [ {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, ] httpcore = [] httpx = [] -idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, -] -importlib-metadata = [ - {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"}, - {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"}, -] +idna = [] +importlib-metadata = [] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -764,10 +751,7 @@ markupsafe = [ {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] +mccabe = [] mslex = [ {file = "mslex-0.3.0-py2.py3-none-any.whl", hash = "sha256:380cb14abf8fabf40e56df5c8b21a6d533dc5cbdcfe42406bbf08dda8f42e42a"}, {file = "mslex-0.3.0.tar.gz", hash = "sha256:4a1ac3f25025cad78ad2fe499dd16d42759f7a3801645399cce5c404415daa97"}, @@ -777,8 +761,12 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -packaging = [] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] pathspec = [] +pep8 = [] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, @@ -788,15 +776,8 @@ py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, -] pydantic = [] -pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, -] +pyflakes = [] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, @@ -841,10 +822,7 @@ pyyaml = [ {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] regex = [] -requests = [ - {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, - {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, -] +requests = [] rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, @@ -856,7 +834,9 @@ six = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] sniffio = [] -stringcase = [] +stringcase = [ + {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, +] taskipy = [] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, @@ -892,7 +872,10 @@ typed-ast = [ {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] -typer = [] +typer = [ + {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, + {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, +] typing-extensions = [] urllib3 = [] zipp = [] diff --git a/pyproject.toml b/pyproject.toml index 95831012f..fbdfdff95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ isort = "^5.0.5" pyyaml = "^5.3.1" importlib_metadata = {version = ">=4.4", python = "<3.8"} pydantic = "^1.6.1" -attrs = ">=20.1.0, <22.0" +attrs = ">=20.1.0, <23.0" python-dateutil = "^2.8.1" httpx = ">=0.23.0" autoflake = "^1.4" From fadd74bdf890f5359d1235f4557ce70574db6bbd Mon Sep 17 00:00:00 2001 From: George Murray Date: Tue, 25 Oct 2022 09:10:38 -0700 Subject: [PATCH 49/50] Bump Version to 1.0.6 --- pyproject.toml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fbdfdff95..ffbef685b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "openapi-python-client" # Our versions have diverged and have no relation to upstream code changes # Henceforth, openapi-python-package will be maintained internally -version = "1.0.5" +version = "1.0.6" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" diff --git a/setup.py b/setup.py index 2c2b9158f..6af28f852 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ setup_kwargs = { "name": "benchling-openapi-python-client", - "version": "1.0.5", + "version": "1.0.6", "description": "Generate modern Python clients from OpenAPI", "long_description": '[![triaxtec](https://circleci.com/gh/triaxtec/openapi-python-client.svg?style=svg)](https://circleci.com/gh/triaxtec/openapi-python-client)\n[![codecov](https://codecov.io/gh/triaxtec/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n[![Generic badge](https://img.shields.io/badge/type_checked-mypy-informational.svg)](https://mypy.readthedocs.io/en/stable/introduction.html)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![PyPI version shields.io](https://img.shields.io/pypi/v/openapi-python-client.svg)](https://pypi.python.org/pypi/openapi-python-client/)\n[![Downloads](https://static.pepy.tech/personalized-badge/openapi-python-client?period=total&units=international_system&left_color=blue&right_color=green&left_text=Downloads)](https://pepy.tech/project/openapi-python-client)\n\n# openapi-python-client\n\nGenerate modern Python clients from OpenAPI 3.x documents.\n\n_This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to\nversion 3 first with one of many available converters._\n\n**This project is still in development and does not support all OpenAPI features**\n\n## Why This?\n\nThe Python clients generated by openapi-generator support Python 2 and therefore come with a lot of baggage. This tool\naims to generate clients which:\n\n1. Use all the latest and greatest Python features like type annotations and dataclasses\n1. Don\'t carry around a bunch of compatibility code for older version of Python (e.g. the `six` package)\n1. Have better documentation and more obvious usage instructions\n\nAdditionally, because this generator is written in Python, it should be more accessible to contribution by the people\nusing it (Python developers).\n\n## Installation\n\nI recommend you install with [pipx](https://pipxproject.github.io/pipx/) so you don\'t conflict with any other packages\nyou might have: `pipx install openapi-python-client`.\n\nBetter yet, use `pipx run openapi-python-client ` to always use the latest version of the generator.\n\nYou can install with normal pip if you want to though: `pip install openapi-python-client`\n\nThen, if you want tab completion: `openapi-python-client --install-completion`\n\n## Usage\n\n### Create a new client\n\n`openapi-python-client generate --url https://my.api.com/openapi.json`\n\nThis will generate a new client library named based on the title in your OpenAPI spec. For example, if the title\nof your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you\'ll\nget an error.\n\n### Update an existing client\n\n`openapi-python-client update --url https://my.api.com/openapi.json`\n\n> For more usage details run `openapi-python-client --help` or read [usage](usage.md)\n\n### Using custom templates\n\nThis feature leverages Jinja2\'s [ChoiceLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.ChoiceLoader) and [FileSystemLoader](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader). This means you do _not_ need to customize every template. Simply copy the template(s) you want to customize from [the default template directory](openapi_python_client/templates) to your own custom template directory (file names _must_ match exactly) and pass the template directory through the `custom-template-path` flag to the `generate` and `update` commands. For instance,\n\n```\nopenapi-python-client update \\\n --url https://my.api.com/openapi.json \\\n --custom-template-path=relative/path/to/mytemplates\n```\n\n_Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable._\n\n## What You Get\n\n1. A `pyproject.toml` file with some basic metadata intended to be used with [Poetry].\n1. A `README.md` you\'ll most definitely need to update with your project\'s details\n1. A Python module named just like the auto-generated project name (e.g. "my_api_client") which contains:\n 1. A `client` module which will have both a `Client` class and an `AuthenticatedClient` class. You\'ll need these\n for calling the functions in the `api` module.\n 1. An `api` module which will contain one module for each tag in your OpenAPI spec, as well as a `default` module\n for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.\n 1. A `models` module which has all the classes defined by the various schemas in your OpenAPI spec\n\nFor a full example you can look at the `end_to_end_tests` directory which has an `openapi.json` file.\n"golden-record" in that same directory is the generated client from that OpenAPI document.\n\n## OpenAPI features supported\n\n1. All HTTP Methods\n1. JSON and form bodies, path and query parameters\n1. File uploads with multipart/form-data bodies\n1. float, string, int, date, datetime, string enums, and custom schemas or lists containing any of those\n1. html/text or application/json responses containing any of the previous types\n1. Bearer token security\n\n## Configuration\n\nYou can pass a YAML (or JSON) file to openapi-python-client with the `--config` option in order to change some behavior.\nThe following parameters are supported:\n\n### class_overrides\n\nUsed to change the name of generated model classes. This param should be a mapping of existing class name\n(usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the\nname of the a model in OpenAPI (and therefore the generated class name) was something like "\\_PrivateInternalLongName"\nand you want the generated client\'s model to be called "ShortName" in a module called "short_name" you could do this:\n\nExample:\n\n```yaml\nclass_overrides:\n _PrivateInternalLongName:\n class_name: ShortName\n module_name: short_name\n```\n\nThe easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the\nmodels folder.\n\n### project_name_override and package_name_override\n\nUsed to change the name of generated client library project/package. If the project name is changed but an override for the package name\nisn\'t provided, the package name will be converted from the project name using the standard convention (replacing `-`\'s with `_`\'s).\n\nExample:\n\n```yaml\nproject_name_override: my-special-project-name\npackage_name_override: my_extra_special_package_name\n```\n\n### field_prefix\n\nWhen generating properties, the `name` attribute of the OpenAPI schema will be used. When the `name` is not a valid\nPython identifier (e.g. begins with a number) this string will be prepended. Defaults to "field\\_".\n\nExample:\n\n```yaml\nfield_prefix: attr_\n```\n\n### package_version_override\n\nSpecify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.\n\nExample:\n\n```yaml\npackage_version_override: 1.2.3\n```\n\n## How to publish changes\nQuip doc that highlights how to pull the dependency to Aurelia and publish using a buildkite pipeline can be found [here](https://benchling.quip.com/PgytA283Rlyo/2022-02-16-Guide-for-Publishing-a-Package)\n\nAfter changes are made to this package, to publish a new version of this package:\n* Bump the version on pyproject.toml\n* Install `gnu-sed` (assuming that you\'re running on a mac) by running `brew install gnu-sed`\n * macOS uses BSD sed, which is similar to Linux\'s GNU sed but cannot explicitly edit files in place i.e. cannot utilize `-i` tag\n* Set GNU sed PATH by running `brew info gnu-sed` to check for PATH\n* Run `poetry run task gen-setuppy` which updates setup.py\n* Kick off a buildkite pipeline build as highlighted in the quip doc (would need to designate the branch of which to check for publish)\n\n\n[changelog.md]: CHANGELOG.md\n[poetry]: https://python-poetry.org/\n', "author": "Dylan Anthony", From 884ea5f6c666ddede52a92355852e0eb58c57f89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 02:59:47 +0000 Subject: [PATCH 50/50] chore(deps-dev): bump mypy from 0.982 to 1.4.1 Bumps [mypy](https://github.com/python/mypy) from 0.982 to 1.4.1. - [Commits](https://github.com/python/mypy/compare/v0.982...v1.4.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 896 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 588 insertions(+), 308 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6fe3d048d..034f6cf01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,15 @@ +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. + [[package]] name = "anyio" version = "3.6.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = false python-versions = ">=3.6.2" +files = [ + {file = "anyio-3.6.1-py3-none-any.whl", hash = "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"}, + {file = "anyio-3.6.1.tar.gz", hash = "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b"}, +] [package.dependencies] idna = ">=2.8" @@ -12,39 +17,49 @@ sniffio = ">=1.1" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] -test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] +doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] trio = ["trio (>=0.16)"] [[package]] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = "*" +files = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] [[package]] name = "attrs" version = "22.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, +] [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "autoflake" version = "1.7.5" description = "Removes unused imports and unused variables" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "autoflake-1.7.5-py2.py3-none-any.whl", hash = "sha256:bedb29201b07876cd9cad3a804760b1127b9bf156cf9689762a12eabd1683b65"}, + {file = "autoflake-1.7.5-py3-none-any.whl", hash = "sha256:5ce7977d4f9905b01ef12d572f69252406009718ec1bac95fb5d74eb4faca58b"}, + {file = "autoflake-1.7.5.tar.gz", hash = "sha256:9848061faca11745e6ca9feb010a8caa9d62ec3ea1817413c226eb3b58bbdada"}, +] [package.dependencies] pyflakes = ">=1.1.0" @@ -54,9 +69,12 @@ tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} name = "black" version = "21.6b0" description = "The uncompromising code formatter." -category = "main" optional = false python-versions = ">=3.6.2" +files = [ + {file = "black-21.6b0-py3-none-any.whl", hash = "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7"}, + {file = "black-21.6b0.tar.gz", hash = "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04"}, +] [package.dependencies] appdirs = "*" @@ -78,44 +96,107 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2022.9.24" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, + {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, +] [[package]] name = "charset-normalizer" version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" optional = false python-versions = ">=3.6.0" +files = [ + {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, +] [package.extras] -unicode_backport = ["unicodedata2"] +unicode-backport = ["unicodedata2"] [[package]] name = "click" version = "7.1.2" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] [[package]] name = "colorama" version = "0.4.5" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, +] [[package]] name = "coverage" version = "6.5.0" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, + {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, + {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, + {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, + {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, + {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, + {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, + {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, + {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, + {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, + {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, + {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, + {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, + {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, + {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, + {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, + {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, + {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, + {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, + {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, + {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, + {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, + {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, + {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, + {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, + {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, + {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, + {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, +] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -127,25 +208,31 @@ toml = ["tomli"] name = "dparse" version = "0.6.2" description = "A parser for Python dependency files" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "dparse-0.6.2-py3-none-any.whl", hash = "sha256:8097076f1dd26c377f30d4745e6ec18fef42f3bf493933b842ac5bafad8c345f"}, + {file = "dparse-0.6.2.tar.gz", hash = "sha256:d45255bda21f998bc7ddf2afd5e62505ba6134756ba2d42a84c56b0826614dfe"}, +] [package.dependencies] packaging = "*" toml = "*" [package.extras] -pipenv = ["pipenv"] conda = ["pyyaml"] +pipenv = ["pipenv"] [[package]] name = "flake8" version = "2.3.0" description = "the modular source code checker: pep8, pyflakes and co" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "flake8-2.3.0-py2.py3-none-any.whl", hash = "sha256:c99cc9716d6655d9c8bcb1e77632b8615bf0abd282d7abd9f5c2148cad7fc669"}, + {file = "flake8-2.3.0.tar.gz", hash = "sha256:5ee1a43ccd0716d6061521eec6937c983efa027793013e572712c4da55c7c83e"}, +] [package.dependencies] mccabe = ">=0.2.1" @@ -156,35 +243,44 @@ pyflakes = ">=0.8.1" name = "h11" version = "0.12.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, + {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, +] [[package]] name = "httpcore" version = "0.15.0" description = "A minimal low-level HTTP client." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "httpcore-0.15.0-py3-none-any.whl", hash = "sha256:1105b8b73c025f23ff7c36468e4432226cbb959176eab66864b8e31c4ee27fa6"}, + {file = "httpcore-0.15.0.tar.gz", hash = "sha256:18b68ab86a3ccf3e7dc0f43598eaddcf472b602aba29f9aa6ab85fe2ada3980b"}, +] [package.dependencies] -anyio = ">=3.0.0,<4.0.0" +anyio = "==3.*" certifi = "*" h11 = ">=0.11,<0.13" -sniffio = ">=1.0.0,<2.0.0" +sniffio = "==1.*" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "httpx" version = "0.23.0" description = "The next generation HTTP client." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "httpx-0.23.0-py3-none-any.whl", hash = "sha256:42974f577483e1e932c3cdc3cd2303e883cbfba17fe228b0f63589764d7b9c4b"}, + {file = "httpx-0.23.0.tar.gz", hash = "sha256:f28eac771ec9eb4866d3fb4ab65abd42d38c424739e80c08d8d20570de60b0ef"}, +] [package.dependencies] certifi = "*" @@ -193,65 +289,80 @@ rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} sniffio = "*" [package.extras] -brotli = ["brotlicffi", "brotli"] -cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10,<13)", "pygments (>=2.0.0,<3.0.0)"] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<13)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "importlib-metadata" version = "5.0.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-5.0.0-py3-none-any.whl", hash = "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"}, + {file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"}, +] [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "iniconfig" version = "1.1.1" description = "iniconfig: brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] [[package]] name = "isort" version = "5.10.1" description = "A Python utility / library to sort Python imports." -category = "main" optional = false python-versions = ">=3.6.1,<4.0" +files = [ + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, +] [package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] +pipfile-deprecated-finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] [package.dependencies] MarkupSafe = ">=2.0" @@ -263,60 +374,141 @@ i18n = ["Babel (>=2.7)"] name = "markupsafe" version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] [[package]] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] [[package]] name = "mslex" version = "0.3.0" description = "shlex for windows" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "mslex-0.3.0-py2.py3-none-any.whl", hash = "sha256:380cb14abf8fabf40e56df5c8b21a6d533dc5cbdcfe42406bbf08dda8f42e42a"}, + {file = "mslex-0.3.0.tar.gz", hash = "sha256:4a1ac3f25025cad78ad2fe499dd16d42759f7a3801645399cce5c404415daa97"}, +] [[package]] name = "mypy" -version = "0.982" +version = "1.4.1" description = "Optional static typing for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"}, + {file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"}, + {file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"}, + {file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"}, + {file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"}, + {file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"}, + {file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"}, + {file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"}, + {file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"}, + {file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"}, + {file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"}, + {file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"}, + {file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"}, + {file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"}, + {file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"}, + {file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"}, + {file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"}, + {file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"}, + {file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"}, + {file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"}, + {file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"}, + {file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"}, + {file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"}, + {file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"}, + {file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"}, + {file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"}, +] [package.dependencies] -mypy-extensions = ">=0.4.3" +mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} -typing-extensions = ">=3.10" +typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] python2 = ["typed-ast (>=1.4.0,<2)"] reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "main" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = "*" +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] [[package]] name = "packaging" version = "21.3" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" @@ -325,25 +517,34 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" name = "pathspec" version = "0.10.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, + {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, +] [[package]] name = "pep8" version = "1.7.1" description = "Python style guide checker" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "pep8-1.7.1-py2.py3-none-any.whl", hash = "sha256:b22cfae5db09833bb9bd7c8463b53e1a9c9b39f12e304a8d0bba729c501827ee"}, + {file = "pep8-1.7.1.tar.gz", hash = "sha256:fe249b52e20498e59e0b5c5256aa52ee99fc295b26ec9eaa85776ffdb9fe6374"}, +] [[package]] name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} @@ -356,28 +557,101 @@ testing = ["pytest", "pytest-benchmark"] name = "psutil" version = "5.9.2" description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "psutil-5.9.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:8f024fbb26c8daf5d70287bb3edfafa22283c255287cf523c5d81721e8e5d82c"}, + {file = "psutil-5.9.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b2f248ffc346f4f4f0d747ee1947963613216b06688be0be2e393986fe20dbbb"}, + {file = "psutil-5.9.2-cp27-cp27m-win32.whl", hash = "sha256:b1928b9bf478d31fdffdb57101d18f9b70ed4e9b0e41af751851813547b2a9ab"}, + {file = "psutil-5.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:404f4816c16a2fcc4eaa36d7eb49a66df2d083e829d3e39ee8759a411dbc9ecf"}, + {file = "psutil-5.9.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:94e621c6a4ddb2573d4d30cba074f6d1aa0186645917df42c811c473dd22b339"}, + {file = "psutil-5.9.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:256098b4f6ffea6441eb54ab3eb64db9ecef18f6a80d7ba91549195d55420f84"}, + {file = "psutil-5.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:614337922702e9be37a39954d67fdb9e855981624d8011a9927b8f2d3c9625d9"}, + {file = "psutil-5.9.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39ec06dc6c934fb53df10c1672e299145ce609ff0611b569e75a88f313634969"}, + {file = "psutil-5.9.2-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3ac2c0375ef498e74b9b4ec56df3c88be43fe56cac465627572dbfb21c4be34"}, + {file = "psutil-5.9.2-cp310-cp310-win32.whl", hash = "sha256:e4c4a7636ffc47b7141864f1c5e7d649f42c54e49da2dd3cceb1c5f5d29bfc85"}, + {file = "psutil-5.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:f4cb67215c10d4657e320037109939b1c1d2fd70ca3d76301992f89fe2edb1f1"}, + {file = "psutil-5.9.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:dc9bda7d5ced744622f157cc8d8bdd51735dafcecff807e928ff26bdb0ff097d"}, + {file = "psutil-5.9.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75291912b945a7351d45df682f9644540d564d62115d4a20d45fa17dc2d48f8"}, + {file = "psutil-5.9.2-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4018d5f9b6651f9896c7a7c2c9f4652e4eea53f10751c4e7d08a9093ab587ec"}, + {file = "psutil-5.9.2-cp36-cp36m-win32.whl", hash = "sha256:f40ba362fefc11d6bea4403f070078d60053ed422255bd838cd86a40674364c9"}, + {file = "psutil-5.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9770c1d25aee91417eba7869139d629d6328a9422ce1cdd112bd56377ca98444"}, + {file = "psutil-5.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42638876b7f5ef43cef8dcf640d3401b27a51ee3fa137cb2aa2e72e188414c32"}, + {file = "psutil-5.9.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91aa0dac0c64688667b4285fa29354acfb3e834e1fd98b535b9986c883c2ce1d"}, + {file = "psutil-5.9.2-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fb54941aac044a61db9d8eb56fc5bee207db3bc58645d657249030e15ba3727"}, + {file = "psutil-5.9.2-cp37-cp37m-win32.whl", hash = "sha256:7cbb795dcd8ed8fd238bc9e9f64ab188f3f4096d2e811b5a82da53d164b84c3f"}, + {file = "psutil-5.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5d39e3a2d5c40efa977c9a8dd4f679763c43c6c255b1340a56489955dbca767c"}, + {file = "psutil-5.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fd331866628d18223a4265371fd255774affd86244fc307ef66eaf00de0633d5"}, + {file = "psutil-5.9.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b315febaebae813326296872fdb4be92ad3ce10d1d742a6b0c49fb619481ed0b"}, + {file = "psutil-5.9.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7929a516125f62399d6e8e026129c8835f6c5a3aab88c3fff1a05ee8feb840d"}, + {file = "psutil-5.9.2-cp38-cp38-win32.whl", hash = "sha256:561dec454853846d1dd0247b44c2e66a0a0c490f937086930ec4b8f83bf44f06"}, + {file = "psutil-5.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:67b33f27fc0427483b61563a16c90d9f3b547eeb7af0ef1b9fe024cdc9b3a6ea"}, + {file = "psutil-5.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3591616fa07b15050b2f87e1cdefd06a554382e72866fcc0ab2be9d116486c8"}, + {file = "psutil-5.9.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b29f581b5edab1f133563272a6011925401804d52d603c5c606936b49c8b97"}, + {file = "psutil-5.9.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4642fd93785a29353d6917a23e2ac6177308ef5e8be5cc17008d885cb9f70f12"}, + {file = "psutil-5.9.2-cp39-cp39-win32.whl", hash = "sha256:ed29ea0b9a372c5188cdb2ad39f937900a10fb5478dc077283bf86eeac678ef1"}, + {file = "psutil-5.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:68b35cbff92d1f7103d8f1db77c977e72f49fcefae3d3d2b91c76b0e7aef48b8"}, + {file = "psutil-5.9.2.tar.gz", hash = "sha256:feb861a10b6c3bb00701063b37e4afc754f8217f0f09c42280586bd6ac712b5c"}, +] [package.extras] -test = ["ipaddress", "mock", "enum34", "pywin32", "wmi"] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] [[package]] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] [[package]] name = "pydantic" version = "1.10.2" description = "Data validation and settings management using python type hints" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"}, + {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"}, + {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"}, + {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"}, + {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"}, + {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"}, + {file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"}, + {file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"}, + {file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"}, + {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"}, + {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"}, + {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"}, + {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"}, + {file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"}, + {file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"}, + {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"}, + {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"}, + {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"}, + {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"}, + {file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"}, + {file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"}, + {file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"}, + {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"}, + {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"}, + {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"}, + {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"}, + {file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"}, + {file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"}, + {file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"}, + {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"}, + {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"}, + {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"}, + {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"}, + {file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"}, + {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"}, + {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"}, +] [package.dependencies] typing-extensions = ">=4.1.0" @@ -390,28 +664,37 @@ email = ["email-validator (>=1.0.3)"] name = "pyflakes" version = "2.5.0" description = "passive checker of Python programs" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, +] [[package]] name = "pyparsing" version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" optional = false python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] [package.extras] -diagrams = ["railroad-diagrams", "jinja2"] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" version = "7.1.3" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, + {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, +] [package.dependencies] attrs = ">=19.2.0" @@ -430,38 +713,47 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2. name = "pytest-cov" version = "4.0.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, + {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, +] [package.dependencies] coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytest-mock" version = "3.10.0" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-mock-3.10.0.tar.gz", hash = "sha256:fbbdb085ef7c252a326fd8cdcac0aa3b1333d8811f131bdcc701002e1be7ed4f"}, + {file = "pytest_mock-3.10.0-py3-none-any.whl", hash = "sha256:f4c973eeae0282963eb293eb173ce91b091a79c1334455acfac9ddee8a1c784b"}, +] [package.dependencies] pytest = ">=5.0" [package.extras] -dev = ["pre-commit", "tox", "pytest-asyncio"] +dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] [package.dependencies] six = ">=1.5" @@ -470,9 +762,11 @@ six = ">=1.5" name = "python-multipart" version = "0.0.5" description = "A streaming multipart parser for Python" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, +] [package.dependencies] six = ">=1.4.0" @@ -481,25 +775,147 @@ six = ">=1.4.0" name = "pyyaml" version = "5.4.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, +] [[package]] name = "regex" version = "2022.9.13" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "regex-2022.9.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0394265391a86e2bbaa7606e59ac71bd9f1edf8665a59e42771a9c9adbf6fd4f"}, + {file = "regex-2022.9.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86df2049b18745f3cd4b0f4c4ef672bfac4b80ca488e6ecfd2bbfe68d2423a2c"}, + {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce331b076b2b013e7d7f07157f957974ef0b0881a808e8a4a4b3b5105aee5d04"}, + {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:360ffbc9357794ae41336b681dff1c0463193199dfb91fcad3ec385ea4972f46"}, + {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18e503b1e515a10282b3f14f1b3d856194ecece4250e850fad230842ed31227f"}, + {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e167d1ccd41d27b7b6655bb7a2dcb1b1eb1e0d2d662043470bd3b4315d8b2b"}, + {file = "regex-2022.9.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4146cb7ae6029fc83b5c905ec6d806b7e5568dc14297c423e66b86294bad6c39"}, + {file = "regex-2022.9.13-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a1aec4ae549fd7b3f52ceaf67e133010e2fba1538bf4d5fc5cd162a5e058d5df"}, + {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cab548d6d972e1de584161487b2ac1aa82edd8430d1bde69587ba61698ad1cfb"}, + {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3d64e1a7e6d98a4cdc8b29cb8d8ed38f73f49e55fbaa737bdb5933db99b9de22"}, + {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:67a4c625361db04ae40ef7c49d3cbe2c1f5ff10b5a4491327ab20f19f2fb5d40"}, + {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:5d0dd8b06896423211ce18fba0c75dacc49182a1d6514c004b535be7163dca0f"}, + {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4318f69b79f9f7d84a7420e97d4bfe872dc767c72f891d4fea5fa721c74685f7"}, + {file = "regex-2022.9.13-cp310-cp310-win32.whl", hash = "sha256:26df88c9636a0c3f3bd9189dd435850a0c49d0b7d6e932500db3f99a6dd604d1"}, + {file = "regex-2022.9.13-cp310-cp310-win_amd64.whl", hash = "sha256:6fe1dd1021e0f8f3f454ce2811f1b0b148f2d25bb38c712fec00316551e93650"}, + {file = "regex-2022.9.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83cc32a1a2fa5bac00f4abc0e6ce142e3c05d3a6d57e23bd0f187c59b4e1e43b"}, + {file = "regex-2022.9.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2effeaf50a6838f3dd4d3c5d265f06eabc748f476e8441892645ae3a697e273"}, + {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a786a55d00439d8fae4caaf71581f2aaef7297d04ee60345c3594efef5648a"}, + {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b701dbc124558fd2b1b08005eeca6c9160e209108fbcbd00091fcfac641ac7"}, + {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dab81cc4d58026861445230cfba27f9825e9223557926e7ec22156a1a140d55c"}, + {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0c5cc3d1744a67c3b433dce91e5ef7c527d612354c1f1e8576d9e86bc5c5e2"}, + {file = "regex-2022.9.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:518272f25da93e02af4f1e94985f5042cec21557ef3591027d0716f2adda5d0a"}, + {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8418ee2cb857b83881b8f981e4c636bc50a0587b12d98cb9b947408a3c484fe7"}, + {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cfa4c956ff0a977c4823cb3b930b0a4e82543b060733628fec7ab3eb9b1abe37"}, + {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a1c4d17879dd4c4432c08a1ca1ab379f12ab54af569e945b6fc1c4cf6a74ca45"}, + {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:77c2879d3ba51e5ca6c2b47f2dcf3d04a976a623a8fc8236010a16c9e0b0a3c7"}, + {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2885ec6eea629c648ecc9bde0837ec6b92208b7f36381689937fe5d64a517e8"}, + {file = "regex-2022.9.13-cp311-cp311-win32.whl", hash = "sha256:2dda4b096a6f630d6531728a45bd12c67ec3badf44342046dc77d4897277d4f2"}, + {file = "regex-2022.9.13-cp311-cp311-win_amd64.whl", hash = "sha256:592b9e2e1862168e71d9e612bfdc22c451261967dbd46681f14e76dfba7105fd"}, + {file = "regex-2022.9.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:df8fe00b60e4717662c7f80c810ba66dcc77309183c76b7754c0dff6f1d42054"}, + {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:995e70bb8c91d1b99ed2aaf8ec44863e06ad1dfbb45d7df95f76ef583ec323a9"}, + {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad75173349ad79f9d21e0d0896b27dcb37bfd233b09047bc0b4d226699cf5c87"}, + {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7681c49da1a2d4b905b4f53d86c9ba4506e79fba50c4a664d9516056e0f7dfcc"}, + {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bc8edc5f8ef0ebb46f3fa0d02bd825bbe9cc63d59e428ffb6981ff9672f6de1"}, + {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bee775ff05c9d519195bd9e8aaaccfe3971db60f89f89751ee0f234e8aeac5"}, + {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1a901ce5cd42658ab8f8eade51b71a6d26ad4b68c7cfc86b87efc577dfa95602"}, + {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:14a7ab070fa3aec288076eed6ed828587b805ef83d37c9bfccc1a4a7cfbd8111"}, + {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d23ac6b4bf9e32fcde5fcdb2e1fd5e7370d6693fcac51ee1d340f0e886f50d1f"}, + {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:4cdbfa6d2befeaee0c899f19222e9b20fc5abbafe5e9c43a46ef819aeb7b75e5"}, + {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ab07934725e6f25c6f87465976cc69aef1141e86987af49d8c839c3ffd367c72"}, + {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d2a1371dc73e921f3c2e087c05359050f3525a9a34b476ebc8130e71bec55e97"}, + {file = "regex-2022.9.13-cp36-cp36m-win32.whl", hash = "sha256:fcbd1edff1473d90dc5cf4b52d355cf1f47b74eb7c85ba6e45f45d0116b8edbd"}, + {file = "regex-2022.9.13-cp36-cp36m-win_amd64.whl", hash = "sha256:fe428822b7a8c486bcd90b334e9ab541ce6cc0d6106993d59f201853e5e14121"}, + {file = "regex-2022.9.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d7430f041755801b712ec804aaf3b094b9b5facbaa93a6339812a8e00d7bd53a"}, + {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:079c182f99c89524069b9cd96f5410d6af437e9dca576a7d59599a574972707e"}, + {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59bac44b5a07b08a261537f652c26993af9b1bbe2a29624473968dd42fc29d56"}, + {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a59d0377e58d96a6f11636e97992f5b51b7e1e89eb66332d1c01b35adbabfe8a"}, + {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9d68eb704b24bc4d441b24e4a12653acd07d2c39940548761e0985a08bc1fff"}, + {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0385d66e73cdd4462f3cc42c76a6576ddcc12472c30e02a2ae82061bff132c32"}, + {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:db45016364eec9ddbb5af93c8740c5c92eb7f5fc8848d1ae04205a40a1a2efc6"}, + {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:03ff695518482b946a6d3d4ce9cbbd99a21320e20d94913080aa3841f880abcd"}, + {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6b32b45433df1fad7fed738fe15200b6516da888e0bd1fdd6aa5e50cc16b76bc"}, + {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:003a2e1449d425afc817b5f0b3d4c4aa9072dd5f3dfbf6c7631b8dc7b13233de"}, + {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:a9eb9558e1d0f78e07082d8a70d5c4d631c8dd75575fae92105df9e19c736730"}, + {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f6e0321921d2fdc082ef90c1fd0870f129c2e691bfdc4937dcb5cd308aba95c4"}, + {file = "regex-2022.9.13-cp37-cp37m-win32.whl", hash = "sha256:3f3b4594d564ed0b2f54463a9f328cf6a5b2a32610a90cdff778d6e3e561d08b"}, + {file = "regex-2022.9.13-cp37-cp37m-win_amd64.whl", hash = "sha256:8aba0d01e3dfd335f2cb107079b07fdddb4cd7fb2d8c8a1986f9cb8ce9246c24"}, + {file = "regex-2022.9.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:944567bb08f52268d8600ee5bdf1798b2b62ea002cc692a39cec113244cbdd0d"}, + {file = "regex-2022.9.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b664a4d33ffc6be10996606dfc25fd3248c24cc589c0b139feb4c158053565e"}, + {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f06cc1190f3db3192ab8949e28f2c627e1809487e2cfc435b6524c1ce6a2f391"}, + {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c57d50d4d5eb0c862569ca3c840eba2a73412f31d9ecc46ef0d6b2e621a592b"}, + {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19a4da6f513045f5ba00e491215bd00122e5bd131847586522463e5a6b2bd65f"}, + {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a926339356fe29595f8e37af71db37cd87ff764e15da8ad5129bbaff35bcc5a6"}, + {file = "regex-2022.9.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:091efcfdd4178a7e19a23776dc2b1fafb4f57f4d94daf340f98335817056f874"}, + {file = "regex-2022.9.13-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:880dbeb6bdde7d926b4d8e41410b16ffcd4cb3b4c6d926280fea46e2615c7a01"}, + {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:73b985c9fc09a7896846e26d7b6f4d1fd5a20437055f4ef985d44729f9f928d0"}, + {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c0b7cb9598795b01f9a3dd3f770ab540889259def28a3bf9b2fa24d52edecba3"}, + {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:37e5a26e76c46f54b3baf56a6fdd56df9db89758694516413757b7d127d4c57b"}, + {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:99945ddb4f379bb9831c05e9f80f02f079ba361a0fb1fba1fc3b267639b6bb2e"}, + {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dcbcc9e72a791f622a32d17ff5011326a18996647509cac0609a7fc43adc229"}, + {file = "regex-2022.9.13-cp38-cp38-win32.whl", hash = "sha256:d3102ab9bf16bf541ca228012d45d88d2a567c9682a805ae2c145a79d3141fdd"}, + {file = "regex-2022.9.13-cp38-cp38-win_amd64.whl", hash = "sha256:14216ea15efc13f28d0ef1c463d86d93ca7158a79cd4aec0f9273f6d4c6bb047"}, + {file = "regex-2022.9.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9a165a05979e212b2c2d56a9f40b69c811c98a788964e669eb322de0a3e420b4"}, + {file = "regex-2022.9.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:14c71437ffb89479c89cc7022a5ea2075a842b728f37205e47c824cc17b30a42"}, + {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee7045623a5ace70f3765e452528b4c1f2ce669ed31959c63f54de64fe2f6ff7"}, + {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6e521d9db006c5e4a0f8acfef738399f72b704913d4e083516774eb51645ad7c"}, + {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b86548b8234b2be3985dbc0b385e35f5038f0f3e6251464b827b83ebf4ed90e5"}, + {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b39ee3b280e15824298b97cec3f7cbbe6539d8282cc8a6047a455b9a72c598"}, + {file = "regex-2022.9.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6e6e61e9a38b6cc60ca3e19caabc90261f070f23352e66307b3d21a24a34aaf"}, + {file = "regex-2022.9.13-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d837ccf3bd2474feabee96cd71144e991472e400ed26582edc8ca88ce259899c"}, + {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6adfe300848d61a470ec7547adc97b0ccf86de86a99e6830f1d8c8d19ecaf6b3"}, + {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d5b003d248e6f292475cd24b04e5f72c48412231961a675edcb653c70730e79e"}, + {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d5edd3eb877c9fc2e385173d4a4e1d792bf692d79e25c1ca391802d36ecfaa01"}, + {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:50e764ffbd08b06aa8c4e86b8b568b6722c75d301b33b259099f237c46b2134e"}, + {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d43bd402b27e0e7eae85c612725ba1ce7798f20f6fab4e8bc3de4f263294f03"}, + {file = "regex-2022.9.13-cp39-cp39-win32.whl", hash = "sha256:7fcf7f94ccad19186820ac67e2ec7e09e0ac2dac39689f11cf71eac580503296"}, + {file = "regex-2022.9.13-cp39-cp39-win_amd64.whl", hash = "sha256:322bd5572bed36a5b39952d88e072738926759422498a96df138d93384934ff8"}, + {file = "regex-2022.9.13.tar.gz", hash = "sha256:f07373b6e56a6f3a0df3d75b651a278ca7bd357a796078a26a958ea1ce0588fd"}, +] [[package]] name = "requests" version = "2.28.1" description = "Python HTTP for Humans." -category = "dev" optional = false python-versions = ">=3.7, <4" +files = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] [package.dependencies] certifi = ">=2017.4.17" @@ -509,15 +925,18 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rfc3986" version = "1.5.0" description = "Validating URI References per RFC 3986" -category = "main" optional = false python-versions = "*" +files = [ + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, +] [package.dependencies] idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} @@ -529,55 +948,89 @@ idna2008 = ["idna"] name = "safety" version = "1.10.3" description = "Checks installed dependencies for known vulnerabilities." -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, + {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, +] [package.dependencies] Click = ">=6.0" dparse = ">=0.5.1" packaging = "*" requests = "*" +setuptools = "*" + +[[package]] +name = "setuptools" +version = "68.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shellingham" version = "1.5.0" description = "Tool to Detect Surrounding Shell" -category = "main" optional = false python-versions = ">=3.4" +files = [ + {file = "shellingham-1.5.0-py2.py3-none-any.whl", hash = "sha256:a8f02ba61b69baaa13facdba62908ca8690a94b8119b69f5ec5873ea85f7391b"}, + {file = "shellingham-1.5.0.tar.gz", hash = "sha256:72fb7f5c63103ca2cb91b23dee0c71fe8ad6fbfd46418ef17dbe40db51592dad"}, +] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] [[package]] name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] [[package]] name = "stringcase" version = "1.2.0" description = "String case converter." -category = "main" optional = false python-versions = "*" +files = [ + {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, +] [[package]] name = "taskipy" version = "1.10.3" description = "tasks runner for python projects" -category = "dev" optional = false python-versions = ">=3.6,<4.0" +files = [ + {file = "taskipy-1.10.3-py3-none-any.whl", hash = "sha256:4c0070ca53868d97989f7ab5c6f237525d52ee184f9b967576e8fe427ed9d0b8"}, + {file = "taskipy-1.10.3.tar.gz", hash = "sha256:112beaf21e3d5569950b99162a1de003fa885fabee9e450757a6b874be914877"}, +] [package.dependencies] colorama = ">=0.4.4,<0.5.0" @@ -589,293 +1042,120 @@ tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version >= \"3.7\" and py name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] [[package]] name = "typed-ast" version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, +] [[package]] name = "typer" version = "0.3.2" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, + {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, +] [package.dependencies] click = ">=7.1.1,<7.2.0" [package.extras] -test = ["pytest-xdist (>=1.32.0,<2.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "mypy (==0.782)", "black (>=19.10b0,<20.0b0)", "isort (>=5.0.6,<6.0.0)", "shellingham (>=1.3.0,<2.0.0)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "coverage (>=5.2,<6.0)"] all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"] dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)"] -doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown-include (>=0.5.1,<0.6.0)"] +doc = ["markdown-include (>=0.5.1,<0.6.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)"] +test = ["black (>=19.10b0,<20.0b0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.782)", "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)"] [[package]] name = "typing-extensions" version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, +] [[package]] name = "urllib3" version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" +files = [ + {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, + {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, +] [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "zipp" version = "3.9.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "zipp-3.9.0-py3-none-any.whl", hash = "sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980"}, + {file = "zipp-3.9.0.tar.gz", hash = "sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb"}, +] [package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] -lock-version = "1.1" +lock-version = "2.0" python-versions = "^3.7" content-hash = "f852408a0681affc04125fdef3479d4734bc970a0254296383efb0484067d56c" - -[metadata.files] -anyio = [ - {file = "anyio-3.6.1-py3-none-any.whl", hash = "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"}, - {file = "anyio-3.6.1.tar.gz", hash = "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b"}, -] -appdirs = [ - {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, - {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, -] -attrs = [] -autoflake = [] -black = [] -certifi = [] -charset-normalizer = [] -click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, -] -colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, -] -coverage = [] -dparse = [] -flake8 = [] -h11 = [ - {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, - {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, -] -httpcore = [] -httpx = [] -idna = [] -importlib-metadata = [] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -isort = [ - {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, - {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, -] -jinja2 = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] -markupsafe = [ - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, - {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, -] -mccabe = [] -mslex = [ - {file = "mslex-0.3.0-py2.py3-none-any.whl", hash = "sha256:380cb14abf8fabf40e56df5c8b21a6d533dc5cbdcfe42406bbf08dda8f42e42a"}, - {file = "mslex-0.3.0.tar.gz", hash = "sha256:4a1ac3f25025cad78ad2fe499dd16d42759f7a3801645399cce5c404415daa97"}, -] -mypy = [] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -pathspec = [] -pep8 = [] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -psutil = [] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -pydantic = [] -pyflakes = [] -pyparsing = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] -pytest = [] -pytest-cov = [] -pytest-mock = [] -python-dateutil = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] -python-multipart = [] -pyyaml = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, -] -regex = [] -requests = [] -rfc3986 = [ - {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, - {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, -] -safety = [] -shellingham = [] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -sniffio = [] -stringcase = [ - {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, -] -taskipy = [] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -typed-ast = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, -] -typer = [ - {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, - {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, -] -typing-extensions = [] -urllib3 = [] -zipp = []