Coverage for pyfields/tests/issues/test_issue_73.py: 94%

46 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-11-06 16:35 +0000

1import sys 

2 

3import pytest 

4from pyfields import FieldTypeError 

5 

6 

7@pytest.mark.skipif(sys.version_info < (3, 6), reason="class member annotations are not supported in python < 3.6") 

8@pytest.mark.parametrize('str_hint', [False, True], ids="str_hint={}".format) 

9@pytest.mark.parametrize('fix_in_class_field', [False, True], ids="fix_in_class_field={}".format) 

10def test_self_referenced_class(str_hint, fix_in_class_field): 

11 """Fix https://github.com/smarie/python-pyfields/issues/73 """ 

12 if str_hint: 

13 # this is the old behaviour that happens when PEP563 is not enabled at the top of the module 

14 from ._test_py36 import test_issue_73 

15 Foo = test_issue_73() 

16 else: 

17 # this is the new behaviour that happens when PEP563 is enabled at the top of the module 

18 if sys.version_info < (3, 7): 18 ↛ 19line 18 didn't jump to line 19, because the condition on line 18 was never true

19 pytest.skip("python 3.6 does not support PEP563") 

20 from ._test_py36_pep563 import test_issue_73 

21 Foo = test_issue_73() 

22 

23 if fix_in_class_field: 

24 # this will read the class fields, and the fix will happen during reading 

25 assert Foo.bar.type_hint is Foo 

26 

27 # if the fix was not done before, it is done when the field is first used 

28 f = Foo() 

29 with pytest.raises(FieldTypeError): 

30 f.bar = 1 

31 

32 f.bar = f 

33 assert f.bar is f 

34 

35 if not fix_in_class_field: 

36 # we can optionally check this now, but the mere fact that the above worked is already a proof 

37 assert Foo.bar.type_hint is Foo 

38 

39 

40@pytest.mark.skipif(sys.version_info < (3, 6), reason="class member annotations are not supported in python < 3.6") 

41@pytest.mark.parametrize('str_hint', [False, True], ids="str_hint={}".format) 

42@pytest.mark.parametrize('fix_in_class_field', [False, True], ids="fix_in_class_field={}".format) 

43def test_cross_referenced_class(str_hint, fix_in_class_field): 

44 if str_hint: 

45 # this is the old behaviour that happens when PEP563 is not enabled at the top of the module 

46 from ._test_py36 import test_issue_73_cross_ref 

47 A, B = test_issue_73_cross_ref() 

48 else: 

49 # this is the new behaviour that happens when PEP563 is enabled at the top of the module 

50 if sys.version_info < (3, 7): 50 ↛ 51line 50 didn't jump to line 51, because the condition on line 50 was never true

51 pytest.skip("python 3.6 does not support PEP563") 

52 from ._test_py36_pep563 import test_issue_73_cross_ref 

53 A, B = test_issue_73_cross_ref() 

54 

55 if fix_in_class_field: 

56 # this will read the class fields, and the fix will happen during reading 

57 assert A.bar.type_hint is B 

58 assert B.bar.type_hint is A 

59 

60 # if the fix was not done before, it is done when the field is first used 

61 a = A() 

62 with pytest.raises(FieldTypeError): 

63 a.bar = 1 

64 

65 b = B() 

66 a.bar = b 

67 b.bar = a 

68 assert a.bar is b 

69 assert b.bar is a 

70 

71 if not fix_in_class_field: 

72 # we can optionally check this now, but the mere fact that the above worked is already a proof 

73 assert A.bar.type_hint is B 

74 assert B.bar.type_hint is A