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