##// END OF EJS Templates
Merge branch 'ipython:master' into master
asteppke -
r27455:34efb114 merge
parent child Browse files
Show More
@@ -0,0 +1,6 b''
1 # Security Policy
2
3 ## Reporting a Vulnerability
4
5 All IPython and Jupyter security are handled via security@ipython.org.
6 You can find more informations on the Jupyter website. https://jupyter.org/security
@@ -2,6 +2,10 b' name: Run tests'
2
2
3 on:
3 on:
4 push:
4 push:
5 branches:
6 - main
7 - master
8 - '*.x'
5 pull_request:
9 pull_request:
6 # Run weekly on Monday at 1:23 UTC
10 # Run weekly on Monday at 1:23 UTC
7 schedule:
11 schedule:
@@ -83,7 +83,7 b' def _display_mimetype(mimetype, objs, raw=False, metadata=None):'
83 if raw:
83 if raw:
84 # turn list of pngdata into list of { 'image/png': pngdata }
84 # turn list of pngdata into list of { 'image/png': pngdata }
85 objs = [ {mimetype: obj} for obj in objs ]
85 objs = [ {mimetype: obj} for obj in objs ]
86 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
86 display_functions.display(*objs, raw=raw, metadata=metadata, include=[mimetype])
87
87
88 #-----------------------------------------------------------------------------
88 #-----------------------------------------------------------------------------
89 # Main functions
89 # Main functions
@@ -517,10 +517,10 b' class ProgressBar(DisplayObject):'
517 self.html_width, self.total, self.progress)
517 self.html_width, self.total, self.progress)
518
518
519 def display(self):
519 def display(self):
520 display(self, display_id=self._display_id)
520 display_functions.display(self, display_id=self._display_id)
521
521
522 def update(self):
522 def update(self):
523 display(self, display_id=self._display_id, update=True)
523 display_functions.display(self, display_id=self._display_id, update=True)
524
524
525 @property
525 @property
526 def progress(self):
526 def progress(self):
@@ -694,7 +694,7 b' class GeoJSON(JSON):'
694 metadata = {
694 metadata = {
695 'application/geo+json': self.metadata
695 'application/geo+json': self.metadata
696 }
696 }
697 display(bundle, metadata=metadata, raw=True)
697 display_functions.display(bundle, metadata=metadata, raw=True)
698
698
699 class Javascript(TextDisplayObject):
699 class Javascript(TextDisplayObject):
700
700
@@ -507,9 +507,12 b' def make_tokens_by_line(lines:List[str]):'
507
507
508 # reexported from token on 3.7+
508 # reexported from token on 3.7+
509 NEWLINE, NL = tokenize.NEWLINE, tokenize.NL # type: ignore
509 NEWLINE, NL = tokenize.NEWLINE, tokenize.NL # type: ignore
510 tokens_by_line:List[List[Any]] = [[]]
510 tokens_by_line: List[List[Any]] = [[]]
511 if len(lines) > 1 and not lines[0].endswith(('\n', '\r', '\r\n', '\x0b', '\x0c')):
511 if len(lines) > 1 and not lines[0].endswith(("\n", "\r", "\r\n", "\x0b", "\x0c")):
512 warnings.warn("`make_tokens_by_line` received a list of lines which do not have lineending markers ('\\n', '\\r', '\\r\\n', '\\x0b', '\\x0c'), behavior will be unspecified")
512 warnings.warn(
513 "`make_tokens_by_line` received a list of lines which do not have lineending markers ('\\n', '\\r', '\\r\\n', '\\x0b', '\\x0c'), behavior will be unspecified",
514 stacklevel=2,
515 )
513 parenlev = 0
516 parenlev = 0
514 try:
517 try:
515 for token in tokenize.generate_tokens(iter(lines).__next__):
518 for token in tokenize.generate_tokens(iter(lines).__next__):
@@ -782,9 +785,6 b' class MaybeAsyncCompile(Compile):'
782 super().__init__()
785 super().__init__()
783 self.flags |= extra_flags
786 self.flags |= extra_flags
784
787
785 def __call__(self, *args, **kwds):
786 return compile(*args, **kwds)
787
788
788
789 class MaybeAsyncCommandCompiler(CommandCompiler):
789 class MaybeAsyncCommandCompiler(CommandCompiler):
790 def __init__(self, extra_flags=0):
790 def __init__(self, extra_flags=0):
@@ -37,6 +37,38 b' arguments::'
37 -o OPTION, --option OPTION
37 -o OPTION, --option OPTION
38 An optional argument.
38 An optional argument.
39
39
40 Here is an elaborated example that uses default parameters in `argument` and calls the `args` in the cell magic::
41
42 from IPython.core.magic import register_cell_magic
43 from IPython.core.magic_arguments import (argument, magic_arguments,
44 parse_argstring)
45
46
47 @magic_arguments()
48 @argument(
49 "--option",
50 "-o",
51 help=("Add an option here"),
52 )
53 @argument(
54 "--style",
55 "-s",
56 default="foo",
57 help=("Add some style arguments"),
58 )
59 @register_cell_magic
60 def my_cell_magic(line, cell):
61 args = parse_argstring(my_cell_magic, line)
62 print(f"{args.option=}")
63 print(f"{args.style=}")
64 print(f"{cell=}")
65
66 In a jupyter notebook, this cell magic can be executed like this::
67
68 %%my_cell_magic -o Hello
69 print("bar")
70 i = 42
71
40 Inheritance diagram:
72 Inheritance diagram:
41
73
42 .. inheritance-diagram:: IPython.core.magic_arguments
74 .. inheritance-diagram:: IPython.core.magic_arguments
@@ -4,6 +4,7 b' Line-based transformers are the simpler ones; token-based transformers are'
4 more complex. See test_inputtransformer2_line for tests for line-based
4 more complex. See test_inputtransformer2_line for tests for line-based
5 transformations.
5 transformations.
6 """
6 """
7 import platform
7 import string
8 import string
8 import sys
9 import sys
9 from textwrap import dedent
10 from textwrap import dedent
@@ -291,6 +292,7 b' def test_check_complete_param(code, expected, number):'
291 assert cc(code) == (expected, number)
292 assert cc(code) == (expected, number)
292
293
293
294
295 @pytest.mark.xfail(platform.python_implementation() == "PyPy", reason="fail on pypy")
294 @pytest.mark.xfail(
296 @pytest.mark.xfail(
295 reason="Bug in python 3.9.8 – bpo 45738",
297 reason="Bug in python 3.9.8 – bpo 45738",
296 condition=sys.version_info in [(3, 9, 8, "final", 0), (3, 11, 0, "alpha", 2)],
298 condition=sys.version_info in [(3, 9, 8, "final", 0), (3, 11, 0, "alpha", 2)],
@@ -319,7 +321,16 b' def test_check_complete():'
319 assert cc("def f():\n x=0\n \\\n ") == ("incomplete", 2)
321 assert cc("def f():\n x=0\n \\\n ") == ("incomplete", 2)
320
322
321
323
322 def test_check_complete_II():
324 @pytest.mark.xfail(platform.python_implementation() == "PyPy", reason="fail on pypy")
325 @pytest.mark.parametrize(
326 "value, expected",
327 [
328 ('''def foo():\n """''', ("incomplete", 4)),
329 ("""async with example:\n pass""", ("incomplete", 4)),
330 ("""async with example:\n pass\n """, ("complete", None)),
331 ],
332 )
333 def test_check_complete_II(value, expected):
323 """
334 """
324 Test that multiple line strings are properly handled.
335 Test that multiple line strings are properly handled.
325
336
@@ -327,25 +338,31 b' def test_check_complete_II():'
327
338
328 """
339 """
329 cc = ipt2.TransformerManager().check_complete
340 cc = ipt2.TransformerManager().check_complete
330 assert cc('''def foo():\n """''') == ("incomplete", 4)
341 assert cc(value) == expected
331
342
332
343
333 def test_check_complete_invalidates_sunken_brackets():
344 @pytest.mark.parametrize(
345 "value, expected",
346 [
347 (")", ("invalid", None)),
348 ("]", ("invalid", None)),
349 ("}", ("invalid", None)),
350 (")(", ("invalid", None)),
351 ("][", ("invalid", None)),
352 ("}{", ("invalid", None)),
353 ("]()(", ("invalid", None)),
354 ("())(", ("invalid", None)),
355 (")[](", ("invalid", None)),
356 ("()](", ("invalid", None)),
357 ],
358 )
359 def test_check_complete_invalidates_sunken_brackets(value, expected):
334 """
360 """
335 Test that a single line with more closing brackets than the opening ones is
361 Test that a single line with more closing brackets than the opening ones is
336 interpreted as invalid
362 interpreted as invalid
337 """
363 """
338 cc = ipt2.TransformerManager().check_complete
364 cc = ipt2.TransformerManager().check_complete
339 assert cc(")") == ("invalid", None)
365 assert cc(value) == expected
340 assert cc("]") == ("invalid", None)
341 assert cc("}") == ("invalid", None)
342 assert cc(")(") == ("invalid", None)
343 assert cc("][") == ("invalid", None)
344 assert cc("}{") == ("invalid", None)
345 assert cc("]()(") == ("invalid", None)
346 assert cc("())(") == ("invalid", None)
347 assert cc(")[](") == ("invalid", None)
348 assert cc("()](") == ("invalid", None)
349
366
350
367
351 def test_null_cleanup_transformer():
368 def test_null_cleanup_transformer():
@@ -406,13 +406,18 b' class TestShellGlob(unittest.TestCase):'
406 self.check_match(patterns, matches)
406 self.check_match(patterns, matches)
407
407
408
408
409 # TODO : pytest.mark.parametrise once nose is gone.
409 @pytest.mark.parametrize(
410 def test_unescape_glob():
410 "globstr, unescaped_globstr",
411 assert path.unescape_glob(r"\*\[\!\]\?") == "*[!]?"
411 [
412 assert path.unescape_glob(r"\\*") == r"\*"
412 (r"\*\[\!\]\?", "*[!]?"),
413 assert path.unescape_glob(r"\\\*") == r"\*"
413 (r"\\*", r"\*"),
414 assert path.unescape_glob(r"\\a") == r"\a"
414 (r"\\\*", r"\*"),
415 assert path.unescape_glob(r"\a") == r"\a"
415 (r"\\a", r"\a"),
416 (r"\a", r"\a"),
417 ],
418 )
419 def test_unescape_glob(globstr, unescaped_globstr):
420 assert path.unescape_glob(globstr) == unescaped_globstr
416
421
417
422
418 @onlyif_unicode_paths
423 @onlyif_unicode_paths
@@ -1,4 +1,3 b''
1 # encoding: utf-8
2 """
1 """
3 Tests for platutils.py
2 Tests for platutils.py
4 """
3 """
@@ -56,35 +55,37 b' def test_find_cmd_fail():'
56 pytest.raises(FindCmdError, find_cmd, "asdfasdf")
55 pytest.raises(FindCmdError, find_cmd, "asdfasdf")
57
56
58
57
59 # TODO: move to pytest.mark.parametrize once nose gone
60 @dec.skip_win32
58 @dec.skip_win32
61 def test_arg_split():
59 @pytest.mark.parametrize(
60 "argstr, argv",
61 [
62 ("hi", ["hi"]),
63 ("hello there", ["hello", "there"]),
64 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
65 # Do not use \N because the tests crash with syntax error in
66 # some cases, for example windows python2.6.
67 ("h\u01cello", ["h\u01cello"]),
68 ('something "with quotes"', ["something", '"with quotes"']),
69 ],
70 )
71 def test_arg_split(argstr, argv):
62 """Ensure that argument lines are correctly split like in a shell."""
72 """Ensure that argument lines are correctly split like in a shell."""
63 tests = [['hi', ['hi']],
73 assert arg_split(argstr) == argv
64 [u'hi', [u'hi']],
74
65 ['hello there', ['hello', 'there']],
75
66 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
67 # Do not use \N because the tests crash with syntax error in
68 # some cases, for example windows python2.6.
69 [u'h\u01cello', [u'h\u01cello']],
70 ['something "with quotes"', ['something', '"with quotes"']],
71 ]
72 for argstr, argv in tests:
73 assert arg_split(argstr) == argv
74
75
76 # TODO: move to pytest.mark.parametrize once nose gone
77 @dec.skip_if_not_win32
76 @dec.skip_if_not_win32
78 def test_arg_split_win32():
77 @pytest.mark.parametrize(
78 "argstr,argv",
79 [
80 ("hi", ["hi"]),
81 ("hello there", ["hello", "there"]),
82 ("h\u01cello", ["h\u01cello"]),
83 ('something "with quotes"', ["something", "with quotes"]),
84 ],
85 )
86 def test_arg_split_win32(argstr, argv):
79 """Ensure that argument lines are correctly split like in a shell."""
87 """Ensure that argument lines are correctly split like in a shell."""
80 tests = [['hi', ['hi']],
88 assert arg_split(argstr) == argv
81 [u'hi', [u'hi']],
82 ['hello there', ['hello', 'there']],
83 [u'h\u01cello', [u'h\u01cello']],
84 ['something "with quotes"', ['something', 'with quotes']],
85 ]
86 for argstr, argv in tests:
87 assert arg_split(argstr) == argv
88
89
89
90
90 class SubProcessTestCase(tt.TempFileMixin):
91 class SubProcessTestCase(tt.TempFileMixin):
@@ -98,7 +99,7 b' class SubProcessTestCase(tt.TempFileMixin):'
98 self.mktmp('\n'.join(lines))
99 self.mktmp('\n'.join(lines))
99
100
100 def test_system(self):
101 def test_system(self):
101 status = system('%s "%s"' % (python, self.fname))
102 status = system(f'{python} "{self.fname}"')
102 self.assertEqual(status, 0)
103 self.assertEqual(status, 0)
103
104
104 def test_system_quotes(self):
105 def test_system_quotes(self):
@@ -145,11 +146,11 b' class SubProcessTestCase(tt.TempFileMixin):'
145
146
146 status = self.assert_interrupts(command)
147 status = self.assert_interrupts(command)
147 self.assertNotEqual(
148 self.assertNotEqual(
148 status, 0, "The process wasn't interrupted. Status: %s" % (status,)
149 status, 0, f"The process wasn't interrupted. Status: {status}"
149 )
150 )
150
151
151 def test_getoutput(self):
152 def test_getoutput(self):
152 out = getoutput('%s "%s"' % (python, self.fname))
153 out = getoutput(f'{python} "{self.fname}"')
153 # we can't rely on the order the line buffered streams are flushed
154 # we can't rely on the order the line buffered streams are flushed
154 try:
155 try:
155 self.assertEqual(out, 'on stderron stdout')
156 self.assertEqual(out, 'on stderron stdout')
@@ -169,7 +170,7 b' class SubProcessTestCase(tt.TempFileMixin):'
169 self.assertEqual(out.strip(), '1')
170 self.assertEqual(out.strip(), '1')
170
171
171 def test_getoutput_error(self):
172 def test_getoutput_error(self):
172 out, err = getoutputerror('%s "%s"' % (python, self.fname))
173 out, err = getoutputerror(f'{python} "{self.fname}"')
173 self.assertEqual(out, 'on stdout')
174 self.assertEqual(out, 'on stdout')
174 self.assertEqual(err, 'on stderr')
175 self.assertEqual(err, 'on stderr')
175
176
@@ -179,7 +180,7 b' class SubProcessTestCase(tt.TempFileMixin):'
179 self.assertEqual(out, '')
180 self.assertEqual(out, '')
180 self.assertEqual(err, '')
181 self.assertEqual(err, '')
181 self.assertEqual(code, 1)
182 self.assertEqual(code, 1)
182 out, err, code = get_output_error_code('%s "%s"' % (python, self.fname))
183 out, err, code = get_output_error_code(f'{python} "{self.fname}"')
183 self.assertEqual(out, 'on stdout')
184 self.assertEqual(out, 'on stdout')
184 self.assertEqual(err, 'on stderr')
185 self.assertEqual(err, 'on stderr')
185 self.assertEqual(code, 0)
186 self.assertEqual(code, 0)
@@ -80,24 +80,22 b' def test_columnize_random():'
80 )
80 )
81
81
82
82
83 # TODO: pytest mark.parametrize once nose removed.
83 @pytest.mark.parametrize("row_first", [True, False])
84 def test_columnize_medium():
84 def test_columnize_medium(row_first):
85 """Test with inputs than shouldn't be wider than 80"""
85 """Test with inputs than shouldn't be wider than 80"""
86 size = 40
86 size = 40
87 items = [l*size for l in 'abc']
87 items = [l*size for l in 'abc']
88 for row_first in [True, False]:
88 out = text.columnize(items, row_first=row_first, displaywidth=80)
89 out = text.columnize(items, row_first=row_first, displaywidth=80)
89 assert out == "\n".join(items + [""]), "row_first={0}".format(row_first)
90 assert out == "\n".join(items + [""]), "row_first={0}".format(row_first)
91
90
92
91
93 # TODO: pytest mark.parametrize once nose removed.
92 @pytest.mark.parametrize("row_first", [True, False])
94 def test_columnize_long():
93 def test_columnize_long(row_first):
95 """Test columnize with inputs longer than the display window"""
94 """Test columnize with inputs longer than the display window"""
96 size = 11
95 size = 11
97 items = [l*size for l in 'abc']
96 items = [l*size for l in 'abc']
98 for row_first in [True, False]:
97 out = text.columnize(items, row_first=row_first, displaywidth=size - 1)
99 out = text.columnize(items, row_first=row_first, displaywidth=size - 1)
98 assert out == "\n".join(items + [""]), "row_first={0}".format(row_first)
100 assert out == "\n".join(items + [""]), "row_first={0}".format(row_first)
101
99
102
100
103 def eval_formatter_check(f):
101 def eval_formatter_check(f):
@@ -14,6 +14,7 b' recursive-exclude tools *'
14 exclude tools
14 exclude tools
15 exclude CONTRIBUTING.md
15 exclude CONTRIBUTING.md
16 exclude .editorconfig
16 exclude .editorconfig
17 exclude SECURITY.md
17
18
18 graft scripts
19 graft scripts
19
20
@@ -81,8 +81,8 b' profile with:'
81 $ ipython locate profile foo
81 $ ipython locate profile foo
82 /home/you/.ipython/profile_foo
82 /home/you/.ipython/profile_foo
83
83
84 These map to the utility functions: :func:`IPython.utils.path.get_ipython_dir`
84 These map to the utility functions: :func:`IPython.paths.get_ipython_dir`
85 and :func:`IPython.utils.path.locate_profile` respectively.
85 and :func:`IPython.paths.locate_profile` respectively.
86
86
87
87
88 .. _profiles_dev:
88 .. _profiles_dev:
@@ -48,7 +48,7 b' or have been turned into explicit errors for better error messages.'
48 I will use this occasion to add the following requests to anyone emitting a
48 I will use this occasion to add the following requests to anyone emitting a
49 deprecation warning:
49 deprecation warning:
50
50
51 - Please use at least ``stacklevel=2`` so that the warning is emitted into the
51 - Please add at least ``stacklevel=2`` so that the warning is emitted into the
52 caller context, and not the callee one.
52 caller context, and not the callee one.
53 - Please add **since which version** something is deprecated.
53 - Please add **since which version** something is deprecated.
54
54
@@ -15,6 +15,7 b' keywords = Interactive, Interpreter, Shell, Embedding'
15 platforms = Linux, Mac OSX, Windows
15 platforms = Linux, Mac OSX, Windows
16 classifiers =
16 classifiers =
17 Framework :: IPython
17 Framework :: IPython
18 Framework :: Jupyter
18 Intended Audience :: Developers
19 Intended Audience :: Developers
19 Intended Audience :: Science/Research
20 Intended Audience :: Science/Research
20 License :: OSI Approved :: BSD License
21 License :: OSI Approved :: BSD License
@@ -23,26 +24,69 b' classifiers ='
23 Programming Language :: Python :: 3 :: Only
24 Programming Language :: Python :: 3 :: Only
24 Topic :: System :: Shells
25 Topic :: System :: Shells
25
26
26
27 [options]
27 [options]
28 packages = find:
28 packages = find:
29 python_requires = >=3.8
29 python_requires = >=3.8
30 zip_safe = False
30 zip_safe = False
31 install_requires =
31 install_requires =
32 setuptools>=18.5
32 appnope; sys_platform == "darwin"
33 jedi>=0.16
33 backcall
34 black
34 colorama; sys_platform == "win32"
35 decorator
35 decorator
36 jedi>=0.16
37 matplotlib-inline
38 pexpect>4.3; sys_platform != "win32"
36 pickleshare
39 pickleshare
37 traitlets>=5
38 prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1
40 prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1
39 pygments>=2.4.0
41 pygments>=2.4.0
40 backcall
42 setuptools>=18.5
41 stack_data
43 stack_data
42 matplotlib-inline
44 traitlets>=5
43 pexpect>4.3; sys_platform != "win32"
45
44 appnope; sys_platform == "darwin"
46 [options.extras_require]
45 colorama; sys_platform == "win32"
47 black =
48 black
49 doc =
50 Sphinx>=1.3
51 kernel =
52 ipykernel
53 nbconvert =
54 nbconvert
55 nbformat =
56 nbformat
57 notebook =
58 ipywidgets
59 notebook
60 parallel =
61 ipyparallel
62 qtconsole =
63 qtconsole
64 terminal =
65 test =
66 pytest
67 pytest-asyncio
68 testpath
69 test_extra =
70 curio
71 matplotlib!=3.2.0
72 nbformat
73 numpy>=1.19
74 pandas
75 pytest
76 testpath
77 trio
78 all =
79 %(black)s
80 %(doc)s
81 %(kernel)s
82 %(nbconvert)s
83 %(nbformat)s
84 %(notebook)s
85 %(parallel)s
86 %(qtconsole)s
87 %(terminal)s
88 %(test_extra)s
89 %(test)s
46
90
47 [options.packages.find]
91 [options.packages.find]
48 exclude =
92 exclude =
@@ -64,7 +108,7 b' pygments.lexers ='
64 ipython3 = IPython.lib.lexers:IPython3Lexer
108 ipython3 = IPython.lib.lexers:IPython3Lexer
65
109
66 [velin]
110 [velin]
67 ignore_patterns =
111 ignore_patterns =
68 IPython/core/tests
112 IPython/core/tests
69 IPython/testing
113 IPython/testing
70
114
@@ -137,46 +137,6 b" setup_args['cmdclass'] = {"
137 'unsymlink': unsymlink,
137 'unsymlink': unsymlink,
138 }
138 }
139
139
140
141 #---------------------------------------------------------------------------
142 # Handle scripts, dependencies, and setuptools specific things
143 #---------------------------------------------------------------------------
144
145 # setuptools requirements
146
147 extras_require = dict(
148 parallel=["ipyparallel"],
149 qtconsole=["qtconsole"],
150 doc=["Sphinx>=1.3"],
151 test=[
152 "pytest",
153 "pytest-asyncio",
154 "testpath",
155 "pygments>=2.4.0",
156 ],
157 test_extra=[
158 "pytest",
159 "testpath",
160 "curio",
161 "matplotlib!=3.2.0",
162 "nbformat",
163 "numpy>=1.19",
164 "pandas",
165 "pygments>=2.4.0",
166 "trio",
167 ],
168 terminal=[],
169 kernel=["ipykernel"],
170 nbformat=["nbformat"],
171 notebook=["notebook", "ipywidgets"],
172 nbconvert=["nbconvert"],
173 )
174
175 everything = set(chain.from_iterable(extras_require.values()))
176 extras_require['all'] = list(sorted(everything))
177
178 setup_args["extras_require"] = extras_require
179
180 #---------------------------------------------------------------------------
140 #---------------------------------------------------------------------------
181 # Do the actual setup now
141 # Do the actual setup now
182 #---------------------------------------------------------------------------
142 #---------------------------------------------------------------------------
General Comments 0
You need to be logged in to leave comments. Login now