test_struct.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. from __future__ import annotations
  2. import unittest
  3. from mypyc.ir.rtypes import (
  4. RStruct,
  5. bool_rprimitive,
  6. int32_rprimitive,
  7. int64_rprimitive,
  8. int_rprimitive,
  9. object_rprimitive,
  10. )
  11. from mypyc.rt_subtype import is_runtime_subtype
  12. class TestStruct(unittest.TestCase):
  13. def test_struct_offsets(self) -> None:
  14. # test per-member alignment
  15. r = RStruct("", [], [bool_rprimitive, int32_rprimitive, int64_rprimitive])
  16. assert r.size == 16
  17. assert r.offsets == [0, 4, 8]
  18. # test final alignment
  19. r1 = RStruct("", [], [bool_rprimitive, bool_rprimitive])
  20. assert r1.size == 2
  21. assert r1.offsets == [0, 1]
  22. r2 = RStruct("", [], [int32_rprimitive, bool_rprimitive])
  23. r3 = RStruct("", [], [int64_rprimitive, bool_rprimitive])
  24. assert r2.offsets == [0, 4]
  25. assert r3.offsets == [0, 8]
  26. assert r2.size == 8
  27. assert r3.size == 16
  28. r4 = RStruct("", [], [bool_rprimitive, bool_rprimitive, bool_rprimitive, int32_rprimitive])
  29. assert r4.size == 8
  30. assert r4.offsets == [0, 1, 2, 4]
  31. # test nested struct
  32. r5 = RStruct("", [], [bool_rprimitive, r])
  33. assert r5.offsets == [0, 8]
  34. assert r5.size == 24
  35. r6 = RStruct("", [], [int32_rprimitive, r5])
  36. assert r6.offsets == [0, 8]
  37. assert r6.size == 32
  38. # test nested struct with alignment less than 8
  39. r7 = RStruct("", [], [bool_rprimitive, r4])
  40. assert r7.offsets == [0, 4]
  41. assert r7.size == 12
  42. def test_struct_str(self) -> None:
  43. r = RStruct("Foo", ["a", "b"], [bool_rprimitive, object_rprimitive])
  44. assert str(r) == "Foo{a:bool, b:object}"
  45. assert (
  46. repr(r) == "<RStruct Foo{a:<RPrimitive builtins.bool>, "
  47. "b:<RPrimitive builtins.object>}>"
  48. )
  49. r1 = RStruct("Bar", ["c"], [int32_rprimitive])
  50. assert str(r1) == "Bar{c:i32}"
  51. assert repr(r1) == "<RStruct Bar{c:<RPrimitive i32>}>"
  52. r2 = RStruct("Baz", [], [])
  53. assert str(r2) == "Baz{}"
  54. assert repr(r2) == "<RStruct Baz{}>"
  55. def test_runtime_subtype(self) -> None:
  56. # right type to check with
  57. r = RStruct("Foo", ["a", "b"], [bool_rprimitive, int_rprimitive])
  58. # using the exact same fields
  59. r1 = RStruct("Foo", ["a", "b"], [bool_rprimitive, int_rprimitive])
  60. # names different
  61. r2 = RStruct("Bar", ["c", "b"], [bool_rprimitive, int_rprimitive])
  62. # name different
  63. r3 = RStruct("Baz", ["a", "b"], [bool_rprimitive, int_rprimitive])
  64. # type different
  65. r4 = RStruct("FooBar", ["a", "b"], [bool_rprimitive, int32_rprimitive])
  66. # number of types different
  67. r5 = RStruct(
  68. "FooBarBaz", ["a", "b", "c"], [bool_rprimitive, int_rprimitive, bool_rprimitive]
  69. )
  70. assert is_runtime_subtype(r1, r) is True
  71. assert is_runtime_subtype(r2, r) is False
  72. assert is_runtime_subtype(r3, r) is False
  73. assert is_runtime_subtype(r4, r) is False
  74. assert is_runtime_subtype(r5, r) is False
  75. def test_eq_and_hash(self) -> None:
  76. r = RStruct("Foo", ["a", "b"], [bool_rprimitive, int_rprimitive])
  77. # using the exact same fields
  78. r1 = RStruct("Foo", ["a", "b"], [bool_rprimitive, int_rprimitive])
  79. assert hash(r) == hash(r1)
  80. assert r == r1
  81. # different name
  82. r2 = RStruct("Foq", ["a", "b"], [bool_rprimitive, int_rprimitive])
  83. assert hash(r) != hash(r2)
  84. assert r != r2
  85. # different names
  86. r3 = RStruct("Foo", ["a", "c"], [bool_rprimitive, int_rprimitive])
  87. assert hash(r) != hash(r3)
  88. assert r != r3
  89. # different type
  90. r4 = RStruct("Foo", ["a", "b"], [bool_rprimitive, int_rprimitive, bool_rprimitive])
  91. assert hash(r) != hash(r4)
  92. assert r != r4