3
3
###########################################################################
4
4
import os
5
5
import sys
6
+ from importlib .metadata import PackageNotFoundError , metadata
6
7
from pathlib import Path
7
8
8
9
import pytest
9
10
10
11
12
+ def xfail_if_not_installed (package_name ):
13
+ """A test decorator that xfails a test if the named package isn't installed.
14
+
15
+ The third-party tests are dependant on packages being built. During pre-release some
16
+ packages won't be compilable. So - the pyproject.toml installs third party packages
17
+ with a version conditional gate.
18
+
19
+ This decorator checks for app metadata (which is an indicator that the package has
20
+ been installed). If the metadata exists, the test is executed; if it isn't we XFAIL
21
+ the test because it *can't* pass.
22
+ """
23
+
24
+ def _xfail_if_not_installed (fn ):
25
+ def _testfunc (* args , ** kwargs ):
26
+ try :
27
+ metadata (package_name )
28
+ except PackageNotFoundError :
29
+ pytest .xfail (f"{ package_name } is not installed" )
30
+
31
+ # Actually run the test
32
+ fn (* args , ** kwargs )
33
+
34
+ return _testfunc
35
+
36
+ return _xfail_if_not_installed
37
+
38
+
39
+ @xfail_if_not_installed ("pillow" )
11
40
def test_module_paths ():
12
41
"Third party binary modules have meaningful __file__ attributes"
13
42
import PIL
@@ -22,6 +51,7 @@ def test_module_paths():
22
51
23
52
24
53
@pytest .mark .skipif (sys .platform == "win32" , reason = "cffi not available on windows" )
54
+ @xfail_if_not_installed ("cffi" )
25
55
def test_cffi ():
26
56
"CFFI can be used as an alternative FFI interface"
27
57
from cffi import FFI
@@ -32,6 +62,7 @@ def test_cffi():
32
62
assert lib .strlen (ffi .new ("char[]" , b"hello world" )) == 11
33
63
34
64
65
+ @xfail_if_not_installed ("cryptography" )
35
66
def test_cryptography ():
36
67
"The cryptography module can be used"
37
68
# Cryptography is a common binary library that uses cffi and OpenSSL internally
@@ -87,6 +118,7 @@ def test_cryptography():
87
118
assert "www.android.com" == domain
88
119
89
120
121
+ @xfail_if_not_installed ("lru-dict" )
90
122
def test_lru_dict ():
91
123
"The LRUDict binary module can be used"
92
124
# lru-dict is the simplest possible example of a third-party module.
@@ -107,6 +139,7 @@ def test_lru_dict():
107
139
assert lru_dict [f"item_{ i } " ] == i
108
140
109
141
142
+ @xfail_if_not_installed ("pillow" )
110
143
def test_pillow ():
111
144
"Pillow can be used to load images"
112
145
# Pillow is a module that has dependencies on other libraries (libjpeg, libft2)
@@ -122,6 +155,7 @@ def test_pillow():
122
155
image .close ()
123
156
124
157
158
+ @xfail_if_not_installed ("numpy" )
125
159
def test_numpy ():
126
160
"Numpy Arrays can be created"
127
161
from numpy import array
@@ -130,6 +164,7 @@ def test_numpy():
130
164
assert [4 , 7 ] == (array ([1 , 2 ]) + array ([3 , 5 ])).tolist ()
131
165
132
166
167
+ @xfail_if_not_installed ("pandas" )
133
168
def test_pandas ():
134
169
"Pandas DataFrames can be created"
135
170
from pandas import DataFrame , __version__
0 commit comments