Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/py-polars/tests/unit/test_plugins.py
6939 views
1
from __future__ import annotations
2
3
import sys
4
from pathlib import Path
5
from typing import Any
6
7
import pytest
8
9
import polars as pl
10
from polars.exceptions import ComputeError
11
from polars.plugins import (
12
_is_dynamic_lib,
13
_resolve_plugin_path,
14
_serialize_kwargs,
15
register_plugin_function,
16
)
17
18
19
@pytest.mark.write_disk
20
def test_register_plugin_function_invalid_plugin_path(tmp_path: Path) -> None:
21
tmp_path.mkdir(exist_ok=True)
22
plugin_path = tmp_path / "lib.so"
23
plugin_path.touch()
24
25
expr = register_plugin_function(
26
plugin_path=plugin_path, function_name="hello", args=5
27
)
28
29
with pytest.raises(ComputeError, match="error loading dynamic library"):
30
pl.select(expr)
31
32
33
@pytest.mark.parametrize(
34
("input", "expected"),
35
[
36
(None, b""),
37
({}, b""),
38
(
39
{"hi": 0},
40
b"\x80\x05\x95\x0b\x00\x00\x00\x00\x00\x00\x00}\x94\x8c\x02hi\x94K\x00s.",
41
),
42
],
43
)
44
def test_serialize_kwargs(input: dict[str, Any] | None, expected: bytes) -> None:
45
assert _serialize_kwargs(input) == expected
46
47
48
@pytest.mark.write_disk
49
@pytest.mark.parametrize("use_abs_path", [True, False])
50
def test_resolve_plugin_path(
51
monkeypatch: pytest.MonkeyPatch,
52
tmp_path: Path,
53
use_abs_path: bool,
54
) -> None:
55
tmp_path.mkdir(exist_ok=True)
56
57
mock_venv = tmp_path / ".venv"
58
mock_venv.mkdir(exist_ok=True)
59
mock_venv_lib = mock_venv / "lib"
60
mock_venv_lib.mkdir(exist_ok=True)
61
(mock_venv_lib / "lib1.so").touch()
62
(mock_venv_lib / "__init__.py").touch()
63
64
with pytest.MonkeyPatch.context() as mp:
65
mp.setattr(sys, "prefix", str(mock_venv))
66
expected_full_path = mock_venv_lib / "lib1.so"
67
expected_relative_path = expected_full_path.relative_to(mock_venv)
68
69
if use_abs_path:
70
result = _resolve_plugin_path(mock_venv_lib, use_abs_path=use_abs_path)
71
assert result == expected_full_path
72
else:
73
result = _resolve_plugin_path(mock_venv_lib, use_abs_path=use_abs_path)
74
assert result == expected_relative_path
75
76
77
@pytest.mark.write_disk
78
def test_resolve_plugin_path_raises(tmp_path: Path) -> None:
79
tmp_path.mkdir(exist_ok=True)
80
(tmp_path / "__init__.py").touch()
81
82
with pytest.raises(FileNotFoundError, match="no dynamic library found"):
83
_resolve_plugin_path(tmp_path)
84
85
86
@pytest.mark.write_disk
87
@pytest.mark.parametrize(
88
("path", "expected"),
89
[
90
(Path("lib.so"), True),
91
(Path("lib.pyd"), True),
92
(Path("lib.dll"), True),
93
(Path("lib.py"), False),
94
],
95
)
96
def test_is_dynamic_lib(path: Path, expected: bool, tmp_path: Path) -> None:
97
tmp_path.mkdir(exist_ok=True)
98
full_path = tmp_path / path
99
full_path.touch()
100
assert _is_dynamic_lib(full_path) is expected
101
102
103
@pytest.mark.write_disk
104
def test_is_dynamic_lib_dir(tmp_path: Path) -> None:
105
path = Path("lib.so")
106
full_path = tmp_path / path
107
108
full_path.mkdir(exist_ok=True)
109
(full_path / "hello.txt").touch()
110
111
assert _is_dynamic_lib(full_path) is False
112
113