Files
Samuel Colvin 594effa279 Switching to pydantic_core (#4516)
* working on core schema generation

* adapting main.py

* getting tests to run

* fix tests

* disable pyright, fix mypy

* moving to class-based model generation

* working on validators

* change how models are created

* start fixing test_main.py

* fixing mypy

* SelfType

* recursive models working, more tests fixed

* fix tests on <3.10

* get docs build to pass

* starting to cleanup types.py

* starting works on custom types

* working on using annotated-types

* using annoated types for constraints

* lots of cleanup, fixing network tests

* network tests passing 🎉

* working on types

* working on types and cleanup

* fixing UUID type, restructing again

* more types and newer pydantic-core

* working on Iterable

* more test_types tests

* support newer pydantic-core, fixing more test_types.py

* working through more test_types.py

* test_types.py at last passing locally 🎉

* fixing more tests in test_types.py

* fix datetime_parse tests and linting

* get tests running again, rename to test_datetime.py

* renaming internal modules

* working through mypy errors

* fixing mypy

* refactoring _generate_schema.py

* test_main.py passing

* uprev deps

* fix conftest and linting?

* importing Annotated

* ltining

* import Annotated from typing_extensions

* fixing 3.7 compatibility

* fixing tests on 3.9

* fix linting

* fixing SecretField and 3.9 tests

* customising get_type_hints

* ignore warnings on 3.11

* spliting repr out of utils

* removing unused bits of _repr, fix tests for 3.7

* more cleanup, removing many type aliases

* clean up repr

* support namedtuples and typeddicts

* test is_union

* removing errors, uprev pydantic-core

* fix tests on 3.8

* fixing private attributes and model_post_init

* renaming and cleanup

* remove unnecessary PydanticMetadata inheritance

* fixing forward refs and mypy tests

* fix signatures, change how xfail works

* revert mypy tests to 3.7 syntax

* correct model title

* try to fix tests

* fixing ClassVar forward refs

* uprev pydantic-core, new error format

* add "force" argument to model_rebuild

* Apply suggestions from code review

Suggestions from @tiangolo and @hramezani 🙏

Co-authored-by: Hasan Ramezani <hasan.r67@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>

* more suggestions from @tiangolo

* extra -> json_schema_extra on Field

Co-authored-by: Hasan Ramezani <hasan.r67@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-11-02 12:01:17 +00:00

83 lines
2.4 KiB
Python

import importlib
import inspect
import re
import secrets
import sys
import textwrap
from dataclasses import dataclass
from types import FunctionType
from typing import Any, Optional
import pytest
from _pytest.assertion.rewrite import AssertionRewritingHook
def _extract_source_code_from_function(function):
if function.__code__.co_argcount:
raise RuntimeError(f'function {function.__qualname__} cannot have any arguments')
code_lines = ''
body_started = False
for line in textwrap.dedent(inspect.getsource(function)).split('\n'):
if line.startswith('def '):
body_started = True
continue
elif body_started:
code_lines += f'{line}\n'
return textwrap.dedent(code_lines)
def _create_module_file(code, tmp_path, name):
name = f'{name}_{secrets.token_hex(5)}'
path = tmp_path / f'{name}.py'
path.write_text(code)
return name, str(path)
@pytest.fixture
def create_module(tmp_path, request):
def run(source_code_or_function, rewrite_assertions=True):
"""
Create module object, execute it and return
Can be used as a decorator of the function from the source code of which the module will be constructed
:param source_code_or_function string or function with body as a source code for created module
:param rewrite_assertions: whether to rewrite assertions in module or not
"""
if isinstance(source_code_or_function, FunctionType):
source_code = _extract_source_code_from_function(source_code_or_function)
else:
source_code = source_code_or_function
module_name, filename = _create_module_file(source_code, tmp_path, request.node.name)
if rewrite_assertions:
loader = AssertionRewritingHook(config=request.config)
loader.mark_rewrite(module_name)
else:
loader = None
spec = importlib.util.spec_from_file_location(module_name, filename, loader=loader)
sys.modules[module_name] = module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
return run
@dataclass
class Err:
message: str
errors: Optional[Any] = None
def __repr__(self):
if self.errors:
return f'Err({self.message!r}, errors={self.errors!r})'
else:
return f'Err({self.message!r})'
def message_escaped(self):
return re.escape(self.message)