Skip to content

Commit 3b31b5a

Browse files
authored
Add fixture load_kllvm (#4843)
Direct imports of `pyk.kllvm.load` are removed by relying on the fixture where needed. This eliminates the 5-10s startup delay in the integration test harness, as the `kllvm` Python module is now generated during test execution rather than at test collection.
1 parent b597daf commit 3b31b5a

18 files changed

Lines changed: 176 additions & 123 deletions

pyk/src/pyk/testing/_kompiler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ class RuntimeTest(KompiledTest):
352352
KOMPILE_BACKEND = 'llvm'
353353

354354
@pytest.fixture(scope='class')
355-
def runtime(self, definition_dir: Path) -> Runtime:
355+
def runtime(self, load_kllvm: None, definition_dir: Path) -> Runtime:
356356
compile_runtime(definition_dir)
357357
return import_runtime(definition_dir)
358358

pyk/src/pyk/testing/plugin.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,28 @@ def profile(tmp_path: Path) -> Profiler:
6060
@pytest.fixture(scope='session')
6161
def kompile(tmp_path_factory: TempPathFactory) -> Kompiler:
6262
return Kompiler(tmp_path_factory)
63+
64+
65+
@pytest.fixture(scope='session')
66+
def load_kllvm(tmp_path_factory: TempPathFactory) -> None:
67+
"""Generate and import the ``_kllvm`` bindings module.
68+
69+
Use this fixture in all tests that import from ``pyk.kllvm``.
70+
It ensures transitive imports of ``_kllvm`` are successful.
71+
72+
Example:
73+
.. code-block:: python
74+
75+
def test_symbol_name(load_kllvm: None) -> None:
76+
from pyk.kllvm.ast import Symbol
77+
78+
name = "Lbl'UndsPlus'Int'Unds'"
79+
symbol = Symbol(name)
80+
assert symbol.name == name
81+
"""
82+
from ..kllvm.compiler import compile_kllvm
83+
from ..kllvm.importer import import_kllvm
84+
85+
tmp_dir = tmp_path_factory.mktemp('kllvm')
86+
module_file = compile_kllvm(tmp_dir)
87+
import_kllvm(module_file)

pyk/src/tests/integration/kllvm/test_convert.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
import pytest
66

7-
import pyk.kllvm.load # noqa: F401
8-
from pyk.kllvm.convert import definition_to_llvm, llvm_to_definition, llvm_to_pattern, pattern_to_llvm
97
from pyk.kore.parser import KoreParser
108

119
if TYPE_CHECKING:
@@ -66,7 +64,9 @@ def _in_module(kore_text: str) -> str:
6664

6765

6866
@pytest.mark.parametrize('test_id,kore_text', PAT_TEST_DATA, ids=[test_id for test_id, *_ in PAT_TEST_DATA])
69-
def test_pattern_to_llvm(test_id: str, kore_text: str) -> None:
67+
def test_pattern_to_llvm(load_kllvm: None, test_id: str, kore_text: str) -> None:
68+
from pyk.kllvm.convert import llvm_to_pattern, pattern_to_llvm
69+
7070
# Given
7171
expected = KoreParser(kore_text).pattern()
7272

@@ -85,7 +85,9 @@ def test_pattern_to_llvm(test_id: str, kore_text: str) -> None:
8585

8686

8787
@pytest.mark.parametrize('test_id,kore_text', DEF_TEST_DATA, ids=[test_id for test_id, *_ in DEF_TEST_DATA])
88-
def test_definition_to_llvm(test_id: str, kore_text: str) -> None:
88+
def test_definition_to_llvm(load_kllvm: None, test_id: str, kore_text: str) -> None:
89+
from pyk.kllvm.convert import definition_to_llvm, llvm_to_definition
90+
8991
# Given
9092
expected = KoreParser(kore_text).definition()
9193

pyk/src/tests/integration/kllvm/test_desugar_associative.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
import pytest
77

8-
import pyk.kllvm.load # noqa: F401
9-
from pyk.kllvm.convert import pattern_to_llvm
108
from pyk.kore.parser import KoreParser
119

1210
if TYPE_CHECKING:
@@ -37,7 +35,9 @@
3735

3836

3937
@pytest.mark.parametrize('kore_text,expected_text', TEST_DATA, ids=count())
40-
def test_desugar_associative(kore_text: str, expected_text: str) -> None:
38+
def test_desugar_associative(load_kllvm: None, kore_text: str, expected_text: str) -> None:
39+
from pyk.kllvm.convert import pattern_to_llvm
40+
4141
# Given
4242
kore = pattern_to_llvm(KoreParser(kore_text).pattern())
4343
expected = pattern_to_llvm(KoreParser(expected_text).pattern())

pyk/src/tests/integration/kllvm/test_evaluate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
import pytest
66

7-
import pyk.kllvm.load # noqa: F401
8-
from pyk.kllvm import parser
97
from pyk.testing import RuntimeTest
108

119
from ..utils import K_FILES
@@ -39,6 +37,8 @@ class TestEvaluate(RuntimeTest):
3937
ids=[test_id for test_id, *_ in EVALUATE_TEST_DATA],
4038
)
4139
def test_simplify(self, runtime: Runtime, test_id: str, pattern_text: str, expected: str) -> None:
40+
from pyk.kllvm import parser
41+
4242
# Given
4343
pattern = parser.parse_pattern(pattern_text)
4444

pyk/src/tests/integration/kllvm/test_internal_term.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
import pytest
66

7-
import pyk.kllvm.load # noqa: F401
8-
from pyk.kllvm.parser import Parser
97
from pyk.testing import RuntimeTest
108

119
from ..utils import K_FILES
@@ -21,15 +19,18 @@
2119
class TestInternalTerm(RuntimeTest):
2220
KOMPILE_MAIN_FILE = K_FILES / 'imp.k'
2321

24-
def test_str_llvm_backend_issue_724(self, runtime: Runtime) -> None:
22+
def test_str_llvm_backend_issue_724(self, runtime: Runtime, start_pattern: Pattern) -> None:
2523
for _ in range(10000):
26-
term = runtime._module.InternalTerm(start_pattern())
24+
term = runtime._module.InternalTerm(start_pattern)
2725
term.step(-1)
2826
# just checking that str doesn't crash
2927
str(term)
3028

3129

32-
def start_pattern() -> Pattern:
30+
@pytest.fixture
31+
def start_pattern(load_kllvm: None) -> Pattern:
32+
from pyk.kllvm.parser import Parser
33+
3334
"""
3435
<k> int x ; x = 1 </k>
3536
"""

pyk/src/tests/integration/kllvm/test_load.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
from typing import TYPE_CHECKING
44

5-
import pyk.kllvm.load # noqa: F401
6-
import pyk.kllvm.load_static # noqa: F401
7-
from pyk.kllvm.compiler import compile_kllvm
8-
95
if TYPE_CHECKING:
106
from typing import Final
117

128

139
def test_kllvm_module() -> None:
10+
import pyk.kllvm.load # noqa: F401
11+
import pyk.kllvm.load_static # noqa: F401
12+
from pyk.kllvm.compiler import compile_kllvm
1413

1514
# Given
1615
kllvm_module_dir: Final = pyk.kllvm.load.KLLVM_MODULE_DIR

pyk/src/tests/integration/kllvm/test_parser.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
from typing import TYPE_CHECKING
44

5-
import pyk.kllvm.load # noqa: F401
6-
from pyk.kllvm import parser
7-
85
if TYPE_CHECKING:
96
from pathlib import Path
107

118

12-
def test_parse_pattern_file(tmp_path: Path) -> None:
9+
def test_parse_pattern_file(load_kllvm: None, tmp_path: Path) -> None:
10+
from pyk.kllvm import parser
11+
1312
# Given
1413
kore_text = 'A{}(B{}(),C{}())'
1514
kore_file = tmp_path / 'test.kore'
@@ -22,7 +21,9 @@ def test_parse_pattern_file(tmp_path: Path) -> None:
2221
assert str(actual) == kore_text
2322

2423

25-
def test_parse_pattern() -> None:
24+
def test_parse_pattern(load_kllvm: None) -> None:
25+
from pyk.kllvm import parser
26+
2627
# Given
2728
kore_text = 'A{}(X : S,Y : Z,Int{}())'
2829

@@ -33,7 +34,9 @@ def test_parse_pattern() -> None:
3334
assert str(actual) == kore_text
3435

3536

36-
def test_parse_sort_file(tmp_path: Path) -> None:
37+
def test_parse_sort_file(load_kllvm: None, tmp_path: Path) -> None:
38+
from pyk.kllvm import parser
39+
3740
# Given
3841
kore_text = 'Foo{Bar,Baz}'
3942
kore_file = tmp_path / 'test.kore'
@@ -46,7 +49,9 @@ def test_parse_sort_file(tmp_path: Path) -> None:
4649
assert str(actual) == kore_text
4750

4851

49-
def test_parse_sort() -> None:
52+
def test_parse_sort(load_kllvm: None) -> None:
53+
from pyk.kllvm import parser
54+
5055
# Given
5156
kore_text = 'Foo{Bar,Baz}'
5257

@@ -57,9 +62,10 @@ def test_parse_sort() -> None:
5762
assert str(actual) == kore_text
5863

5964

60-
def test_parse_definition_file(tmp_path: Path) -> None:
61-
# Given
65+
def test_parse_definition_file(load_kllvm: None, tmp_path: Path) -> None:
66+
from pyk.kllvm import parser
6267

68+
# Given
6369
# fmt: off
6470
kore_text = (
6571
'[]\n'
@@ -81,10 +87,10 @@ def test_parse_definition_file(tmp_path: Path) -> None:
8187
assert str(actual) == kore_text
8288

8389

84-
def test_parse_definition() -> None:
85-
# Given
90+
def test_parse_definition(load_kllvm: None) -> None:
91+
from pyk.kllvm import parser
8692

87-
# fmt: off
93+
# Given
8894
kore_text = (
8995
'[]\n'
9096
'\n'
@@ -93,7 +99,6 @@ def test_parse_definition() -> None:
9399
'endmodule\n'
94100
'[concrete{}()]\n'
95101
)
96-
# fmt: on
97102

98103
# When
99104
actual = parser.parse_definition(kore_text)

pyk/src/tests/integration/kllvm/test_patterns.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
import pytest
66

7-
import pyk.kllvm.load # noqa: F401
8-
from pyk.kllvm.ast import CompositePattern, CompositeSort, Pattern, StringPattern, VariablePattern
9-
107
if TYPE_CHECKING:
118
from pathlib import Path
129

@@ -19,7 +16,9 @@
1916
'XYZ : ABC',
2017
),
2118
)
22-
def test_file_load(tmp_path: Path, kore_text: str) -> None:
19+
def test_file_load(load_kllvm: None, tmp_path: Path, kore_text: str) -> None:
20+
from pyk.kllvm.ast import Pattern
21+
2322
# Given
2423
kore_file = tmp_path / 'test.kore'
2524
kore_file.write_text(kore_text)
@@ -31,7 +30,9 @@ def test_file_load(tmp_path: Path, kore_text: str) -> None:
3130
assert str(actual) == kore_text
3231

3332

34-
def test_composite() -> None:
33+
def test_composite(load_kllvm: None) -> None:
34+
from pyk.kllvm.ast import CompositePattern, CompositeSort, VariablePattern
35+
3536
# Given
3637
pattern = CompositePattern('F')
3738
pattern.add_argument(CompositePattern('A'))
@@ -44,7 +45,9 @@ def test_composite() -> None:
4445
assert str(actual) == 'F{}(A{}(),B{}())'
4546

4647

47-
def test_string() -> None:
48+
def test_string(load_kllvm: None) -> None:
49+
from pyk.kllvm.ast import StringPattern
50+
4851
# Given
4952
pattern = StringPattern('abc')
5053

@@ -53,7 +56,9 @@ def test_string() -> None:
5356
assert pattern.contents.decode('latin-1') == 'abc'
5457

5558

56-
def test_variable() -> None:
59+
def test_variable(load_kllvm: None) -> None:
60+
from pyk.kllvm.ast import CompositePattern, CompositeSort, VariablePattern
61+
5762
# Given
5863
pattern = VariablePattern('X', CompositeSort('S'))
5964

pyk/src/tests/integration/kllvm/test_serialize.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44

55
import pytest
66

7-
import pyk.kllvm.load # noqa: F401
8-
from pyk.kllvm import parser
9-
from pyk.kllvm.ast import Pattern
10-
from pyk.kllvm.convert import pattern_to_llvm
117
from pyk.kore.parser import KoreParser
128
from pyk.testing import RuntimeTest
139

@@ -31,7 +27,10 @@
3127

3228

3329
@pytest.mark.parametrize('kore_text', TEST_DATA)
34-
def test_serialize(kore_text: str) -> None:
30+
def test_serialize(load_kllvm: None, kore_text: str) -> None:
31+
from pyk.kllvm.ast import Pattern
32+
from pyk.kllvm.convert import pattern_to_llvm
33+
3534
# Given
3635
_pattern = KoreParser(kore_text).pattern()
3736
pattern = pattern_to_llvm(_pattern)
@@ -49,6 +48,9 @@ class TestSerializeRaw(RuntimeTest):
4948
KOMPILE_MAIN_FILE = K_FILES / 'imp.k'
5049

5150
def test_serialize_raw(self, runtime: Runtime, tmp_path: Path) -> None:
51+
from pyk.kllvm import parser
52+
from pyk.kllvm.ast import Pattern
53+
5254
# Given
5355
kore_text = r"""Lbl'UndsPlus'Int'Unds'{}(\dv{SortInt{}}("1"),\dv{SortInt{}}("2"))"""
5456
pattern = parser.parse_pattern(kore_text)

0 commit comments

Comments
 (0)