##// END OF EJS Templates
Fix compatibility with pytest 8 (#14413)...
M Bussonnier -
r28736:f68c7376 merge
parent child Browse files
Show More
@@ -1,354 +1,354 b''
1 """Tests for pylab tools module.
1 """Tests for pylab tools module.
2 """
2 """
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 from binascii import a2b_base64
8 from binascii import a2b_base64
9 from io import BytesIO
9 from io import BytesIO
10
10
11 import pytest
11 import pytest
12
12
13 matplotlib = pytest.importorskip("matplotlib")
13 matplotlib = pytest.importorskip("matplotlib")
14 matplotlib.use('Agg')
14 matplotlib.use('Agg')
15 from matplotlib.figure import Figure
15 from matplotlib.figure import Figure
16
16
17 from matplotlib import pyplot as plt
17 from matplotlib import pyplot as plt
18 from matplotlib_inline import backend_inline
18 from matplotlib_inline import backend_inline
19 import numpy as np
19 import numpy as np
20
20
21 from IPython.core.getipython import get_ipython
21 from IPython.core.getipython import get_ipython
22 from IPython.core.interactiveshell import InteractiveShell
22 from IPython.core.interactiveshell import InteractiveShell
23 from IPython.core.display import _PNG, _JPEG
23 from IPython.core.display import _PNG, _JPEG
24 from .. import pylabtools as pt
24 from .. import pylabtools as pt
25
25
26 from IPython.testing import decorators as dec
26 from IPython.testing import decorators as dec
27
27
28
28
29 def test_figure_to_svg():
29 def test_figure_to_svg():
30 # simple empty-figure test
30 # simple empty-figure test
31 fig = plt.figure()
31 fig = plt.figure()
32 assert pt.print_figure(fig, "svg") is None
32 assert pt.print_figure(fig, "svg") is None
33
33
34 plt.close('all')
34 plt.close('all')
35
35
36 # simple check for at least svg-looking output
36 # simple check for at least svg-looking output
37 fig = plt.figure()
37 fig = plt.figure()
38 ax = fig.add_subplot(1,1,1)
38 ax = fig.add_subplot(1,1,1)
39 ax.plot([1,2,3])
39 ax.plot([1,2,3])
40 plt.draw()
40 plt.draw()
41 svg = pt.print_figure(fig, "svg")[:100].lower()
41 svg = pt.print_figure(fig, "svg")[:100].lower()
42 assert "doctype svg" in svg
42 assert "doctype svg" in svg
43
43
44
44
45 def _check_pil_jpeg_bytes():
45 def _check_pil_jpeg_bytes():
46 """Skip if PIL can't write JPEGs to BytesIO objects"""
46 """Skip if PIL can't write JPEGs to BytesIO objects"""
47 # PIL's JPEG plugin can't write to BytesIO objects
47 # PIL's JPEG plugin can't write to BytesIO objects
48 # Pillow fixes this
48 # Pillow fixes this
49 from PIL import Image
49 from PIL import Image
50 buf = BytesIO()
50 buf = BytesIO()
51 img = Image.new("RGB", (4,4))
51 img = Image.new("RGB", (4,4))
52 try:
52 try:
53 img.save(buf, 'jpeg')
53 img.save(buf, 'jpeg')
54 except Exception as e:
54 except Exception as e:
55 ename = e.__class__.__name__
55 ename = e.__class__.__name__
56 raise pytest.skip("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) from e
56 raise pytest.skip("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) from e
57
57
58 @dec.skip_without("PIL.Image")
58 @dec.skip_without("PIL.Image")
59 def test_figure_to_jpeg():
59 def test_figure_to_jpeg():
60 _check_pil_jpeg_bytes()
60 _check_pil_jpeg_bytes()
61 # simple check for at least jpeg-looking output
61 # simple check for at least jpeg-looking output
62 fig = plt.figure()
62 fig = plt.figure()
63 ax = fig.add_subplot(1,1,1)
63 ax = fig.add_subplot(1,1,1)
64 ax.plot([1,2,3])
64 ax.plot([1,2,3])
65 plt.draw()
65 plt.draw()
66 jpeg = pt.print_figure(fig, 'jpeg', pil_kwargs={'optimize': 50})[:100].lower()
66 jpeg = pt.print_figure(fig, 'jpeg', pil_kwargs={'optimize': 50})[:100].lower()
67 assert jpeg.startswith(_JPEG)
67 assert jpeg.startswith(_JPEG)
68
68
69 def test_retina_figure():
69 def test_retina_figure():
70 # simple empty-figure test
70 # simple empty-figure test
71 fig = plt.figure()
71 fig = plt.figure()
72 assert pt.retina_figure(fig) == None
72 assert pt.retina_figure(fig) == None
73 plt.close('all')
73 plt.close('all')
74
74
75 fig = plt.figure()
75 fig = plt.figure()
76 ax = fig.add_subplot(1,1,1)
76 ax = fig.add_subplot(1,1,1)
77 ax.plot([1,2,3])
77 ax.plot([1,2,3])
78 plt.draw()
78 plt.draw()
79 png, md = pt.retina_figure(fig)
79 png, md = pt.retina_figure(fig)
80 assert png.startswith(_PNG)
80 assert png.startswith(_PNG)
81 assert "width" in md
81 assert "width" in md
82 assert "height" in md
82 assert "height" in md
83
83
84
84
85 _fmt_mime_map = {
85 _fmt_mime_map = {
86 'png': 'image/png',
86 'png': 'image/png',
87 'jpeg': 'image/jpeg',
87 'jpeg': 'image/jpeg',
88 'pdf': 'application/pdf',
88 'pdf': 'application/pdf',
89 'retina': 'image/png',
89 'retina': 'image/png',
90 'svg': 'image/svg+xml',
90 'svg': 'image/svg+xml',
91 }
91 }
92
92
93 def test_select_figure_formats_str():
93 def test_select_figure_formats_str():
94 ip = get_ipython()
94 ip = get_ipython()
95 for fmt, active_mime in _fmt_mime_map.items():
95 for fmt, active_mime in _fmt_mime_map.items():
96 pt.select_figure_formats(ip, fmt)
96 pt.select_figure_formats(ip, fmt)
97 for mime, f in ip.display_formatter.formatters.items():
97 for mime, f in ip.display_formatter.formatters.items():
98 if mime == active_mime:
98 if mime == active_mime:
99 assert Figure in f
99 assert Figure in f
100 else:
100 else:
101 assert Figure not in f
101 assert Figure not in f
102
102
103 def test_select_figure_formats_kwargs():
103 def test_select_figure_formats_kwargs():
104 ip = get_ipython()
104 ip = get_ipython()
105 kwargs = dict(bbox_inches="tight")
105 kwargs = dict(bbox_inches="tight")
106 pt.select_figure_formats(ip, "png", **kwargs)
106 pt.select_figure_formats(ip, "png", **kwargs)
107 formatter = ip.display_formatter.formatters["image/png"]
107 formatter = ip.display_formatter.formatters["image/png"]
108 f = formatter.lookup_by_type(Figure)
108 f = formatter.lookup_by_type(Figure)
109 cell = f.keywords
109 cell = f.keywords
110 expected = kwargs
110 expected = kwargs
111 expected["base64"] = True
111 expected["base64"] = True
112 expected["fmt"] = "png"
112 expected["fmt"] = "png"
113 assert cell == expected
113 assert cell == expected
114
114
115 # check that the formatter doesn't raise
115 # check that the formatter doesn't raise
116 fig = plt.figure()
116 fig = plt.figure()
117 ax = fig.add_subplot(1,1,1)
117 ax = fig.add_subplot(1,1,1)
118 ax.plot([1,2,3])
118 ax.plot([1,2,3])
119 plt.draw()
119 plt.draw()
120 formatter.enabled = True
120 formatter.enabled = True
121 png = formatter(fig)
121 png = formatter(fig)
122 assert isinstance(png, str)
122 assert isinstance(png, str)
123 png_bytes = a2b_base64(png)
123 png_bytes = a2b_base64(png)
124 assert png_bytes.startswith(_PNG)
124 assert png_bytes.startswith(_PNG)
125
125
126 def test_select_figure_formats_set():
126 def test_select_figure_formats_set():
127 ip = get_ipython()
127 ip = get_ipython()
128 for fmts in [
128 for fmts in [
129 {'png', 'svg'},
129 {'png', 'svg'},
130 ['png'],
130 ['png'],
131 ('jpeg', 'pdf', 'retina'),
131 ('jpeg', 'pdf', 'retina'),
132 {'svg'},
132 {'svg'},
133 ]:
133 ]:
134 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
134 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
135 pt.select_figure_formats(ip, fmts)
135 pt.select_figure_formats(ip, fmts)
136 for mime, f in ip.display_formatter.formatters.items():
136 for mime, f in ip.display_formatter.formatters.items():
137 if mime in active_mimes:
137 if mime in active_mimes:
138 assert Figure in f
138 assert Figure in f
139 else:
139 else:
140 assert Figure not in f
140 assert Figure not in f
141
141
142 def test_select_figure_formats_bad():
142 def test_select_figure_formats_bad():
143 ip = get_ipython()
143 ip = get_ipython()
144 with pytest.raises(ValueError):
144 with pytest.raises(ValueError):
145 pt.select_figure_formats(ip, 'foo')
145 pt.select_figure_formats(ip, 'foo')
146 with pytest.raises(ValueError):
146 with pytest.raises(ValueError):
147 pt.select_figure_formats(ip, {'png', 'foo'})
147 pt.select_figure_formats(ip, {'png', 'foo'})
148 with pytest.raises(ValueError):
148 with pytest.raises(ValueError):
149 pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad'])
149 pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad'])
150
150
151 def test_import_pylab():
151 def test_import_pylab():
152 ns = {}
152 ns = {}
153 pt.import_pylab(ns, import_all=False)
153 pt.import_pylab(ns, import_all=False)
154 assert "plt" in ns
154 assert "plt" in ns
155 assert ns["np"] == np
155 assert ns["np"] == np
156
156
157
157
158 class TestPylabSwitch(object):
158 class TestPylabSwitch(object):
159 class Shell(InteractiveShell):
159 class Shell(InteractiveShell):
160 def init_history(self):
160 def init_history(self):
161 """Sets up the command history, and starts regular autosaves."""
161 """Sets up the command history, and starts regular autosaves."""
162 self.config.HistoryManager.hist_file = ":memory:"
162 self.config.HistoryManager.hist_file = ":memory:"
163 super().init_history()
163 super().init_history()
164
164
165 def enable_gui(self, gui):
165 def enable_gui(self, gui):
166 pass
166 pass
167
167
168 def setup(self):
168 def setup_method(self):
169 import matplotlib
169 import matplotlib
170 def act_mpl(backend):
170 def act_mpl(backend):
171 matplotlib.rcParams['backend'] = backend
171 matplotlib.rcParams['backend'] = backend
172
172
173 # Save rcParams since they get modified
173 # Save rcParams since they get modified
174 self._saved_rcParams = matplotlib.rcParams
174 self._saved_rcParams = matplotlib.rcParams
175 self._saved_rcParamsOrig = matplotlib.rcParamsOrig
175 self._saved_rcParamsOrig = matplotlib.rcParamsOrig
176 matplotlib.rcParams = dict(backend="QtAgg")
176 matplotlib.rcParams = dict(backend="QtAgg")
177 matplotlib.rcParamsOrig = dict(backend="QtAgg")
177 matplotlib.rcParamsOrig = dict(backend="QtAgg")
178
178
179 # Mock out functions
179 # Mock out functions
180 self._save_am = pt.activate_matplotlib
180 self._save_am = pt.activate_matplotlib
181 pt.activate_matplotlib = act_mpl
181 pt.activate_matplotlib = act_mpl
182 self._save_ip = pt.import_pylab
182 self._save_ip = pt.import_pylab
183 pt.import_pylab = lambda *a,**kw:None
183 pt.import_pylab = lambda *a,**kw:None
184 self._save_cis = backend_inline.configure_inline_support
184 self._save_cis = backend_inline.configure_inline_support
185 backend_inline.configure_inline_support = lambda *a, **kw: None
185 backend_inline.configure_inline_support = lambda *a, **kw: None
186
186
187 def teardown(self):
187 def teardown_method(self):
188 pt.activate_matplotlib = self._save_am
188 pt.activate_matplotlib = self._save_am
189 pt.import_pylab = self._save_ip
189 pt.import_pylab = self._save_ip
190 backend_inline.configure_inline_support = self._save_cis
190 backend_inline.configure_inline_support = self._save_cis
191 import matplotlib
191 import matplotlib
192 matplotlib.rcParams = self._saved_rcParams
192 matplotlib.rcParams = self._saved_rcParams
193 matplotlib.rcParamsOrig = self._saved_rcParamsOrig
193 matplotlib.rcParamsOrig = self._saved_rcParamsOrig
194
194
195 def test_qt(self):
195 def test_qt(self):
196 s = self.Shell()
196 s = self.Shell()
197 gui, backend = s.enable_matplotlib(None)
197 gui, backend = s.enable_matplotlib(None)
198 assert gui == "qt"
198 assert gui == "qt"
199 assert s.pylab_gui_select == "qt"
199 assert s.pylab_gui_select == "qt"
200
200
201 gui, backend = s.enable_matplotlib("inline")
201 gui, backend = s.enable_matplotlib("inline")
202 assert gui is None
202 assert gui is None
203 assert s.pylab_gui_select == "qt"
203 assert s.pylab_gui_select == "qt"
204
204
205 gui, backend = s.enable_matplotlib("qt")
205 gui, backend = s.enable_matplotlib("qt")
206 assert gui == "qt"
206 assert gui == "qt"
207 assert s.pylab_gui_select == "qt"
207 assert s.pylab_gui_select == "qt"
208
208
209 gui, backend = s.enable_matplotlib("inline")
209 gui, backend = s.enable_matplotlib("inline")
210 assert gui is None
210 assert gui is None
211 assert s.pylab_gui_select == "qt"
211 assert s.pylab_gui_select == "qt"
212
212
213 gui, backend = s.enable_matplotlib()
213 gui, backend = s.enable_matplotlib()
214 assert gui == "qt"
214 assert gui == "qt"
215 assert s.pylab_gui_select == "qt"
215 assert s.pylab_gui_select == "qt"
216
216
217 def test_inline(self):
217 def test_inline(self):
218 s = self.Shell()
218 s = self.Shell()
219 gui, backend = s.enable_matplotlib("inline")
219 gui, backend = s.enable_matplotlib("inline")
220 assert gui is None
220 assert gui is None
221 assert s.pylab_gui_select == None
221 assert s.pylab_gui_select == None
222
222
223 gui, backend = s.enable_matplotlib("inline")
223 gui, backend = s.enable_matplotlib("inline")
224 assert gui is None
224 assert gui is None
225 assert s.pylab_gui_select == None
225 assert s.pylab_gui_select == None
226
226
227 gui, backend = s.enable_matplotlib("qt")
227 gui, backend = s.enable_matplotlib("qt")
228 assert gui == "qt"
228 assert gui == "qt"
229 assert s.pylab_gui_select == "qt"
229 assert s.pylab_gui_select == "qt"
230
230
231 def test_inline_twice(self):
231 def test_inline_twice(self):
232 "Using '%matplotlib inline' twice should not reset formatters"
232 "Using '%matplotlib inline' twice should not reset formatters"
233
233
234 ip = self.Shell()
234 ip = self.Shell()
235 gui, backend = ip.enable_matplotlib("inline")
235 gui, backend = ip.enable_matplotlib("inline")
236 assert gui is None
236 assert gui is None
237
237
238 fmts = {'png'}
238 fmts = {'png'}
239 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
239 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
240 pt.select_figure_formats(ip, fmts)
240 pt.select_figure_formats(ip, fmts)
241
241
242 gui, backend = ip.enable_matplotlib("inline")
242 gui, backend = ip.enable_matplotlib("inline")
243 assert gui is None
243 assert gui is None
244
244
245 for mime, f in ip.display_formatter.formatters.items():
245 for mime, f in ip.display_formatter.formatters.items():
246 if mime in active_mimes:
246 if mime in active_mimes:
247 assert Figure in f
247 assert Figure in f
248 else:
248 else:
249 assert Figure not in f
249 assert Figure not in f
250
250
251 def test_qt_gtk(self):
251 def test_qt_gtk(self):
252 s = self.Shell()
252 s = self.Shell()
253 gui, backend = s.enable_matplotlib("qt")
253 gui, backend = s.enable_matplotlib("qt")
254 assert gui == "qt"
254 assert gui == "qt"
255 assert s.pylab_gui_select == "qt"
255 assert s.pylab_gui_select == "qt"
256
256
257 gui, backend = s.enable_matplotlib("gtk3")
257 gui, backend = s.enable_matplotlib("gtk3")
258 assert gui == "qt"
258 assert gui == "qt"
259 assert s.pylab_gui_select == "qt"
259 assert s.pylab_gui_select == "qt"
260
260
261
261
262 def test_no_gui_backends():
262 def test_no_gui_backends():
263 for k in ['agg', 'svg', 'pdf', 'ps']:
263 for k in ['agg', 'svg', 'pdf', 'ps']:
264 assert k not in pt.backend2gui
264 assert k not in pt.backend2gui
265
265
266
266
267 def test_figure_no_canvas():
267 def test_figure_no_canvas():
268 fig = Figure()
268 fig = Figure()
269 fig.canvas = None
269 fig.canvas = None
270 pt.print_figure(fig)
270 pt.print_figure(fig)
271
271
272
272
273 @pytest.mark.parametrize(
273 @pytest.mark.parametrize(
274 "name, expected_gui, expected_backend",
274 "name, expected_gui, expected_backend",
275 [
275 [
276 # name is gui
276 # name is gui
277 ("gtk3", "gtk3", "gtk3agg"),
277 ("gtk3", "gtk3", "gtk3agg"),
278 ("gtk4", "gtk4", "gtk4agg"),
278 ("gtk4", "gtk4", "gtk4agg"),
279 ("headless", "headless", "agg"),
279 ("headless", "headless", "agg"),
280 ("osx", "osx", "macosx"),
280 ("osx", "osx", "macosx"),
281 ("qt", "qt", "qtagg"),
281 ("qt", "qt", "qtagg"),
282 ("qt5", "qt5", "qt5agg"),
282 ("qt5", "qt5", "qt5agg"),
283 ("qt6", "qt6", "qt6agg"),
283 ("qt6", "qt6", "qt6agg"),
284 ("tk", "tk", "tkagg"),
284 ("tk", "tk", "tkagg"),
285 ("wx", "wx", "wxagg"),
285 ("wx", "wx", "wxagg"),
286 # name is backend
286 # name is backend
287 ("agg", None, "agg"),
287 ("agg", None, "agg"),
288 ("cairo", None, "cairo"),
288 ("cairo", None, "cairo"),
289 ("pdf", None, "pdf"),
289 ("pdf", None, "pdf"),
290 ("ps", None, "ps"),
290 ("ps", None, "ps"),
291 ("svg", None, "svg"),
291 ("svg", None, "svg"),
292 ("template", None, "template"),
292 ("template", None, "template"),
293 ("gtk3agg", "gtk3", "gtk3agg"),
293 ("gtk3agg", "gtk3", "gtk3agg"),
294 ("gtk3cairo", "gtk3", "gtk3cairo"),
294 ("gtk3cairo", "gtk3", "gtk3cairo"),
295 ("gtk4agg", "gtk4", "gtk4agg"),
295 ("gtk4agg", "gtk4", "gtk4agg"),
296 ("gtk4cairo", "gtk4", "gtk4cairo"),
296 ("gtk4cairo", "gtk4", "gtk4cairo"),
297 ("macosx", "osx", "macosx"),
297 ("macosx", "osx", "macosx"),
298 ("nbagg", "nbagg", "nbagg"),
298 ("nbagg", "nbagg", "nbagg"),
299 ("notebook", "nbagg", "notebook"),
299 ("notebook", "nbagg", "notebook"),
300 ("qtagg", "qt", "qtagg"),
300 ("qtagg", "qt", "qtagg"),
301 ("qtcairo", "qt", "qtcairo"),
301 ("qtcairo", "qt", "qtcairo"),
302 ("qt5agg", "qt5", "qt5agg"),
302 ("qt5agg", "qt5", "qt5agg"),
303 ("qt5cairo", "qt5", "qt5cairo"),
303 ("qt5cairo", "qt5", "qt5cairo"),
304 ("qt6agg", "qt", "qt6agg"),
304 ("qt6agg", "qt", "qt6agg"),
305 ("qt6cairo", "qt", "qt6cairo"),
305 ("qt6cairo", "qt", "qt6cairo"),
306 ("tkagg", "tk", "tkagg"),
306 ("tkagg", "tk", "tkagg"),
307 ("tkcairo", "tk", "tkcairo"),
307 ("tkcairo", "tk", "tkcairo"),
308 ("webagg", "webagg", "webagg"),
308 ("webagg", "webagg", "webagg"),
309 ("wxagg", "wx", "wxagg"),
309 ("wxagg", "wx", "wxagg"),
310 ("wxcairo", "wx", "wxcairo"),
310 ("wxcairo", "wx", "wxcairo"),
311 ],
311 ],
312 )
312 )
313 def test_backend_builtin(name, expected_gui, expected_backend):
313 def test_backend_builtin(name, expected_gui, expected_backend):
314 # Test correct identification of Matplotlib built-in backends without importing and using them,
314 # Test correct identification of Matplotlib built-in backends without importing and using them,
315 # otherwise we would need to ensure all the complex dependencies such as windowing toolkits are
315 # otherwise we would need to ensure all the complex dependencies such as windowing toolkits are
316 # installed.
316 # installed.
317
317
318 mpl_manages_backends = pt._matplotlib_manages_backends()
318 mpl_manages_backends = pt._matplotlib_manages_backends()
319 if not mpl_manages_backends:
319 if not mpl_manages_backends:
320 # Backends not supported before _matplotlib_manages_backends or supported
320 # Backends not supported before _matplotlib_manages_backends or supported
321 # but with different expected_gui or expected_backend.
321 # but with different expected_gui or expected_backend.
322 if (
322 if (
323 name.endswith("agg")
323 name.endswith("agg")
324 or name.endswith("cairo")
324 or name.endswith("cairo")
325 or name in ("headless", "macosx", "pdf", "ps", "svg", "template")
325 or name in ("headless", "macosx", "pdf", "ps", "svg", "template")
326 ):
326 ):
327 pytest.skip()
327 pytest.skip()
328 elif name == "qt6":
328 elif name == "qt6":
329 expected_backend = "qtagg"
329 expected_backend = "qtagg"
330 elif name == "notebook":
330 elif name == "notebook":
331 expected_backend, expected_gui = expected_gui, expected_backend
331 expected_backend, expected_gui = expected_gui, expected_backend
332
332
333 gui, backend = pt.find_gui_and_backend(name)
333 gui, backend = pt.find_gui_and_backend(name)
334 if not mpl_manages_backends:
334 if not mpl_manages_backends:
335 gui = gui.lower() if gui else None
335 gui = gui.lower() if gui else None
336 backend = backend.lower() if backend else None
336 backend = backend.lower() if backend else None
337 assert gui == expected_gui
337 assert gui == expected_gui
338 assert backend == expected_backend
338 assert backend == expected_backend
339
339
340
340
341 def test_backend_entry_point():
341 def test_backend_entry_point():
342 gui, backend = pt.find_gui_and_backend("inline")
342 gui, backend = pt.find_gui_and_backend("inline")
343 assert gui is None
343 assert gui is None
344 expected_backend = (
344 expected_backend = (
345 "inline"
345 "inline"
346 if pt._matplotlib_manages_backends()
346 if pt._matplotlib_manages_backends()
347 else "module://matplotlib_inline.backend_inline"
347 else "module://matplotlib_inline.backend_inline"
348 )
348 )
349 assert backend == expected_backend
349 assert backend == expected_backend
350
350
351
351
352 def test_backend_unknown():
352 def test_backend_unknown():
353 with pytest.raises(RuntimeError if pt._matplotlib_manages_backends() else KeyError):
353 with pytest.raises(RuntimeError if pt._matplotlib_manages_backends() else KeyError):
354 pt.find_gui_and_backend("name-does-not-exist")
354 pt.find_gui_and_backend("name-does-not-exist")
@@ -1,209 +1,209 b''
1 [build-system]
1 [build-system]
2 requires = ["setuptools>=61.2"]
2 requires = ["setuptools>=61.2"]
3 # We need access to the 'setupbase' module at build time.
3 # We need access to the 'setupbase' module at build time.
4 # Hence we declare a custom build backend.
4 # Hence we declare a custom build backend.
5 build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions
5 build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions
6 backend-path = ["."]
6 backend-path = ["."]
7
7
8 [project]
8 [project]
9 name = "ipython"
9 name = "ipython"
10 description = "IPython: Productive Interactive Computing"
10 description = "IPython: Productive Interactive Computing"
11 keywords = ["Interactive", "Interpreter", "Shell", "Embedding"]
11 keywords = ["Interactive", "Interpreter", "Shell", "Embedding"]
12 classifiers = [
12 classifiers = [
13 "Framework :: IPython",
13 "Framework :: IPython",
14 "Framework :: Jupyter",
14 "Framework :: Jupyter",
15 "Intended Audience :: Developers",
15 "Intended Audience :: Developers",
16 "Intended Audience :: Science/Research",
16 "Intended Audience :: Science/Research",
17 "License :: OSI Approved :: BSD License",
17 "License :: OSI Approved :: BSD License",
18 "Programming Language :: Python",
18 "Programming Language :: Python",
19 "Programming Language :: Python :: 3",
19 "Programming Language :: Python :: 3",
20 "Programming Language :: Python :: 3 :: Only",
20 "Programming Language :: Python :: 3 :: Only",
21 "Topic :: System :: Shells",
21 "Topic :: System :: Shells",
22 ]
22 ]
23 requires-python = ">=3.10"
23 requires-python = ">=3.10"
24 dependencies = [
24 dependencies = [
25 'colorama; sys_platform == "win32"',
25 'colorama; sys_platform == "win32"',
26 "decorator",
26 "decorator",
27 "exceptiongroup; python_version<'3.11'",
27 "exceptiongroup; python_version<'3.11'",
28 "jedi>=0.16",
28 "jedi>=0.16",
29 "matplotlib-inline",
29 "matplotlib-inline",
30 'pexpect>4.3; sys_platform != "win32" and sys_platform != "emscripten"',
30 'pexpect>4.3; sys_platform != "win32" and sys_platform != "emscripten"',
31 "prompt_toolkit>=3.0.41,<3.1.0",
31 "prompt_toolkit>=3.0.41,<3.1.0",
32 "pygments>=2.4.0",
32 "pygments>=2.4.0",
33 "stack_data",
33 "stack_data",
34 "traitlets>=5.13.0",
34 "traitlets>=5.13.0",
35 "typing_extensions>=4.6; python_version<'3.12'",
35 "typing_extensions>=4.6; python_version<'3.12'",
36 ]
36 ]
37 dynamic = ["authors", "license", "version"]
37 dynamic = ["authors", "license", "version"]
38
38
39 [project.entry-points."pygments.lexers"]
39 [project.entry-points."pygments.lexers"]
40 ipythonconsole = "IPython.lib.lexers:IPythonConsoleLexer"
40 ipythonconsole = "IPython.lib.lexers:IPythonConsoleLexer"
41 ipython = "IPython.lib.lexers:IPythonLexer"
41 ipython = "IPython.lib.lexers:IPythonLexer"
42 ipython3 = "IPython.lib.lexers:IPython3Lexer"
42 ipython3 = "IPython.lib.lexers:IPython3Lexer"
43
43
44 [project.scripts]
44 [project.scripts]
45 ipython = "IPython:start_ipython"
45 ipython = "IPython:start_ipython"
46 ipython3 = "IPython:start_ipython"
46 ipython3 = "IPython:start_ipython"
47
47
48 [project.readme]
48 [project.readme]
49 file = "long_description.rst"
49 file = "long_description.rst"
50 content-type = "text/x-rst"
50 content-type = "text/x-rst"
51
51
52 [project.urls]
52 [project.urls]
53 Homepage = "https://ipython.org"
53 Homepage = "https://ipython.org"
54 Documentation = "https://ipython.readthedocs.io/"
54 Documentation = "https://ipython.readthedocs.io/"
55 Funding = "https://numfocus.org/"
55 Funding = "https://numfocus.org/"
56 Source = "https://github.com/ipython/ipython"
56 Source = "https://github.com/ipython/ipython"
57 Tracker = "https://github.com/ipython/ipython/issues"
57 Tracker = "https://github.com/ipython/ipython/issues"
58
58
59 [project.optional-dependencies]
59 [project.optional-dependencies]
60 black = [
60 black = [
61 "black",
61 "black",
62 ]
62 ]
63 doc = [
63 doc = [
64 "ipykernel",
64 "ipykernel",
65 "setuptools>=18.5",
65 "setuptools>=18.5",
66 "sphinx>=1.3",
66 "sphinx>=1.3",
67 "sphinx-rtd-theme",
67 "sphinx-rtd-theme",
68 "sphinxcontrib-jquery",
68 "sphinxcontrib-jquery",
69 "docrepr",
69 "docrepr",
70 "matplotlib",
70 "matplotlib",
71 "stack_data",
71 "stack_data",
72 "typing_extensions",
72 "typing_extensions",
73 "exceptiongroup",
73 "exceptiongroup",
74 "ipython[test]",
74 "ipython[test]",
75 ]
75 ]
76 kernel = [
76 kernel = [
77 "ipykernel",
77 "ipykernel",
78 ]
78 ]
79 nbconvert = [
79 nbconvert = [
80 "nbconvert",
80 "nbconvert",
81 ]
81 ]
82 nbformat = [
82 nbformat = [
83 "nbformat",
83 "nbformat",
84 ]
84 ]
85 notebook = [
85 notebook = [
86 "ipywidgets",
86 "ipywidgets",
87 "notebook",
87 "notebook",
88 ]
88 ]
89 parallel = [
89 parallel = [
90 "ipyparallel",
90 "ipyparallel",
91 ]
91 ]
92 qtconsole = [
92 qtconsole = [
93 "qtconsole",
93 "qtconsole",
94 ]
94 ]
95 terminal = []
95 terminal = []
96 test = [
96 test = [
97 "pytest<8",
97 "pytest",
98 "pytest-asyncio<0.22",
98 "pytest-asyncio<0.22",
99 "testpath",
99 "testpath",
100 "pickleshare",
100 "pickleshare",
101 ]
101 ]
102 test_extra = [
102 test_extra = [
103 "ipython[test]",
103 "ipython[test]",
104 "curio",
104 "curio",
105 "matplotlib!=3.2.0",
105 "matplotlib!=3.2.0",
106 "nbformat",
106 "nbformat",
107 "numpy>=1.23",
107 "numpy>=1.23",
108 "pandas",
108 "pandas",
109 "trio",
109 "trio",
110 ]
110 ]
111 matplotlib = [
111 matplotlib = [
112 "matplotlib"
112 "matplotlib"
113 ]
113 ]
114 all = [
114 all = [
115 "ipython[black,doc,kernel,nbconvert,nbformat,notebook,parallel,qtconsole,matplotlib]",
115 "ipython[black,doc,kernel,nbconvert,nbformat,notebook,parallel,qtconsole,matplotlib]",
116 "ipython[test,test_extra]",
116 "ipython[test,test_extra]",
117 ]
117 ]
118
118
119 [tool.mypy]
119 [tool.mypy]
120 python_version = "3.10"
120 python_version = "3.10"
121 ignore_missing_imports = true
121 ignore_missing_imports = true
122 follow_imports = 'silent'
122 follow_imports = 'silent'
123 exclude = [
123 exclude = [
124 'test_\.+\.py',
124 'test_\.+\.py',
125 'IPython.utils.tests.test_wildcard',
125 'IPython.utils.tests.test_wildcard',
126 'testing',
126 'testing',
127 'tests',
127 'tests',
128 'PyColorize.py',
128 'PyColorize.py',
129 '_process_win32_controller.py',
129 '_process_win32_controller.py',
130 'IPython/core/application.py',
130 'IPython/core/application.py',
131 'IPython/core/profileapp.py',
131 'IPython/core/profileapp.py',
132 'IPython/lib/deepreload.py',
132 'IPython/lib/deepreload.py',
133 'IPython/sphinxext/ipython_directive.py',
133 'IPython/sphinxext/ipython_directive.py',
134 'IPython/terminal/ipapp.py',
134 'IPython/terminal/ipapp.py',
135 'IPython/utils/_process_win32.py',
135 'IPython/utils/_process_win32.py',
136 'IPython/utils/path.py',
136 'IPython/utils/path.py',
137 ]
137 ]
138
138
139 [tool.pytest.ini_options]
139 [tool.pytest.ini_options]
140 addopts = [
140 addopts = [
141 "--durations=10",
141 "--durations=10",
142 "-pIPython.testing.plugin.pytest_ipdoctest",
142 "-pIPython.testing.plugin.pytest_ipdoctest",
143 "--ipdoctest-modules",
143 "--ipdoctest-modules",
144 "--ignore=docs",
144 "--ignore=docs",
145 "--ignore=examples",
145 "--ignore=examples",
146 "--ignore=htmlcov",
146 "--ignore=htmlcov",
147 "--ignore=ipython_kernel",
147 "--ignore=ipython_kernel",
148 "--ignore=ipython_parallel",
148 "--ignore=ipython_parallel",
149 "--ignore=results",
149 "--ignore=results",
150 "--ignore=tmp",
150 "--ignore=tmp",
151 "--ignore=tools",
151 "--ignore=tools",
152 "--ignore=traitlets",
152 "--ignore=traitlets",
153 "--ignore=IPython/core/tests/daft_extension",
153 "--ignore=IPython/core/tests/daft_extension",
154 "--ignore=IPython/sphinxext",
154 "--ignore=IPython/sphinxext",
155 "--ignore=IPython/terminal/pt_inputhooks",
155 "--ignore=IPython/terminal/pt_inputhooks",
156 "--ignore=IPython/__main__.py",
156 "--ignore=IPython/__main__.py",
157 "--ignore=IPython/external/qt_for_kernel.py",
157 "--ignore=IPython/external/qt_for_kernel.py",
158 "--ignore=IPython/html/widgets/widget_link.py",
158 "--ignore=IPython/html/widgets/widget_link.py",
159 "--ignore=IPython/html/widgets/widget_output.py",
159 "--ignore=IPython/html/widgets/widget_output.py",
160 "--ignore=IPython/terminal/console.py",
160 "--ignore=IPython/terminal/console.py",
161 "--ignore=IPython/utils/_process_cli.py",
161 "--ignore=IPython/utils/_process_cli.py",
162 "--ignore=IPython/utils/_process_posix.py",
162 "--ignore=IPython/utils/_process_posix.py",
163 "--ignore=IPython/utils/_process_win32.py",
163 "--ignore=IPython/utils/_process_win32.py",
164 "--ignore=IPython/utils/_process_win32_controller.py",
164 "--ignore=IPython/utils/_process_win32_controller.py",
165 "--ignore=IPython/utils/daemonize.py",
165 "--ignore=IPython/utils/daemonize.py",
166 "--ignore=IPython/utils/eventful.py",
166 "--ignore=IPython/utils/eventful.py",
167 "--ignore=IPython/kernel",
167 "--ignore=IPython/kernel",
168 "--ignore=IPython/consoleapp.py",
168 "--ignore=IPython/consoleapp.py",
169 "--ignore=IPython/core/inputsplitter.py",
169 "--ignore=IPython/core/inputsplitter.py",
170 "--ignore=IPython/lib/kernel.py",
170 "--ignore=IPython/lib/kernel.py",
171 "--ignore=IPython/utils/jsonutil.py",
171 "--ignore=IPython/utils/jsonutil.py",
172 "--ignore=IPython/utils/localinterfaces.py",
172 "--ignore=IPython/utils/localinterfaces.py",
173 "--ignore=IPython/utils/log.py",
173 "--ignore=IPython/utils/log.py",
174 "--ignore=IPython/utils/signatures.py",
174 "--ignore=IPython/utils/signatures.py",
175 "--ignore=IPython/utils/traitlets.py",
175 "--ignore=IPython/utils/traitlets.py",
176 "--ignore=IPython/utils/version.py"
176 "--ignore=IPython/utils/version.py"
177 ]
177 ]
178 doctest_optionflags = [
178 doctest_optionflags = [
179 "NORMALIZE_WHITESPACE",
179 "NORMALIZE_WHITESPACE",
180 "ELLIPSIS"
180 "ELLIPSIS"
181 ]
181 ]
182 ipdoctest_optionflags = [
182 ipdoctest_optionflags = [
183 "NORMALIZE_WHITESPACE",
183 "NORMALIZE_WHITESPACE",
184 "ELLIPSIS"
184 "ELLIPSIS"
185 ]
185 ]
186 asyncio_mode = "strict"
186 asyncio_mode = "strict"
187
187
188 [tool.pyright]
188 [tool.pyright]
189 pythonPlatform="All"
189 pythonPlatform="All"
190
190
191 [tool.setuptools]
191 [tool.setuptools]
192 zip-safe = false
192 zip-safe = false
193 platforms = ["Linux", "Mac OSX", "Windows"]
193 platforms = ["Linux", "Mac OSX", "Windows"]
194 license-files = ["LICENSE"]
194 license-files = ["LICENSE"]
195 include-package-data = false
195 include-package-data = false
196
196
197 [tool.setuptools.packages.find]
197 [tool.setuptools.packages.find]
198 exclude = ["setupext"]
198 exclude = ["setupext"]
199 namespaces = false
199 namespaces = false
200
200
201 [tool.setuptools.package-data]
201 [tool.setuptools.package-data]
202 "IPython" = ["py.typed"]
202 "IPython" = ["py.typed"]
203 "IPython.core" = ["profile/README*"]
203 "IPython.core" = ["profile/README*"]
204 "IPython.core.tests" = ["*.png", "*.jpg", "daft_extension/*.py"]
204 "IPython.core.tests" = ["*.png", "*.jpg", "daft_extension/*.py"]
205 "IPython.lib.tests" = ["*.wav"]
205 "IPython.lib.tests" = ["*.wav"]
206 "IPython.testing.plugin" = ["*.txt"]
206 "IPython.testing.plugin" = ["*.txt"]
207
207
208 [tool.setuptools.dynamic]
208 [tool.setuptools.dynamic]
209 version = {attr = "IPython.core.release.__version__"}
209 version = {attr = "IPython.core.release.__version__"}
General Comments 0
You need to be logged in to leave comments. Login now