Skip to content

Commit 294ff4a

Browse files
michaelosthegemaresb
authored andcommitted
Workaround to suporess (some) import warnings from NumPy
Co-authored-by: Ben Mares <[email protected]>
1 parent 7fe5164 commit 294ff4a

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

pymc/__init__.py

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
__version__ = "4.1.1"
1717

1818
import logging
19-
import multiprocessing as mp
20-
import platform
19+
import sys
2120

2221
_log = logging.getLogger("pymc")
2322

@@ -28,6 +27,74 @@
2827
_log.addHandler(handler)
2928

3029

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+
3198
def __set_compiler_flags():
3299
# Workarounds for Aesara compiler problems on various platforms
33100
import aesara
@@ -47,6 +114,8 @@ def __set_compiler_flags():
47114
aesara.config.gcc__cxxflags = augmented
48115

49116

117+
if sys.platform == "win32":
118+
__suppress_aesara_import_warnings()
50119
__set_compiler_flags()
51120

52121
from pymc import gp, ode, sampling

0 commit comments

Comments
 (0)