|
27 | 27 | import sys
|
28 | 28 | from datetime import datetime
|
29 | 29 | from hashlib import md5
|
30 |
| -from typing import Any, ClassVar, Dict, List, Optional |
| 30 | +from typing import Annotated, Any, ClassVar, Dict, List, Optional |
31 | 31 |
|
32 | 32 | import pytest
|
33 | 33 | from pytest import raises
|
@@ -530,7 +530,7 @@ def test_document_inheritance() -> None:
|
530 | 530 | } == MySubDoc._doc_type.mapping.to_dict()
|
531 | 531 |
|
532 | 532 |
|
533 |
| -def test_child_class_can_override_parent() -> None: |
| 533 | +def test_childdoc_class_can_override_parent() -> None: |
534 | 534 | class A(AsyncDocument):
|
535 | 535 | o = field.Object(dynamic=False, properties={"a": field.Text()})
|
536 | 536 |
|
@@ -679,117 +679,145 @@ class TypedDoc(AsyncDocument):
|
679 | 679 | i1: ClassVar
|
680 | 680 | i2: ClassVar[int]
|
681 | 681 |
|
682 |
| - props = TypedDoc._doc_type.mapping.to_dict()["properties"] |
683 |
| - assert props == { |
684 |
| - "st": {"type": "text"}, |
685 |
| - "dt": {"type": "date"}, |
686 |
| - "li": {"type": "integer"}, |
687 |
| - "ob": { |
688 |
| - "type": "object", |
689 |
| - "properties": { |
690 |
| - "st": {"type": "text"}, |
691 |
| - "dt": {"type": "date"}, |
692 |
| - "li": {"type": "integer"}, |
| 682 | + class TypedDocAnnotated(AsyncDocument): |
| 683 | + st: Annotated[str, "foo"] |
| 684 | + dt: Annotated[Optional[datetime], "bar"] |
| 685 | + li: Annotated[List[int], "baz"] |
| 686 | + ob: Annotated[TypedInnerDoc, "qux"] |
| 687 | + ns: Annotated[List[TypedInnerDoc], "quux"] |
| 688 | + ip: Annotated[Optional[str], field.Ip()] |
| 689 | + k1: Annotated[str, field.Keyword(required=True)] |
| 690 | + k2: Annotated[M[str], field.Keyword()] |
| 691 | + k3: Annotated[str, mapped_field(field.Keyword(), default="foo")] |
| 692 | + k4: Annotated[M[Optional[str]], mapped_field(field.Keyword())] # type: ignore[misc] |
| 693 | + s1: Annotated[Secret, SecretField()] |
| 694 | + s2: Annotated[M[Secret], SecretField()] |
| 695 | + s3: Annotated[Secret, mapped_field(SecretField())] # type: ignore[misc] |
| 696 | + s4: Annotated[ |
| 697 | + M[Optional[Secret]], |
| 698 | + mapped_field(SecretField(), default_factory=lambda: "foo"), |
| 699 | + ] |
| 700 | + if sys.version_info[0] > 3 or ( |
| 701 | + sys.version_info[0] == 3 and sys.version_info[1] >= 11 |
| 702 | + ): |
| 703 | + i1: Annotated[ClassVar, "classvar"] |
| 704 | + i2: Annotated[ClassVar[int], "classvar"] |
| 705 | + else: |
| 706 | + i1: ClassVar |
| 707 | + i2: ClassVar[int] |
| 708 | + |
| 709 | + for doc_class in [TypedDoc, TypedDocAnnotated]: |
| 710 | + props = doc_class._doc_type.mapping.to_dict()["properties"] |
| 711 | + assert props == { |
| 712 | + "st": {"type": "text"}, |
| 713 | + "dt": {"type": "date"}, |
| 714 | + "li": {"type": "integer"}, |
| 715 | + "ob": { |
| 716 | + "type": "object", |
| 717 | + "properties": { |
| 718 | + "st": {"type": "text"}, |
| 719 | + "dt": {"type": "date"}, |
| 720 | + "li": {"type": "integer"}, |
| 721 | + }, |
693 | 722 | },
|
694 |
| - }, |
695 |
| - "ns": { |
696 |
| - "type": "nested", |
697 |
| - "properties": { |
698 |
| - "st": {"type": "text"}, |
699 |
| - "dt": {"type": "date"}, |
700 |
| - "li": {"type": "integer"}, |
| 723 | + "ns": { |
| 724 | + "type": "nested", |
| 725 | + "properties": { |
| 726 | + "st": {"type": "text"}, |
| 727 | + "dt": {"type": "date"}, |
| 728 | + "li": {"type": "integer"}, |
| 729 | + }, |
701 | 730 | },
|
702 |
| - }, |
703 |
| - "ip": {"type": "ip"}, |
704 |
| - "k1": {"type": "keyword"}, |
705 |
| - "k2": {"type": "keyword"}, |
706 |
| - "k3": {"type": "keyword"}, |
707 |
| - "k4": {"type": "keyword"}, |
708 |
| - "s1": {"type": "text"}, |
709 |
| - "s2": {"type": "text"}, |
710 |
| - "s3": {"type": "text"}, |
711 |
| - "s4": {"type": "text"}, |
712 |
| - } |
| 731 | + "ip": {"type": "ip"}, |
| 732 | + "k1": {"type": "keyword"}, |
| 733 | + "k2": {"type": "keyword"}, |
| 734 | + "k3": {"type": "keyword"}, |
| 735 | + "k4": {"type": "keyword"}, |
| 736 | + "s1": {"type": "text"}, |
| 737 | + "s2": {"type": "text"}, |
| 738 | + "s3": {"type": "text"}, |
| 739 | + "s4": {"type": "text"}, |
| 740 | + } |
713 | 741 |
|
714 |
| - TypedDoc.i1 = "foo" |
715 |
| - TypedDoc.i2 = 123 |
| 742 | + doc_class.i1 = "foo" |
| 743 | + doc_class.i2 = 123 |
| 744 | + |
| 745 | + doc = doc_class() |
| 746 | + assert doc.k3 == "foo" |
| 747 | + assert doc.s4 == "foo" |
| 748 | + with raises(ValidationException) as exc_info: |
| 749 | + doc.full_clean() |
| 750 | + assert set(exc_info.value.args[0].keys()) == { |
| 751 | + "st", |
| 752 | + "k1", |
| 753 | + "k2", |
| 754 | + "ob", |
| 755 | + "s1", |
| 756 | + "s2", |
| 757 | + "s3", |
| 758 | + } |
716 | 759 |
|
717 |
| - doc = TypedDoc() |
718 |
| - assert doc.k3 == "foo" |
719 |
| - assert doc.s4 == "foo" |
720 |
| - with raises(ValidationException) as exc_info: |
| 760 | + assert doc_class.i1 == "foo" |
| 761 | + assert doc_class.i2 == 123 |
| 762 | + |
| 763 | + doc.st = "s" |
| 764 | + doc.li = [1, 2, 3] |
| 765 | + doc.k1 = "k1" |
| 766 | + doc.k2 = "k2" |
| 767 | + doc.ob.st = "s" |
| 768 | + doc.ob.li = [1] |
| 769 | + doc.s1 = "s1" |
| 770 | + doc.s2 = "s2" |
| 771 | + doc.s3 = "s3" |
721 | 772 | doc.full_clean()
|
722 |
| - assert set(exc_info.value.args[0].keys()) == { |
723 |
| - "st", |
724 |
| - "k1", |
725 |
| - "k2", |
726 |
| - "ob", |
727 |
| - "s1", |
728 |
| - "s2", |
729 |
| - "s3", |
730 |
| - } |
731 | 773 |
|
732 |
| - assert TypedDoc.i1 == "foo" |
733 |
| - assert TypedDoc.i2 == 123 |
734 |
| - |
735 |
| - doc.st = "s" |
736 |
| - doc.li = [1, 2, 3] |
737 |
| - doc.k1 = "k1" |
738 |
| - doc.k2 = "k2" |
739 |
| - doc.ob.st = "s" |
740 |
| - doc.ob.li = [1] |
741 |
| - doc.s1 = "s1" |
742 |
| - doc.s2 = "s2" |
743 |
| - doc.s3 = "s3" |
744 |
| - doc.full_clean() |
| 774 | + doc.ob = TypedInnerDoc(li=[1]) |
| 775 | + with raises(ValidationException) as exc_info: |
| 776 | + doc.full_clean() |
| 777 | + assert set(exc_info.value.args[0].keys()) == {"ob"} |
| 778 | + assert set(exc_info.value.args[0]["ob"][0].args[0].keys()) == {"st"} |
745 | 779 |
|
746 |
| - doc.ob = TypedInnerDoc(li=[1]) |
747 |
| - with raises(ValidationException) as exc_info: |
748 |
| - doc.full_clean() |
749 |
| - assert set(exc_info.value.args[0].keys()) == {"ob"} |
750 |
| - assert set(exc_info.value.args[0]["ob"][0].args[0].keys()) == {"st"} |
| 780 | + doc.ob.st = "s" |
| 781 | + doc.ns.append(TypedInnerDoc(li=[1, 2])) |
| 782 | + with raises(ValidationException) as exc_info: |
| 783 | + doc.full_clean() |
751 | 784 |
|
752 |
| - doc.ob.st = "s" |
753 |
| - doc.ns.append(TypedInnerDoc(li=[1, 2])) |
754 |
| - with raises(ValidationException) as exc_info: |
| 785 | + doc.ns[0].st = "s" |
755 | 786 | doc.full_clean()
|
756 | 787 |
|
757 |
| - doc.ns[0].st = "s" |
758 |
| - doc.full_clean() |
759 |
| - |
760 |
| - doc.ip = "1.2.3.4" |
761 |
| - n = datetime.now() |
762 |
| - doc.dt = n |
763 |
| - assert doc.to_dict() == { |
764 |
| - "st": "s", |
765 |
| - "li": [1, 2, 3], |
766 |
| - "dt": n, |
767 |
| - "ob": { |
| 788 | + doc.ip = "1.2.3.4" |
| 789 | + n = datetime.now() |
| 790 | + doc.dt = n |
| 791 | + assert doc.to_dict() == { |
768 | 792 | "st": "s",
|
769 |
| - "li": [1], |
770 |
| - }, |
771 |
| - "ns": [ |
772 |
| - { |
| 793 | + "li": [1, 2, 3], |
| 794 | + "dt": n, |
| 795 | + "ob": { |
773 | 796 | "st": "s",
|
774 |
| - "li": [1, 2], |
775 |
| - } |
776 |
| - ], |
777 |
| - "ip": "1.2.3.4", |
778 |
| - "k1": "k1", |
779 |
| - "k2": "k2", |
780 |
| - "k3": "foo", |
781 |
| - "s1": "s1", |
782 |
| - "s2": "s2", |
783 |
| - "s3": "s3", |
784 |
| - "s4": "foo", |
785 |
| - } |
| 797 | + "li": [1], |
| 798 | + }, |
| 799 | + "ns": [ |
| 800 | + { |
| 801 | + "st": "s", |
| 802 | + "li": [1, 2], |
| 803 | + } |
| 804 | + ], |
| 805 | + "ip": "1.2.3.4", |
| 806 | + "k1": "k1", |
| 807 | + "k2": "k2", |
| 808 | + "k3": "foo", |
| 809 | + "s1": "s1", |
| 810 | + "s2": "s2", |
| 811 | + "s3": "s3", |
| 812 | + "s4": "foo", |
| 813 | + } |
786 | 814 |
|
787 |
| - s = TypedDoc.search().sort(TypedDoc.st, -TypedDoc.dt, +TypedDoc.ob.st) |
788 |
| - s.aggs.bucket("terms_agg", "terms", field=TypedDoc.k1) |
789 |
| - assert s.to_dict() == { |
790 |
| - "aggs": {"terms_agg": {"terms": {"field": "k1"}}}, |
791 |
| - "sort": ["st", {"dt": {"order": "desc"}}, "ob.st"], |
792 |
| - } |
| 815 | + s = doc_class.search().sort(doc_class.st, -doc_class.dt, +doc_class.ob.st) |
| 816 | + s.aggs.bucket("terms_agg", "terms", field=doc_class.k1) |
| 817 | + assert s.to_dict() == { |
| 818 | + "aggs": {"terms_agg": {"terms": {"field": "k1"}}}, |
| 819 | + "sort": ["st", {"dt": {"order": "desc"}}, "ob.st"], |
| 820 | + } |
793 | 821 |
|
794 | 822 |
|
795 | 823 | @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10")
|
|
0 commit comments