File: pusimp.patch

package info (click to toggle)
fenics-dolfinx 1%3A0.9.0-8
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 5,304 kB
  • sloc: cpp: 33,643; python: 22,329; makefile: 234; sh: 173; xml: 55
file content (126 lines) | stat: -rw-r--r-- 4,866 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
--- a/python/dolfinx/__init__.py
+++ b/python/dolfinx/__init__.py
@@ -27,6 +27,29 @@
     default_scalar_type = _np.float64
     default_real_type = _np.float64
 
+import pusimp
+
+def pip_uninstall_call(executable: str, dependency_pypi_name: str, dependency_actual_path: str) -> str:
+    """Report to the user how to uninstall a dependency with pip."""
+    output = f"{executable} -m pip uninstall --break-system-packages {dependency_pypi_name}"
+    if dependency_actual_path.startswith("/usr"):
+        return f"sudo {output}"
+    else:
+        return output
+
+
+pusimp.prevent_user_site_imports(
+    "dolfinx", "apt", "https://fenicsproject.discourse.group/",
+    "/usr/lib/python3/dist-packages",
+    ["basix", "ffcx", "ufl"],
+    ["fenics-basix", "fenics-ffcx", "fenics-ufl"],
+    [False, False, False],
+    ["", "", ""],
+    pip_uninstall_call
+)
+
+del pip_uninstall_call, pusimp
+
 from dolfinx import common
 from dolfinx import cpp as _cpp
 from dolfinx import fem, geometry, graph, io, jit, la, log, mesh, nls, plot, utils
--- /dev/null
+++ b/python/test/debian-only/test_pusimp.py
@@ -0,0 +1,91 @@
+# Copyright (C) 2024 by the pusimp authors
+#
+# This file is part of pusimp for FEniCSx.
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+"""Test DOLFINx patches."""
+
+import os
+import typing
+
+import pytest
+import requests
+
+from pusimp.utils import (
+    assert_package_import_errors_with_local_packages,
+    assert_package_import_errors_with_broken_non_optional_packages,
+    assert_package_import_success_with_allowed_local_packages,
+    assert_package_import_success_without_local_packages
+)
+
+try:
+    response = requests.get("https://www.debian.org", timeout=5)
+except requests.ConnectionError:
+    has_internet = False
+else:
+    has_internet = True
+
+if os.getenv("PUSIMP_EXPECT_DOLFINX_IN_CWD") is None:
+    dolfinx_python_prefix = "/usr/lib/petsc/lib/python3/dist-packages/dolfinx"
+else:
+    dolfinx_python_prefix = os.path.join(os.getcwd(), "dolfinx")
+
+
+def pip_install_call(executable: str, dependency_pypi_name: str) -> str:
+    """Command to be run to install a dependency with pip."""
+    return (
+        f"{executable} -m pip install --ignore-installed --break-system-packages {dependency_pypi_name}"
+        # debian does not ship numpy 2.0 yet, and a pip install-ed numpy 2.0 would break binary compatibility
+        + " 'numpy<2.0'"
+    )
+
+
+def pip_uninstall_call(executable: str, dependency_pypi_name: str, dependency_actual_path: str) -> str:
+    """Command to be run to uninstall a dependency with pip."""
+    return f"{executable} -m pip uninstall --break-system-packages {dependency_pypi_name}"
+
+
+def test_dolfinx_import_success_without_local_packages() -> None:
+    """Test that dolfinx imports correctly without any extra local packages."""
+    assert_package_import_success_without_local_packages(
+        "dolfinx", os.path.join(dolfinx_python_prefix, "__init__.py")
+    )
+
+
+@pytest.mark.skipif(not has_internet, reason="Requires downloading from pypi.org")
+@pytest.mark.parametrize("dependencies_import_name,dependencies_pypi_name,dependencies_extra_error_message", [
+    (["ufl"], ["fenics-ufl"], []),
+    (["basix", "ufl"], ["fenics-basix", "fenics-ufl"], [])
+])
+def test_dolfinx_import_errors_with_local_packages(
+    dependencies_import_name: typing.List[str], dependencies_pypi_name: typing.List[str],
+    dependencies_extra_error_message: typing.List[str]
+) -> None:
+    """Test that dolfinx fails to import with extra local packages."""
+    assert_package_import_errors_with_local_packages(
+        "dolfinx", dependencies_import_name, dependencies_pypi_name, dependencies_extra_error_message,
+        pip_install_call, pip_uninstall_call
+    )
+
+
+@pytest.mark.skipif(not has_internet, reason="Requires downloading from pypi.org")
+@pytest.mark.parametrize("dependencies_import_name,dependencies_pypi_name", [
+    (["ufl"], ["fenics-ufl"])
+])
+def test_dolfinx_import_success_with_allowed_local_packages(
+    dependencies_import_name: typing.List[str], dependencies_pypi_name: typing.List[str]
+) -> None:
+    """Test that dolfinx imports correctly even with extra local packages when asked to allow user-site imports."""
+    assert_package_import_success_with_allowed_local_packages(
+        "dolfinx", os.path.join(dolfinx_python_prefix, "__init__.py"),
+        dependencies_import_name, dependencies_pypi_name, pip_install_call
+    )
+
+
+@pytest.mark.parametrize("dependencies_import_name", [
+    ["ufl"],
+    ["ffcx"]
+])
+def test_dolfinx_import_errors_with_broken_non_optional_packages(dependencies_import_name: typing.List[str]) -> None:
+    """Test that dolfinx fails to import with broken local packages."""
+    assert_package_import_errors_with_broken_non_optional_packages("dolfinx", dependencies_import_name, [False])