16
16
__version__ = "4.1.1"
17
17
18
18
import logging
19
- import multiprocessing as mp
20
- import platform
19
+ import sys
21
20
22
21
_log = logging .getLogger ("pymc" )
23
22
28
27
_log .addHandler (handler )
29
28
30
29
30
+ def __suppress_aesara_import_warnings ():
31
+ """This is a workaround to suppress nonlethal NumPy warnings.
32
+
33
+ Some more printouts remain. See https://github.com/numpy/numpy/issues/21942
34
+
35
+ Remove this once https://github.com/aesara-devs/aesara/pull/980 is merged.
36
+ """
37
+ # We need to catch warnings as in some cases NumPy prints
38
+ # stuff that we don't want the user to see.
39
+ import io
40
+ import warnings
41
+
42
+ from contextlib import redirect_stderr , redirect_stdout
43
+
44
+ import numpy .distutils .system_info
45
+
46
+ class NumpyCompatibleStdoutStringIO (io .StringIO ):
47
+ """Used as a temporary replacement of sys.stdout to capture Numpy's output.
48
+ We want to simply use io.StringIO, but this doesn't work because
49
+ Numpy expects the .encoding attribute to be a string. For io.StringIO,
50
+ this attribute is set to None and cannot be modified, hence the need for
51
+ this subclass.
52
+ (See forward_bytes_to_stdout in numpy.distutils.exec_command.)
53
+ """
54
+
55
+ encoding = sys .stdout .encoding
56
+
57
+ # Known executables which trigger false-positive warnings when not found.
58
+ # Ref: <https://github.com/conda-forge/aesara-feedstock/issues/54>
59
+ executables = ["g77" , "f77" , "ifort" , "ifl" , "f90" , "DF" , "efl" ]
60
+
61
+ # The Numpy function which defines blas_info emits false-positive warnings.
62
+ # In what follows we capture these warnings and ignore them.
63
+ with warnings .catch_warnings (record = True ):
64
+ # The warnings about missing executables don't use Python's "warnings"
65
+ # mechanism, and thus are not filtered by the catch_warnings context
66
+ # above. On Linux the warnings are printed to stderr, but on Windows
67
+ # they are printed to stdout. Thus we capture and filter both stdout
68
+ # and stderr.
69
+ stdout_sio , stderr_sio = NumpyCompatibleStdoutStringIO (), io .StringIO ()
70
+ with redirect_stdout (stdout_sio ), redirect_stderr (stderr_sio ):
71
+ numpy .distutils .system_info .get_info ("blas_opt" )
72
+
73
+ # Print any unfiltered messages to stdout and stderr.
74
+ # (We hope that, beyond what we filter out, there should have been
75
+ # no messages printed to stdout or stderr. In case there were messages,
76
+ # we want to print them for the user to see. In what follows, we print
77
+ # the stdout messages followed by the stderr messages. This means that
78
+ # messages will be printed in the wrong order in the case that
79
+ # there is output to both stdout and stderr, and the stderr output
80
+ # doesn't come at the end.)
81
+ for captured_buffer , print_destination in (
82
+ (stdout_sio , sys .stdout ),
83
+ (stderr_sio , sys .stderr ),
84
+ ):
85
+ raw_lines = captured_buffer .getvalue ().splitlines ()
86
+ filtered_lines = [
87
+ line
88
+ for line in raw_lines
89
+ # Keep a line when none of the warnings are found within
90
+ # (equiv. when all of the warnings are not found within).
91
+ if all (f"Could not locate executable { exe } " not in line for exe in executables )
92
+ ]
93
+ for line in filtered_lines :
94
+ print (line , file = print_destination )
95
+ return
96
+
97
+
31
98
def __set_compiler_flags ():
32
99
# Workarounds for Aesara compiler problems on various platforms
33
100
import aesara
@@ -47,6 +114,8 @@ def __set_compiler_flags():
47
114
aesara .config .gcc__cxxflags = augmented
48
115
49
116
117
+ if sys .platform == "win32" :
118
+ __suppress_aesara_import_warnings ()
50
119
__set_compiler_flags ()
51
120
52
121
from pymc import gp , ode , sampling
0 commit comments