Skip to content

Commit 66783f1

Browse files
committed
Merge branch 'fix-jupyter-stdout'
2 parents c0814e6 + 65f77d1 commit 66783f1

File tree

5 files changed

+49
-10
lines changed

5 files changed

+49
-10
lines changed

.github/build/manylinux1_x86_64/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RUN groupadd -o -g $GID runner && \
1010
if [[ $AUDITWHEEL_PLAT == manylinux2014_* ]]; then \
1111
yum install -y glibc-static; \
1212
fi && \
13-
pip install --upgrade cmake cython && \
13+
pip install --upgrade cmake cython --only-binary=cmake && \
1414
for PYBIN in /opt/python/cp3*/bin; do \
1515
"${PYBIN}/pip" install -U setuptools; \
1616
done

doc/installation/unix.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ install location if you prefer (e.g. ``~/.local`` or ``/opt/madx``), but keep
5959
in mind that there is no ``uninstall`` command other than removing the files
6060
manually.
6161

62-
The cmake command has many more options, the most important ones being:
62+
The cmake command has many more options, the most important ones being
63+
(only use if you now what you're doing!):
6364

6465
- ``-DMADX_STATIC=ON``: Pass this flag to link statically against the
6566
dependencies of MAD-X (libc, libgfortran, libstdc++, blas, lapack, etc).
@@ -87,7 +88,7 @@ MAD-X headers and library, for example::
8788
export MADXDIR="$(pwd)"/../dist
8889

8990
Also, set the following variables according to the flags passed to the cmake
90-
command above::
91+
command above (ONLY PASS IF NEEDED!)::
9192

9293
set STATIC=1 # if -DMADX_STATIC=ON
9394
set SHARED=1 # if -DBUILD_SHARED_LIBS=ON
@@ -102,12 +103,14 @@ Install setup requirements::
102103

103104
Enter the cpymad folder, and build as follows::
104105

105-
python setup.py build_ext
106+
python setup.py build_ext -lm
107+
108+
The ``-lm`` might not be necessary on all systems.
106109

107110
If you have installed blas/lapack and MAD-X found it during the cmake step,
108111
you have to pass them as additional link libraries::
109112

110-
python setup.py build_ext -lblas -llapack
113+
python setup.py build_ext -lm -lblas -llapack
111114

112115
You can now create and install a wheel as follows (however, note that this
113116
wheel probably won't be fit to be distributed to other systems)::

doc/installation/windows.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ In the build environment, type::
9797
-DMADX_STATIC=ON ^
9898
-DCMAKE_INSTALL_PREFIX="../dist"
9999

100-
cmake --build . --target install:
100+
cmake --build . --target install
101101

102102
.. note::
103103

src/cpymad/madx.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
from . import _rpc
2121
from . import util
22-
from .stream import AsyncReader
22+
from .stream import AsyncReader, TextCallback
2323

2424

2525
__all__ = [
@@ -172,10 +172,32 @@ def __init__(self, libmadx=None, command_log=None, stdout=None,
172172
if stdout is None:
173173
stdout = sys.stdout
174174
if hasattr(stdout, 'write'):
175-
try:
176-
stdout = stdout.fileno()
177-
except (AttributeError, OSError, IOError):
175+
# Detect if stdout is attached to a jupyter notebook:
176+
cls = getattr(stdout, '__class__', type(None))
177+
qualname = cls.__module__ + '.' + cls.__name__
178+
if qualname == 'ipykernel.iostream.OutStream':
179+
# In that case we want to behave the same way as `print`
180+
# (i.e. log to the notebook not to the terminal). On
181+
# linux, python>=3.7 within notebooks 6.4 `sys.stdout` has
182+
# a valid sys.stdout.fileno(), but writing to it outputs
183+
# to the terminal, so we have to use `sys.stdout.write()`:
178184
stdout = stdout.write
185+
else:
186+
# Otherwise, let the OS handle MAD-X output, by passing
187+
# the file descriptor if available. This is preferred
188+
# because it is faster, and also because it means that the
189+
# MAD-X output is directly connected to the output as
190+
# binary stream, without potential recoding errors.
191+
try:
192+
stdout = stdout.fileno()
193+
except (AttributeError, OSError, IOError):
194+
stdout = stdout.write
195+
# Check for text stream to prevent TypeError (see #110).
196+
if callable(stdout):
197+
try:
198+
stdout(b'')
199+
except TypeError:
200+
stdout = TextCallback(stdout)
179201
Popen_args['stdout'] = \
180202
subprocess.PIPE if callable(stdout) else stdout
181203
# stdin=None leads to an error on windows when STDIN is broken.

src/cpymad/stream.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,17 @@ def _read_thread(self):
7373
if not line:
7474
return lines
7575
lines.append(line)
76+
77+
78+
class TextCallback:
79+
80+
"""Decode bytes and pass to callback."""
81+
82+
def __init__(self, callback, encoding='utf-8', errors='replace'):
83+
self.callback = callback
84+
self.encoding = encoding
85+
self.errors = errors
86+
87+
def __call__(self, data):
88+
text = data.decode(self.encoding, errors=self.errors)
89+
return self.callback(text)

0 commit comments

Comments
 (0)