Example #1
0
        def main():
            Foo = ForwardRef('Foo')

            class Foo(BaseModel):
                a: int = 123
                b: Foo = None

            Foo.update_forward_refs()
            return Foo
Example #2
0
    def module():
        from pydantic import BaseModel
        from pydantic.typing import ForwardRef

        Foo = ForwardRef('Foo')

        class Foo(BaseModel):
            a: int = 123
            b: 'Foo' = None

        Foo.update_forward_refs()
Example #3
0
    def module():
        from typing import Dict, List

        from pydantic import BaseModel
        from pydantic.typing import ForwardRef

        Foo = ForwardRef('Foo')

        class Foo(BaseModel):
            a: int = 123
            b: Foo = None
            c: List[Foo] = []
            d: Dict[str, Foo] = {}

        Foo.update_forward_refs()
Example #4
0
async def test_not_updated_model_m2m_raises_errors():
    Person3Ref = ForwardRef("Person3")

    class PersonFriend(ormar.Model):
        class Meta(ModelMeta):
            metadata = metadata
            database = db

    class Person3(ormar.Model):
        class Meta(ModelMeta):
            metadata = metadata
            database = db

        id: int = ormar.Integer(primary_key=True)
        name: str = ormar.String(max_length=100)
        supervisors: Person3Ref = ormar.ManyToMany(Person3Ref,
                                                   through=PersonFriend,
                                                   related_name="employees")

    with pytest.raises(ModelError):
        await Person3.objects.create(name="Test")

    with pytest.raises(ModelError):
        Person3(name="Test")

    with pytest.raises(ModelError):
        await Person3.objects.get()
Example #5
0
async def test_not_updated_model_m2m_through_raises_errors():
    PersonPetRef = ForwardRef("PersonPet")

    class Pet(ormar.Model):
        class Meta(ModelMeta):
            metadata = metadata
            database = db

        id: int = ormar.Integer(primary_key=True)
        name: str = ormar.String(max_length=100)

    class Person4(ormar.Model):
        class Meta(ModelMeta):
            metadata = metadata
            database = db

        id: int = ormar.Integer(primary_key=True)
        name: str = ormar.String(max_length=100)
        pets: List[Pet] = ormar.ManyToMany(Pet,
                                           through=PersonPetRef,
                                           related_name="owners")

    class PersonPet(ormar.Model):
        class Meta(ModelMeta):
            metadata = metadata
            database = db

    with pytest.raises(ModelError):
        await Person4.objects.create(name="Test")

    with pytest.raises(ModelError):
        Person4(name="Test")

    with pytest.raises(ModelError):
        await Person4.objects.get()
Example #6
0
def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str,
                                                                  Any]) -> Any:
    annotation = param.annotation
    if isinstance(annotation, str):
        annotation = ForwardRef(annotation)
        annotation = evaluate_forwardref(annotation, globalns, globalns)
    return annotation
Example #7
0
def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str, Any]) -> Any:
    annotation = param.annotation
    if isinstance(annotation, str):
        # Temporary ignore type
        # Ref: https://github.com/samuelcolvin/pydantic/issues/1738
        annotation = ForwardRef(annotation)  # type: ignore
        annotation = evaluate_forwardref(annotation, globalns, globalns)
    return annotation
Example #8
0
class Post2(ormar.Model):
    class Meta(BaseMeta):
        pass

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    categories = ormar.ManyToMany(Category,
                                  through=ForwardRef("PostCategory2"))
Example #9
0
def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str, Any]) -> Any:
    annotation = param.annotation
    if isinstance(annotation, str):
        try:
            annotation = ForwardRef(annotation)  # type: ignore
            annotation = evaluate_forwardref(annotation, globalns, globalns)
        except (TypeError, NameError):
            annotation = param.annotation
    return annotation
Example #10
0
    def module():
        from pydantic import BaseModel
        from pydantic.typing import ForwardRef

        Foo = ForwardRef('Foo')

        class Foo(BaseModel):
            a: int = 123
            b: Foo = None
Example #11
0
def test_forward_ref_one_of_fields_not_defined(create_module):
    @create_module
    def module():
        from pydantic import BaseModel

        class Foo(BaseModel):
            foo: 'Foo'
            bar: 'Bar'  # noqa: F821

    from pydantic.typing import ForwardRef

    assert module.Foo.__fields__['bar'].type_ == ForwardRef('Bar')
    assert module.Foo.__fields__['foo'].type_ is module.Foo
Example #12
0
def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str,
                                                                  Any]) -> Any:
    annotation = param.annotation
    if isinstance(annotation, str):
        annotation = ForwardRef(annotation)
        try:
            annotation = evaluate_forwardref(annotation, globalns, globalns)
        except Exception as e:
            logger.opt(colors=True, exception=e).warning(
                f'Unknown ForwardRef["{param.annotation}"] for parameter {param.name}'
            )
            return inspect.Parameter.empty
    return annotation
Example #13
0
    def module():
        from typing import Optional

        from pydantic import BaseModel
        from pydantic.typing import ForwardRef

        class Foo(BaseModel):
            a: int

        FooRef = ForwardRef('Foo')

        class Bar(BaseModel):
            b: Optional[FooRef]
Example #14
0
    def module():
        from typing import List

        import pytest

        from pydantic import BaseModel, Field
        from pydantic.typing import ForwardRef

        Foo = ForwardRef('Foo')

        with pytest.raises(
            ValueError, match='On field "c" the following field constraints are set but not enforced: gt.'
        ):

            class Foo(BaseModel):
                c: List[Foo] = Field(..., gt=0)
Example #15
0
    def module():
        from typing import Tuple, Union

        from pydantic import BaseModel
        from pydantic.typing import ForwardRef

        class Leaf(BaseModel):
            a: str

        TreeType = Union[Union[Tuple[ForwardRef('Node'), str], int], Leaf]

        class Node(BaseModel):
            value: int
            left: TreeType
            right: TreeType

        Node.update_forward_refs()
Example #16
0
def test_forward_ref_auto_update_no_model(create_module):
    module = create_module(
        # language=Python
        """
from pydantic import BaseModel

class Foo(BaseModel):
    a: 'Bar'

class Bar(BaseModel):
    b: 'Foo'
""")

    from pydantic.typing import ForwardRef

    assert module.Foo.__fields__['a'].type_ == ForwardRef('Bar')
    assert module.Bar.__fields__['b'].type_ is module.Foo
Example #17
0
def get_typed_annotation(
    dependency_param: inspect.Parameter,
    global_namespace: Dict[str, Any],
) -> Any:
    """Solve forward reference annotation for instance of `inspect.Parameter`.

    Arguments:
        dependency_param: instance of `inspect.Parameter` for which possible forward
            annotation will be evaluated.
        global_namespace: dictionary of entities that can be used for evaluating
            forward references.

    Returns:
        Parameter annotation.
    """
    annotation = dependency_param.annotation
    if isinstance(annotation, str):
        annotation = ForwardRef(annotation)
        annotation = evaluate_forwardref(annotation, global_namespace, global_namespace)
    return annotation
Example #18
0
async def test_not_updated_model_raises_errors():
    Person2Ref = ForwardRef("Person2")

    class Person2(ormar.Model):
        class Meta(ModelMeta):
            metadata = metadata
            database = db

        id: int = ormar.Integer(primary_key=True)
        name: str = ormar.String(max_length=100)
        supervisor: Person2Ref = ormar.ForeignKey(Person2Ref,
                                                  related_name="employees")

    with pytest.raises(ModelError):
        await Person2.objects.create(name="Test")

    with pytest.raises(ModelError):
        Person2(name="Test")

    with pytest.raises(ModelError):
        await Person2.objects.get()
Example #19
0
# nested decorator should not produce an error
@validate_arguments(config={'arbitrary_types_allowed': True})
def bar(a: int, *, c: str = 'x') -> str:
    return c * a


bar(1, c='thing')
bar(1)


class Foo(BaseModel):
    a: int


FooRef = ForwardRef('Foo')


class MyConf(BaseModel):
    str_pyobject: PyObject = Field('datetime.date')
    callable_pyobject: PyObject = Field(date)


conf = MyConf()
var1: date = conf.str_pyobject(2020, 12, 20)
var2: date = conf.callable_pyobject(2111, 1, 1)


class MyPrivateAttr(BaseModel):
    _private_field: str = PrivateAttr()
Example #20
0
def make_forwardref(annotation: str, globalns: Dict[str, Any]):
    annotation = ForwardRef(annotation)
    annotation = evaluate_forwardref(annotation, globalns, globalns)
    return annotation
import databases
import pytest
import sqlalchemy as sa
from pydantic.typing import ForwardRef
from sqlalchemy import create_engine

import ormar
from ormar import ModelMeta
from tests.settings import DATABASE_URL

metadata = sa.MetaData()
db = databases.Database(DATABASE_URL)
engine = create_engine(DATABASE_URL)

TeacherRef = ForwardRef("Teacher")


class Student(ormar.Model):
    class Meta(ModelMeta):
        metadata = metadata
        database = db

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    primary_teacher: TeacherRef = ormar.ForeignKey(TeacherRef,
                                                   related_name="own_students")


class StudentTeacher(ormar.Model):
    class Meta(ModelMeta):
Example #22
0
class FieldPropertyWithDstId(BaseModel):
    datasheetId: str
    field: ForwardRef("MetaField")
Example #23
0
def make_forwardref(annotation: str, globalns: DictStrAny) -> Any:
    forward_ref = ForwardRef(annotation)
    return evaluate_forwardref(forward_ref, globalns, globalns)
Example #24
0
def _extract_relations(
    mapper: Mapper,
    fields: Dict,
    reverse: bool,
    metadata: MetaData,
    database: Database,
    db_model: Type,
) -> Dict:
    for attr in mapper.attrs:  # type: ignore
        if isinstance(attr, sqlalchemy.orm.RelationshipProperty):
            # skip one to many, it will be populated later by ormar
            # if attr.direction.name == "ONETOMANY":
            #     continue
            if attr.direction.name == "MANYTOONE":
                # we use forward ref as target might not be populated
                target_sqlalchemy = attr.entity.class_
                if (
                    target_sqlalchemy not in PARSED_MODELS
                    and target_sqlalchemy not in CURRENTLY_PROCESSED
                    and not target_sqlalchemy == db_model
                ):
                    PARSED_MODELS[target_sqlalchemy] = sqlalchemy_to_ormar(
                        target_sqlalchemy, metadata=metadata, database=database
                    )
                    target = PARSED_MODELS[target_sqlalchemy]
                else:
                    target = ForwardRef(target_sqlalchemy.__name__)  # type: ignore

                column = next(iter(attr.local_columns))
                sql_fk = next(iter(column.foreign_keys))
                fields[attr.key] = dict(
                    type=ormar.ForeignKey,
                    to=target,
                    name=column.key,
                    related_name=attr.back_populates,
                    onupdate=getattr(sql_fk, "onupdate", None),
                    ondelete=getattr(sql_fk, "ondelete", None),
                )
            elif attr.direction.name == "MANYTOMANY":
                target_sqlalchemy = attr.entity.class_
                if target_sqlalchemy not in PARSED_MODELS and not reverse:
                    PARSED_MODELS[target_sqlalchemy] = sqlalchemy_to_ormar(
                        target_sqlalchemy,
                        metadata=metadata,
                        database=database,
                        reverse=True,
                    )
                else:  # pragma: no cover
                    # target model already should have m2m relation
                    continue
                target = PARSED_MODELS[target_sqlalchemy]
                through_table_name = attr.secondary.key
                fields[attr.key] = dict(
                    type=ormar.ManyToMany,
                    to=target,
                    through=create_through_model(
                        class_name=through_table_name.title(),
                        table_name=through_table_name,
                        metadata=metadata,
                        database=database,
                    ),
                    related_name=attr.back_populates,
                )
    return fields
Example #25
0
def test_resolve_annotations_no_module():
    # TODO: is there a better test for this, can this case really happen?
    fr = ForwardRef('Foo')
    assert resolve_annotations({'Foo': ForwardRef('Foo')}, None) == {'Foo': fr}
Example #26
0
import databases
import pytest
import sqlalchemy as sa
from pydantic.typing import ForwardRef
from sqlalchemy import create_engine

import ormar
from ormar import ModelMeta
from ormar.exceptions import ModelError
from tests.settings import DATABASE_URL

metadata = sa.MetaData()
db = databases.Database(DATABASE_URL)
engine = create_engine(DATABASE_URL)

PersonRef = ForwardRef("Person")


class Person(ormar.Model):
    class Meta(ModelMeta):
        metadata = metadata
        database = db

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    supervisor: PersonRef = ormar.ForeignKey(PersonRef,
                                             related_name="employees")


Person.update_forward_refs()