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