Show More
@@ -24,3 +24,6 b' __pycache__' | |||||
24 | .cache |
|
24 | .cache | |
25 | .coverage |
|
25 | .coverage | |
26 | *.swp |
|
26 | *.swp | |
|
27 | .vscode | |||
|
28 | .pytest_cache | |||
|
29 | .python-version |
@@ -14,7 +14,8 b' group: edge' | |||||
14 | before_install: |
|
14 | before_install: | |
15 | - 'if [[ $GROUP != js* ]]; then COVERAGE=""; fi' |
|
15 | - 'if [[ $GROUP != js* ]]; then COVERAGE=""; fi' | |
16 | install: |
|
16 | install: | |
17 |
- pip install |
|
17 | - pip install pip --upgrade | |
|
18 | - pip install setuptools --upgrade | |||
18 | - pip install -e file://$PWD#egg=ipython[test] --upgrade |
|
19 | - pip install -e file://$PWD#egg=ipython[test] --upgrade | |
19 | - pip install codecov check-manifest --upgrade |
|
20 | - pip install codecov check-manifest --upgrade | |
20 | - sudo apt-get install graphviz |
|
21 | - sudo apt-get install graphviz |
@@ -2,7 +2,7 b'' | |||||
2 | """ |
|
2 | """ | |
3 | IPython: tools for interactive and parallel computing in Python. |
|
3 | IPython: tools for interactive and parallel computing in Python. | |
4 |
|
4 | |||
5 | http://ipython.org |
|
5 | https://ipython.org | |
6 | """ |
|
6 | """ | |
7 | #----------------------------------------------------------------------------- |
|
7 | #----------------------------------------------------------------------------- | |
8 | # Copyright (c) 2008-2011, IPython Development Team. |
|
8 | # Copyright (c) 2008-2011, IPython Development Team. |
@@ -40,7 +40,7 b' import time' | |||||
40 | # Constants |
|
40 | # Constants | |
41 | #----------------------------------------------------------------------------- |
|
41 | #----------------------------------------------------------------------------- | |
42 |
|
42 | |||
43 |
# Rough |
|
43 | # Roughly equal to PyCF_MASK | PyCF_MASK_OBSOLETE as defined in pythonrun.h, | |
44 | # this is used as a bitmask to extract future-related code flags. |
|
44 | # this is used as a bitmask to extract future-related code flags. | |
45 | PyCF_MASK = functools.reduce(operator.or_, |
|
45 | PyCF_MASK = functools.reduce(operator.or_, | |
46 | (getattr(__future__, fname).compiler_flag |
|
46 | (getattr(__future__, fname).compiler_flag | |
@@ -52,7 +52,7 b' PyCF_MASK = functools.reduce(operator.or_,' | |||||
52 |
|
52 | |||
53 | def code_name(code, number=0): |
|
53 | def code_name(code, number=0): | |
54 | """ Compute a (probably) unique name for code for caching. |
|
54 | """ Compute a (probably) unique name for code for caching. | |
55 |
|
55 | |||
56 | This now expects code to be unicode. |
|
56 | This now expects code to be unicode. | |
57 | """ |
|
57 | """ | |
58 | hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest() |
|
58 | hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest() | |
@@ -71,7 +71,7 b' class CachingCompiler(codeop.Compile):' | |||||
71 |
|
71 | |||
72 | def __init__(self): |
|
72 | def __init__(self): | |
73 | codeop.Compile.__init__(self) |
|
73 | codeop.Compile.__init__(self) | |
74 |
|
74 | |||
75 | # This is ugly, but it must be done this way to allow multiple |
|
75 | # This is ugly, but it must be done this way to allow multiple | |
76 | # simultaneous ipython instances to coexist. Since Python itself |
|
76 | # simultaneous ipython instances to coexist. Since Python itself | |
77 | # directly accesses the data structures in the linecache module, and |
|
77 | # directly accesses the data structures in the linecache module, and | |
@@ -95,7 +95,7 b' class CachingCompiler(codeop.Compile):' | |||||
95 | def _fix_module_ds(self, module): |
|
95 | def _fix_module_ds(self, module): | |
96 | """ |
|
96 | """ | |
97 | Starting in python 3.7 the AST for mule have changed, and if |
|
97 | Starting in python 3.7 the AST for mule have changed, and if | |
98 |
the first expressions encountered is a string it is attached to the |
|
98 | the first expressions encountered is a string it is attached to the | |
99 | `docstring` attribute of the `Module` ast node. |
|
99 | `docstring` attribute of the `Module` ast node. | |
100 |
|
100 | |||
101 | This breaks IPython, as if this string is the only expression, IPython |
|
101 | This breaks IPython, as if this string is the only expression, IPython | |
@@ -108,14 +108,14 b' class CachingCompiler(codeop.Compile):' | |||||
108 | new_body=[Expr(Str(docstring, lineno=1, col_offset=0), lineno=1, col_offset=0)] |
|
108 | new_body=[Expr(Str(docstring, lineno=1, col_offset=0), lineno=1, col_offset=0)] | |
109 | new_body.extend(module.body) |
|
109 | new_body.extend(module.body) | |
110 | return fix_missing_locations(Module(new_body)) |
|
110 | return fix_missing_locations(Module(new_body)) | |
111 |
|
111 | |||
112 | def ast_parse(self, source, filename='<unknown>', symbol='exec'): |
|
112 | def ast_parse(self, source, filename='<unknown>', symbol='exec'): | |
113 | """Parse code to an AST with the current compiler flags active. |
|
113 | """Parse code to an AST with the current compiler flags active. | |
114 |
|
114 | |||
115 | Arguments are exactly the same as ast.parse (in the standard library), |
|
115 | Arguments are exactly the same as ast.parse (in the standard library), | |
116 | and are passed to the built-in compile function.""" |
|
116 | and are passed to the built-in compile function.""" | |
117 | return self._fix_module_ds(compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)) |
|
117 | return self._fix_module_ds(compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)) | |
118 |
|
118 | |||
119 | def reset_compiler_flags(self): |
|
119 | def reset_compiler_flags(self): | |
120 | """Reset compiler flags to default state.""" |
|
120 | """Reset compiler flags to default state.""" | |
121 | # This value is copied from codeop.Compile.__init__, so if that ever |
|
121 | # This value is copied from codeop.Compile.__init__, so if that ever | |
@@ -127,10 +127,10 b' class CachingCompiler(codeop.Compile):' | |||||
127 | """Flags currently active in the compilation process. |
|
127 | """Flags currently active in the compilation process. | |
128 | """ |
|
128 | """ | |
129 | return self.flags |
|
129 | return self.flags | |
130 |
|
130 | |||
131 | def cache(self, code, number=0): |
|
131 | def cache(self, code, number=0): | |
132 | """Make a name for a block of code, and cache the code. |
|
132 | """Make a name for a block of code, and cache the code. | |
133 |
|
133 | |||
134 | Parameters |
|
134 | Parameters | |
135 | ---------- |
|
135 | ---------- | |
136 | code : str |
|
136 | code : str | |
@@ -138,7 +138,7 b' class CachingCompiler(codeop.Compile):' | |||||
138 | number : int |
|
138 | number : int | |
139 | A number which forms part of the code's name. Used for the execution |
|
139 | A number which forms part of the code's name. Used for the execution | |
140 | counter. |
|
140 | counter. | |
141 |
|
141 | |||
142 | Returns |
|
142 | Returns | |
143 | ------- |
|
143 | ------- | |
144 | The name of the cached code (as a string). Pass this as the filename |
|
144 | The name of the cached code (as a string). Pass this as the filename |
@@ -1592,7 +1592,7 b' class IPCompleter(Completer):' | |||||
1592 | $ |
|
1592 | $ | |
1593 | ''' |
|
1593 | ''' | |
1594 | regexps = self.__dict_key_regexps = { |
|
1594 | regexps = self.__dict_key_regexps = { | |
1595 | False: re.compile(dict_key_re_fmt % ''' |
|
1595 | False: re.compile(dict_key_re_fmt % r''' | |
1596 | # identifiers separated by . |
|
1596 | # identifiers separated by . | |
1597 | (?!\d)\w+ |
|
1597 | (?!\d)\w+ | |
1598 | (?:\.(?!\d)\w+)* |
|
1598 | (?:\.(?!\d)\w+)* |
@@ -165,7 +165,7 b' def try_import(mod: str, only_modules=False) -> List[str]:' | |||||
165 | except: |
|
165 | except: | |
166 | return [] |
|
166 | return [] | |
167 |
|
167 | |||
168 | m_is_init = hasattr(m, '__file__') and '__init__' in m.__file__ |
|
168 | m_is_init = '__init__' in (getattr(m, '__file__', '') or '') | |
169 |
|
169 | |||
170 | completions = [] |
|
170 | completions = [] | |
171 | if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init: |
|
171 | if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init: |
@@ -176,7 +176,7 b' class Tracer(object):' | |||||
176 | self.debugger.set_trace(sys._getframe().f_back) |
|
176 | self.debugger.set_trace(sys._getframe().f_back) | |
177 |
|
177 | |||
178 |
|
178 | |||
179 | RGX_EXTRA_INDENT = re.compile('(?<=\n)\s+') |
|
179 | RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+') | |
180 |
|
180 | |||
181 |
|
181 | |||
182 | def strip_indentation(multiline_string): |
|
182 | def strip_indentation(multiline_string): |
@@ -800,7 +800,7 b' class JSON(DisplayObject):' | |||||
800 | """ |
|
800 | """ | |
801 | # wrap data in a property, which warns about passing already-serialized JSON |
|
801 | # wrap data in a property, which warns about passing already-serialized JSON | |
802 | _data = None |
|
802 | _data = None | |
803 | def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=None, **kwargs): |
|
803 | def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=None, root='root', **kwargs): | |
804 | """Create a JSON display object given raw data. |
|
804 | """Create a JSON display object given raw data. | |
805 |
|
805 | |||
806 | Parameters |
|
806 | Parameters | |
@@ -817,8 +817,13 b' class JSON(DisplayObject):' | |||||
817 | Metadata to control whether a JSON display component is expanded. |
|
817 | Metadata to control whether a JSON display component is expanded. | |
818 | metadata: dict |
|
818 | metadata: dict | |
819 | Specify extra metadata to attach to the json display object. |
|
819 | Specify extra metadata to attach to the json display object. | |
|
820 | root : str | |||
|
821 | The name of the root element of the JSON tree | |||
820 | """ |
|
822 | """ | |
821 |
self.metadata = { |
|
823 | self.metadata = { | |
|
824 | 'expanded': expanded, | |||
|
825 | 'root': root, | |||
|
826 | } | |||
822 | if metadata: |
|
827 | if metadata: | |
823 | self.metadata.update(metadata) |
|
828 | self.metadata.update(metadata) | |
824 | if kwargs: |
|
829 | if kwargs: | |
@@ -847,18 +852,25 b' class JSON(DisplayObject):' | |||||
847 | def _repr_json_(self): |
|
852 | def _repr_json_(self): | |
848 | return self._data_and_metadata() |
|
853 | return self._data_and_metadata() | |
849 |
|
854 | |||
850 | _css_t = """$("head").append($("<link/>").attr({ |
|
855 | _css_t = """var link = document.createElement("link"); | |
851 |
|
|
856 | link.ref = "stylesheet"; | |
852 |
|
|
857 | link.type = "text/css"; | |
853 |
|
|
858 | link.href = "%s"; | |
854 | })); |
|
859 | document.head.appendChild(link); | |
855 | """ |
|
860 | """ | |
856 |
|
861 | |||
857 |
_lib_t1 = """ |
|
862 | _lib_t1 = """new Promise(function(resolve, reject) { | |
858 | """ |
|
863 | var script = document.createElement("script"); | |
859 | _lib_t2 = """}); |
|
864 | script.onload = resolve; | |
|
865 | script.onerror = reject; | |||
|
866 | script.src = "%s"; | |||
|
867 | document.head.appendChild(script); | |||
|
868 | }).then(() => { | |||
860 | """ |
|
869 | """ | |
861 |
|
870 | |||
|
871 | _lib_t2 = """ | |||
|
872 | });""" | |||
|
873 | ||||
862 | class GeoJSON(JSON): |
|
874 | class GeoJSON(JSON): | |
863 | """GeoJSON expects JSON-able dict |
|
875 | """GeoJSON expects JSON-able dict | |
864 |
|
876 |
@@ -174,7 +174,7 b' class CommandChainDispatcher:' | |||||
174 | def shutdown_hook(self): |
|
174 | def shutdown_hook(self): | |
175 | """ default shutdown hook |
|
175 | """ default shutdown hook | |
176 |
|
176 | |||
177 |
Typically, sh |
|
177 | Typically, shutdown hooks should raise TryNext so all shutdown ops are done | |
178 | """ |
|
178 | """ | |
179 |
|
179 | |||
180 | #print "default shutdown hook ok" # dbg |
|
180 | #print "default shutdown hook ok" # dbg |
@@ -72,7 +72,7 b" ini_spaces_re = re.compile(r'^([ \\t\\r\\f\\v]+)')" | |||||
72 |
|
72 | |||
73 | # regexp to match pure comment lines so we don't accidentally insert 'if 1:' |
|
73 | # regexp to match pure comment lines so we don't accidentally insert 'if 1:' | |
74 | # before pure comments |
|
74 | # before pure comments | |
75 | comment_line_re = re.compile('^\s*\#') |
|
75 | comment_line_re = re.compile(r'^\s*\#') | |
76 |
|
76 | |||
77 |
|
77 | |||
78 | def num_ini_spaces(s): |
|
78 | def num_ini_spaces(s): |
@@ -173,7 +173,7 b' class assemble_python_lines(TokenInputTransformer):' | |||||
173 |
|
173 | |||
174 | @CoroutineInputTransformer.wrap |
|
174 | @CoroutineInputTransformer.wrap | |
175 | def assemble_logical_lines(): |
|
175 | def assemble_logical_lines(): | |
176 | """Join lines following explicit line continuations (\)""" |
|
176 | r"""Join lines following explicit line continuations (\)""" | |
177 | line = '' |
|
177 | line = '' | |
178 | while True: |
|
178 | while True: | |
179 | line = (yield line) |
|
179 | line = (yield line) | |
@@ -363,7 +363,7 b' def cellmagic(end_on_blank_line=False):' | |||||
363 | reset (sent None). |
|
363 | reset (sent None). | |
364 | """ |
|
364 | """ | |
365 | tpl = 'get_ipython().run_cell_magic(%r, %r, %r)' |
|
365 | tpl = 'get_ipython().run_cell_magic(%r, %r, %r)' | |
366 | cellmagic_help_re = re.compile('%%\w+\?') |
|
366 | cellmagic_help_re = re.compile(r'%%\w+\?') | |
367 | line = '' |
|
367 | line = '' | |
368 | while True: |
|
368 | while True: | |
369 | line = (yield line) |
|
369 | line = (yield line) |
@@ -24,7 +24,7 b' from logging import error' | |||||
24 | # Magic implementation classes |
|
24 | # Magic implementation classes | |
25 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
26 |
|
26 | |||
27 | reg = re.compile('^\w+\.\w+$') |
|
27 | reg = re.compile(r'^\w+\.\w+$') | |
28 | @magics_class |
|
28 | @magics_class | |
29 | class ConfigMagics(Magics): |
|
29 | class ConfigMagics(Magics): | |
30 |
|
30 |
@@ -962,11 +962,12 b' python-profiler package from non-free.""")' | |||||
962 | body has access to any variables created in the setup code. |
|
962 | body has access to any variables created in the setup code. | |
963 |
|
963 | |||
964 | Options: |
|
964 | Options: | |
965 |
-n<N>: execute the given statement <N> times in a loop. If |
|
965 | -n<N>: execute the given statement <N> times in a loop. If <N> is not | |
966 | is not given, a fitting value is chosen. |
|
966 | provided, <N> is determined so as to get sufficient accuracy. | |
967 |
|
967 | |||
968 | -r<R>: repeat the loop iteration <R> times and take the best result. |
|
968 | -r<R>: number of repeats <R>, each consisting of <N> loops, and take the | |
969 |
|
|
969 | best result. | |
|
970 | Default: 7 | |||
970 |
|
971 | |||
971 | -t: use time.time to measure the time, which is the default on Unix. |
|
972 | -t: use time.time to measure the time, which is the default on Unix. | |
972 | This function measures wall time. |
|
973 | This function measures wall time. |
@@ -8,7 +8,7 b' import os' | |||||
8 | import sys |
|
8 | import sys | |
9 | import signal |
|
9 | import signal | |
10 | import time |
|
10 | import time | |
11 | from subprocess import Popen, PIPE |
|
11 | from subprocess import Popen, PIPE, CalledProcessError | |
12 | import atexit |
|
12 | import atexit | |
13 |
|
13 | |||
14 | from IPython.core import magic_arguments |
|
14 | from IPython.core import magic_arguments | |
@@ -54,6 +54,12 b' def script_args(f):' | |||||
54 | This is used only when --bg option is given. |
|
54 | This is used only when --bg option is given. | |
55 | """ |
|
55 | """ | |
56 | ), |
|
56 | ), | |
|
57 | magic_arguments.argument( | |||
|
58 | '--raise-error', action="store_true", | |||
|
59 | help="""Whether you should raise an error message in addition to | |||
|
60 | a stream on stderr if you get a nonzero exit code. | |||
|
61 | """ | |||
|
62 | ) | |||
57 | ] |
|
63 | ] | |
58 | for arg in args: |
|
64 | for arg in args: | |
59 | f = arg(f) |
|
65 | f = arg(f) | |
@@ -235,6 +241,8 b' class ScriptMagics(Magics):' | |||||
235 | else: |
|
241 | else: | |
236 | sys.stderr.write(err) |
|
242 | sys.stderr.write(err) | |
237 | sys.stderr.flush() |
|
243 | sys.stderr.flush() | |
|
244 | if args.raise_error and p.returncode!=0: | |||
|
245 | raise CalledProcessError(p.returncode, cell, output=out, stderr=err) | |||
238 |
|
246 | |||
239 | def _run_script(self, p, cell, to_close): |
|
247 | def _run_script(self, p, cell, to_close): | |
240 | """callback for running the script in the background""" |
|
248 | """callback for running the script in the background""" |
@@ -82,7 +82,7 b' class PrefilterManager(Configurable):' | |||||
82 | prefilter consumes lines of input and produces transformed lines of |
|
82 | prefilter consumes lines of input and produces transformed lines of | |
83 | input. |
|
83 | input. | |
84 |
|
84 | |||
85 | The iplementation consists of two phases: |
|
85 | The implementation consists of two phases: | |
86 |
|
86 | |||
87 | 1. Transformers |
|
87 | 1. Transformers | |
88 | 2. Checkers and handlers |
|
88 | 2. Checkers and handlers |
@@ -48,7 +48,7 b' IPython provides a rich toolkit to help you make the most out of using Python' | |||||
48 | interactively. Its main components are: |
|
48 | interactively. Its main components are: | |
49 |
|
49 | |||
50 | * A powerful interactive Python shell |
|
50 | * A powerful interactive Python shell | |
51 | * A `Jupyter <http://jupyter.org/>`_ kernel to work with Python code in Jupyter |
|
51 | * A `Jupyter <https://jupyter.org/>`_ kernel to work with Python code in Jupyter | |
52 | notebooks and other interactive frontends. |
|
52 | notebooks and other interactive frontends. | |
53 |
|
53 | |||
54 | The enhanced interactive Python shells have the following main features: |
|
54 | The enhanced interactive Python shells have the following main features: |
@@ -41,7 +41,7 b' from IPython.utils.encoding import get_stream_enc' | |||||
41 | # ! and !! trigger if they are first char(s) *or* follow an indent |
|
41 | # ! and !! trigger if they are first char(s) *or* follow an indent | |
42 | # ? triggers as first or last char. |
|
42 | # ? triggers as first or last char. | |
43 |
|
43 | |||
44 | line_split = re.compile(""" |
|
44 | line_split = re.compile(r""" | |
45 | ^(\s*) # any leading space |
|
45 | ^(\s*) # any leading space | |
46 | ([,;/%]|!!?|\?\??)? # escape character or characters |
|
46 | ([,;/%]|!!?|\?\??)? # escape character or characters | |
47 | \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading % |
|
47 | \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading % | |
@@ -68,7 +68,7 b' def split_user_input(line, pattern=None):' | |||||
68 | except ValueError: |
|
68 | except ValueError: | |
69 | # print "split failed for line '%s'" % line |
|
69 | # print "split failed for line '%s'" % line | |
70 | ifun, the_rest = line, u'' |
|
70 | ifun, the_rest = line, u'' | |
71 | pre = re.match('^(\s*)(.*)',line).groups()[0] |
|
71 | pre = re.match(r'^(\s*)(.*)',line).groups()[0] | |
72 | esc = "" |
|
72 | esc = "" | |
73 | else: |
|
73 | else: | |
74 | pre, esc, ifun, the_rest = match.groups() |
|
74 | pre, esc, ifun, the_rest = match.groups() |
@@ -16,7 +16,7 b' from os.path import join' | |||||
16 |
|
16 | |||
17 | import nose.tools as nt |
|
17 | import nose.tools as nt | |
18 |
|
18 | |||
19 | from IPython.core.completerlib import magic_run_completer, module_completion |
|
19 | from IPython.core.completerlib import magic_run_completer, module_completion, try_import | |
20 | from IPython.utils.tempdir import TemporaryDirectory |
|
20 | from IPython.utils.tempdir import TemporaryDirectory | |
21 | from IPython.testing.decorators import onlyif_unicode_paths |
|
21 | from IPython.testing.decorators import onlyif_unicode_paths | |
22 |
|
22 | |||
@@ -159,3 +159,20 b' def test_bad_module_all():' | |||||
159 | nt.assert_is_instance(r, str) |
|
159 | nt.assert_is_instance(r, str) | |
160 | finally: |
|
160 | finally: | |
161 | sys.path.remove(testsdir) |
|
161 | sys.path.remove(testsdir) | |
|
162 | ||||
|
163 | ||||
|
164 | def test_module_without_init(): | |||
|
165 | """ | |||
|
166 | Test module without __init__.py. | |||
|
167 | ||||
|
168 | https://github.com/ipython/ipython/issues/11226 | |||
|
169 | """ | |||
|
170 | fake_module_name = "foo" | |||
|
171 | with TemporaryDirectory() as tmpdir: | |||
|
172 | sys.path.insert(0, tmpdir) | |||
|
173 | try: | |||
|
174 | os.makedirs(os.path.join(tmpdir, fake_module_name)) | |||
|
175 | s = try_import(mod=fake_module_name) | |||
|
176 | assert s == [] | |||
|
177 | finally: | |||
|
178 | sys.path.remove(tmpdir) |
@@ -213,31 +213,41 b' def test_progress_iter():' | |||||
213 | def test_json(): |
|
213 | def test_json(): | |
214 | d = {'a': 5} |
|
214 | d = {'a': 5} | |
215 | lis = [d] |
|
215 | lis = [d] | |
216 | md = {'expanded': False} |
|
216 | metadata = [ | |
217 | md2 = {'expanded': True} |
|
217 | {'expanded': False, 'root': 'root'}, | |
218 | j = display.JSON(d) |
|
218 | {'expanded': True, 'root': 'root'}, | |
219 | j2 = display.JSON(d, expanded=True) |
|
219 | {'expanded': False, 'root': 'custom'}, | |
220 | nt.assert_equal(j._repr_json_(), (d, md)) |
|
220 | {'expanded': True, 'root': 'custom'}, | |
221 | nt.assert_equal(j2._repr_json_(), (d, md2)) |
|
221 | ] | |
|
222 | json_objs = [ | |||
|
223 | display.JSON(d), | |||
|
224 | display.JSON(d, expanded=True), | |||
|
225 | display.JSON(d, root='custom'), | |||
|
226 | display.JSON(d, expanded=True, root='custom'), | |||
|
227 | ] | |||
|
228 | for j, md in zip(json_objs, metadata): | |||
|
229 | nt.assert_equal(j._repr_json_(), (d, md)) | |||
222 |
|
230 | |||
223 | with warnings.catch_warnings(record=True) as w: |
|
231 | with warnings.catch_warnings(record=True) as w: | |
224 | warnings.simplefilter("always") |
|
232 | warnings.simplefilter("always") | |
225 | j = display.JSON(json.dumps(d)) |
|
233 | j = display.JSON(json.dumps(d)) | |
226 | nt.assert_equal(len(w), 1) |
|
234 | nt.assert_equal(len(w), 1) | |
227 | nt.assert_equal(j._repr_json_(), (d, md)) |
|
235 | nt.assert_equal(j._repr_json_(), (d, metadata[0])) | |
228 | nt.assert_equal(j2._repr_json_(), (d, md2)) |
|
236 | ||
229 |
|
237 | json_objs = [ | ||
230 |
|
|
238 | display.JSON(lis), | |
231 |
|
|
239 | display.JSON(lis, expanded=True), | |
232 | nt.assert_equal(j._repr_json_(), (lis, md)) |
|
240 | display.JSON(lis, root='custom'), | |
233 | nt.assert_equal(j2._repr_json_(), (lis, md2)) |
|
241 | display.JSON(lis, expanded=True, root='custom'), | |
|
242 | ] | |||
|
243 | for j, md in zip(json_objs, metadata): | |||
|
244 | nt.assert_equal(j._repr_json_(), (lis, md)) | |||
234 |
|
245 | |||
235 | with warnings.catch_warnings(record=True) as w: |
|
246 | with warnings.catch_warnings(record=True) as w: | |
236 | warnings.simplefilter("always") |
|
247 | warnings.simplefilter("always") | |
237 | j = display.JSON(json.dumps(lis)) |
|
248 | j = display.JSON(json.dumps(lis)) | |
238 | nt.assert_equal(len(w), 1) |
|
249 | nt.assert_equal(len(w), 1) | |
239 | nt.assert_equal(j._repr_json_(), (lis, md)) |
|
250 | nt.assert_equal(j._repr_json_(), (lis, metadata[0])) | |
240 | nt.assert_equal(j2._repr_json_(), (lis, md2)) |
|
|||
241 |
|
251 | |||
242 | def test_video_embedding(): |
|
252 | def test_video_embedding(): | |
243 | """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" |
|
253 | """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" |
@@ -546,7 +546,8 b' class ExitCodeChecks(tt.TempFileMixin):' | |||||
546 | else: |
|
546 | else: | |
547 | del os.environ['SHELL'] |
|
547 | del os.environ['SHELL'] | |
548 |
|
548 | |||
549 | class TestSystemRaw(unittest.TestCase, ExitCodeChecks): |
|
549 | ||
|
550 | class TestSystemRaw(ExitCodeChecks, unittest.TestCase): | |||
550 | system = ip.system_raw |
|
551 | system = ip.system_raw | |
551 |
|
552 | |||
552 | @onlyif_unicode_paths |
|
553 | @onlyif_unicode_paths | |
@@ -567,7 +568,7 b' class TestSystemRaw(unittest.TestCase, ExitCodeChecks):' | |||||
567 | self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT) |
|
568 | self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT) | |
568 |
|
569 | |||
569 | # TODO: Exit codes are currently ignored on Windows. |
|
570 | # TODO: Exit codes are currently ignored on Windows. | |
570 |
class TestSystemPipedExitCode(unittest.TestCase |
|
571 | class TestSystemPipedExitCode(ExitCodeChecks, unittest.TestCase): | |
571 | system = ip.system_piped |
|
572 | system = ip.system_piped | |
572 |
|
573 | |||
573 | @skip_win32 |
|
574 | @skip_win32 | |
@@ -582,7 +583,7 b' class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):' | |||||
582 | def test_exit_code_signal(self): |
|
583 | def test_exit_code_signal(self): | |
583 | ExitCodeChecks.test_exit_code_signal(self) |
|
584 | ExitCodeChecks.test_exit_code_signal(self) | |
584 |
|
585 | |||
585 |
class TestModules(unittest.TestCase |
|
586 | class TestModules(tt.TempFileMixin, unittest.TestCase): | |
586 | def test_extraneous_loads(self): |
|
587 | def test_extraneous_loads(self): | |
587 | """Test we're not loading modules on startup that we shouldn't. |
|
588 | """Test we're not loading modules on startup that we shouldn't. | |
588 | """ |
|
589 | """ |
@@ -24,7 +24,7 b" sqlite_err_maybe = dec.module_not_available('sqlite3')" | |||||
24 | SQLITE_NOT_AVAILABLE_ERROR = ('WARNING: IPython History requires SQLite,' |
|
24 | SQLITE_NOT_AVAILABLE_ERROR = ('WARNING: IPython History requires SQLite,' | |
25 | ' your history will not be saved\n') |
|
25 | ' your history will not be saved\n') | |
26 |
|
26 | |||
27 |
class TestFileToRun(unittest.TestCase |
|
27 | class TestFileToRun(tt.TempFileMixin, unittest.TestCase): | |
28 | """Test the behavior of the file_to_run parameter.""" |
|
28 | """Test the behavior of the file_to_run parameter.""" | |
29 |
|
29 | |||
30 | def test_py_script_file_attribute(self): |
|
30 | def test_py_script_file_attribute(self): |
@@ -60,7 +60,7 b' Usage' | |||||
60 | environment variable with this name and setting it to the desired path. |
|
60 | environment variable with this name and setting it to the desired path. | |
61 |
|
61 | |||
62 | For more information, see the manual available in HTML and PDF in your |
|
62 | For more information, see the manual available in HTML and PDF in your | |
63 | installation, or online at http://ipython.org/documentation.html. |
|
63 | installation, or online at https://ipython.org/documentation.html. | |
64 | """ |
|
64 | """ | |
65 |
|
65 | |||
66 | interactive_usage = """ |
|
66 | interactive_usage = """ |
@@ -85,12 +85,12 b' import re' | |||||
85 | import sys |
|
85 | import sys | |
86 | import types |
|
86 | import types | |
87 | from collections import deque |
|
87 | from collections import deque | |
|
88 | from inspect import signature | |||
88 | from io import StringIO |
|
89 | from io import StringIO | |
89 | from warnings import warn |
|
90 | from warnings import warn | |
90 |
|
91 | |||
91 | from IPython.utils.decorators import undoc |
|
92 | from IPython.utils.decorators import undoc | |
92 | from IPython.utils.py3compat import PYPY |
|
93 | from IPython.utils.py3compat import PYPY | |
93 | from IPython.utils.signatures import signature |
|
|||
94 |
|
94 | |||
95 | __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter', |
|
95 | __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter', | |
96 | 'for_type', 'for_type_by_name'] |
|
96 | 'for_type', 'for_type_by_name'] | |
@@ -104,7 +104,7 b" _re_pattern_type = type(re.compile(''))" | |||||
104 |
|
104 | |||
105 | def _safe_getattr(obj, attr, default=None): |
|
105 | def _safe_getattr(obj, attr, default=None): | |
106 | """Safe version of getattr. |
|
106 | """Safe version of getattr. | |
107 |
|
107 | |||
108 | Same as getattr, but will return ``default`` on any Exception, |
|
108 | Same as getattr, but will return ``default`` on any Exception, | |
109 | rather than raising. |
|
109 | rather than raising. | |
110 | """ |
|
110 | """ | |
@@ -246,7 +246,7 b' class PrettyPrinter(_PrettyPrinterBase):' | |||||
246 | self.buffer.append(Breakable(sep, width, self)) |
|
246 | self.buffer.append(Breakable(sep, width, self)) | |
247 | self.buffer_width += width |
|
247 | self.buffer_width += width | |
248 | self._break_outer_groups() |
|
248 | self._break_outer_groups() | |
249 |
|
249 | |||
250 | def break_(self): |
|
250 | def break_(self): | |
251 | """ |
|
251 | """ | |
252 | Explicitly insert a newline into the output, maintaining correct indentation. |
|
252 | Explicitly insert a newline into the output, maintaining correct indentation. | |
@@ -256,7 +256,7 b' class PrettyPrinter(_PrettyPrinterBase):' | |||||
256 | self.output.write(' ' * self.indentation) |
|
256 | self.output.write(' ' * self.indentation) | |
257 | self.output_width = self.indentation |
|
257 | self.output_width = self.indentation | |
258 | self.buffer_width = 0 |
|
258 | self.buffer_width = 0 | |
259 |
|
259 | |||
260 |
|
260 | |||
261 | def begin_group(self, indent=0, open=''): |
|
261 | def begin_group(self, indent=0, open=''): | |
262 | """ |
|
262 | """ | |
@@ -282,7 +282,7 b' class PrettyPrinter(_PrettyPrinterBase):' | |||||
282 | self.group_stack.append(group) |
|
282 | self.group_stack.append(group) | |
283 | self.group_queue.enq(group) |
|
283 | self.group_queue.enq(group) | |
284 | self.indentation += indent |
|
284 | self.indentation += indent | |
285 |
|
285 | |||
286 | def _enumerate(self, seq): |
|
286 | def _enumerate(self, seq): | |
287 | """like enumerate, but with an upper limit on the number of items""" |
|
287 | """like enumerate, but with an upper limit on the number of items""" | |
288 | for idx, x in enumerate(seq): |
|
288 | for idx, x in enumerate(seq): | |
@@ -292,7 +292,7 b' class PrettyPrinter(_PrettyPrinterBase):' | |||||
292 | self.text('...') |
|
292 | self.text('...') | |
293 | return |
|
293 | return | |
294 | yield idx, x |
|
294 | yield idx, x | |
295 |
|
295 | |||
296 | def end_group(self, dedent=0, close=''): |
|
296 | def end_group(self, dedent=0, close=''): | |
297 | """End a group. See `begin_group` for more details.""" |
|
297 | """End a group. See `begin_group` for more details.""" | |
298 | self.indentation -= dedent |
|
298 | self.indentation -= dedent | |
@@ -765,7 +765,7 b' if _env_type is not dict:' | |||||
765 |
|
765 | |||
766 | try: |
|
766 | try: | |
767 | # In PyPy, types.DictProxyType is dict, setting the dictproxy printer |
|
767 | # In PyPy, types.DictProxyType is dict, setting the dictproxy printer | |
768 |
# using dict.setdefault avoids overwrit |
|
768 | # using dict.setdefault avoids overwriting the dict printer | |
769 | _type_pprinters.setdefault(types.DictProxyType, |
|
769 | _type_pprinters.setdefault(types.DictProxyType, | |
770 | _dict_pprinter_factory('dict_proxy({', '})')) |
|
770 | _dict_pprinter_factory('dict_proxy({', '})')) | |
771 | _type_pprinters[types.ClassType] = _type_pprint |
|
771 | _type_pprinters[types.ClassType] = _type_pprint |
@@ -19,9 +19,9 b' def doctest_run():' | |||||
19 | In [13]: run simplevars.py |
|
19 | In [13]: run simplevars.py | |
20 | x is: 1 |
|
20 | x is: 1 | |
21 | """ |
|
21 | """ | |
22 |
|
22 | |||
23 | def doctest_runvars(): |
|
23 | def doctest_runvars(): | |
24 | """Test that variables defined in scripts get loaded correcly via %run. |
|
24 | """Test that variables defined in scripts get loaded correclty via %run. | |
25 |
|
25 | |||
26 | In [13]: run simplevars.py |
|
26 | In [13]: run simplevars.py | |
27 | x is: 1 |
|
27 | x is: 1 |
@@ -49,7 +49,7 b' def extract_vars(*names,**kw):' | |||||
49 | """ |
|
49 | """ | |
50 |
|
50 | |||
51 | depth = kw.get('depth',0) |
|
51 | depth = kw.get('depth',0) | |
52 |
|
52 | |||
53 | callerNS = sys._getframe(depth+1).f_locals |
|
53 | callerNS = sys._getframe(depth+1).f_locals | |
54 | return dict((k,callerNS[k]) for k in names) |
|
54 | return dict((k,callerNS[k]) for k in names) | |
55 |
|
55 | |||
@@ -58,7 +58,7 b' def extract_vars_above(*names):' | |||||
58 | """Extract a set of variables by name from another frame. |
|
58 | """Extract a set of variables by name from another frame. | |
59 |
|
59 | |||
60 | Similar to extractVars(), but with a specified depth of 1, so that names |
|
60 | Similar to extractVars(), but with a specified depth of 1, so that names | |
61 |
are ex |
|
61 | are extracted exactly from above the caller. | |
62 |
|
62 | |||
63 | This is simply a convenience function so that the very common case (for us) |
|
63 | This is simply a convenience function so that the very common case (for us) | |
64 | of skipping exactly 1 frame doesn't have to construct a special dict for |
|
64 | of skipping exactly 1 frame doesn't have to construct a special dict for | |
@@ -93,4 +93,3 b' def extract_module_locals(depth=0):' | |||||
93 | global_ns = f.f_globals |
|
93 | global_ns = f.f_globals | |
94 | module = sys.modules[global_ns['__name__']] |
|
94 | module = sys.modules[global_ns['__name__']] | |
95 | return (module, f.f_locals) |
|
95 | return (module, f.f_locals) | |
96 |
|
@@ -2,14 +2,7 b'' | |||||
2 |
|
2 | |||
3 | Utility functions for finding modules on sys.path. |
|
3 | Utility functions for finding modules on sys.path. | |
4 |
|
4 | |||
5 | `find_mod` finds named module on sys.path. |
|
5 | `find_module` returns a path to module or None, given certain conditions. | |
6 |
|
||||
7 | `get_init` helper function that finds __init__ file in a directory. |
|
|||
8 |
|
||||
9 | `find_module` variant of imp.find_module in std_lib that only returns |
|
|||
10 | path to module and not an open file object as well. |
|
|||
11 |
|
||||
12 |
|
||||
13 |
|
6 | |||
14 | """ |
|
7 | """ | |
15 | #----------------------------------------------------------------------------- |
|
8 | #----------------------------------------------------------------------------- | |
@@ -25,7 +18,7 b' path to module and not an open file object as well.' | |||||
25 | #----------------------------------------------------------------------------- |
|
18 | #----------------------------------------------------------------------------- | |
26 |
|
19 | |||
27 | # Stdlib imports |
|
20 | # Stdlib imports | |
28 | import imp |
|
21 | import importlib | |
29 | import os |
|
22 | import os | |
30 |
|
23 | |||
31 | # Third-party imports |
|
24 | # Third-party imports | |
@@ -44,81 +37,34 b' import os' | |||||
44 | #----------------------------------------------------------------------------- |
|
37 | #----------------------------------------------------------------------------- | |
45 | # Classes and functions |
|
38 | # Classes and functions | |
46 | #----------------------------------------------------------------------------- |
|
39 | #----------------------------------------------------------------------------- | |
47 | def find_module(name, path=None): |
|
|||
48 | """imp.find_module variant that only return path of module. |
|
|||
49 |
|
||||
50 | The `imp.find_module` returns a filehandle that we are not interested in. |
|
|||
51 | Also we ignore any bytecode files that `imp.find_module` finds. |
|
|||
52 |
|
||||
53 | Parameters |
|
|||
54 | ---------- |
|
|||
55 | name : str |
|
|||
56 | name of module to locate |
|
|||
57 | path : list of str |
|
|||
58 | list of paths to search for `name`. If path=None then search sys.path |
|
|||
59 |
|
40 | |||
60 | Returns |
|
41 | def find_mod(module_name): | |
61 | ------- |
|
|||
62 | filename : str |
|
|||
63 | Return full path of module or None if module is missing or does not have |
|
|||
64 | .py or .pyw extension |
|
|||
65 | """ |
|
|||
66 | if name is None: |
|
|||
67 | return None |
|
|||
68 | try: |
|
|||
69 | file, filename, _ = imp.find_module(name, path) |
|
|||
70 | except ImportError: |
|
|||
71 | return None |
|
|||
72 | if file is None: |
|
|||
73 | return filename |
|
|||
74 | else: |
|
|||
75 | file.close() |
|
|||
76 | if os.path.splitext(filename)[1] in [".py", ".pyc"]: |
|
|||
77 | return filename |
|
|||
78 | else: |
|
|||
79 | return None |
|
|||
80 |
|
||||
81 | def get_init(dirname): |
|
|||
82 | """Get __init__ file path for module directory |
|
|||
83 |
|
||||
84 | Parameters |
|
|||
85 | ---------- |
|
|||
86 | dirname : str |
|
|||
87 | Find the __init__ file in directory `dirname` |
|
|||
88 |
|
||||
89 | Returns |
|
|||
90 | ------- |
|
|||
91 | init_path : str |
|
|||
92 | Path to __init__ file |
|
|||
93 |
|
|
42 | """ | |
94 | fbase = os.path.join(dirname, "__init__") |
|
43 | Find module `module_name` on sys.path, and return the path to module `module_name`. | |
95 | for ext in [".py", ".pyw"]: |
|
|||
96 | fname = fbase + ext |
|
|||
97 | if os.path.isfile(fname): |
|
|||
98 | return fname |
|
|||
99 |
|
|
44 | ||
|
45 | - If `module_name` refers to a module directory, then return path to __init__ file. | |||
|
46 | - If `module_name` is a directory without an __init__file, return None. | |||
|
47 | - If module is missing or does not have a `.py` or `.pyw` extension, return None. | |||
|
48 | - Note that we are not interested in running bytecode. | |||
|
49 | - Otherwise, return the fill path of the module. | |||
100 |
|
|
50 | ||
101 | def find_mod(module_name): |
|
|||
102 | """Find module `module_name` on sys.path |
|
|||
103 |
|
||||
104 | Return the path to module `module_name`. If `module_name` refers to |
|
|||
105 | a module directory then return path to __init__ file. Return full |
|
|||
106 | path of module or None if module is missing or does not have .py or .pyw |
|
|||
107 | extension. We are not interested in running bytecode. |
|
|||
108 |
|
||||
109 | Parameters |
|
51 | Parameters | |
110 | ---------- |
|
52 | ---------- | |
111 | module_name : str |
|
53 | module_name : str | |
112 |
|
54 | |||
113 | Returns |
|
55 | Returns | |
114 | ------- |
|
56 | ------- | |
115 | modulepath : str |
|
57 | module_path : str | |
116 | Path to module `module_name`. |
|
58 | Path to module `module_name`, its __init__.py, or None, | |
|
59 | depending on above conditions. | |||
117 | """ |
|
60 | """ | |
118 | parts = module_name.split(".") |
|
61 | loader = importlib.util.find_spec(module_name) | |
119 | basepath = find_module(parts[0]) |
|
62 | module_path = loader.origin | |
120 | for submodname in parts[1:]: |
|
63 | if module_path is None: | |
121 | basepath = find_module(submodname, [basepath]) |
|
64 | return None | |
122 | if basepath and os.path.isdir(basepath): |
|
65 | else: | |
123 | basepath = get_init(basepath) |
|
66 | split_path = module_path.split(".") | |
124 | return basepath |
|
67 | if split_path[1] in ["py", "pyw"]: | |
|
68 | return module_path | |||
|
69 | else: | |||
|
70 | return None |
@@ -202,7 +202,7 b' def get_home_dir(require_writable=False):' | |||||
202 | import _winreg as wreg # Py 2 |
|
202 | import _winreg as wreg # Py 2 | |
203 | key = wreg.OpenKey( |
|
203 | key = wreg.OpenKey( | |
204 | wreg.HKEY_CURRENT_USER, |
|
204 | wreg.HKEY_CURRENT_USER, | |
205 | "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" |
|
205 | r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" | |
206 | ) |
|
206 | ) | |
207 | homedir = wreg.QueryValueEx(key,'Personal')[0] |
|
207 | homedir = wreg.QueryValueEx(key,'Personal')[0] | |
208 | key.Close() |
|
208 | key.Close() |
@@ -5,7 +5,8 b' Fallback on backport otherwise.' | |||||
5 | """ |
|
5 | """ | |
6 |
|
6 | |||
7 | import warnings |
|
7 | import warnings | |
8 |
warnings.warn("{} backport for Python 2 is deprecated in IPython 6, which only supports |
|
8 | warnings.warn("{} backport for Python 2 is deprecated in IPython 6, which only supports " | |
|
9 | "Python 3. Import directly from standard library `inspect`".format(__name__), | |||
9 | DeprecationWarning, stacklevel=2) |
|
10 | DeprecationWarning, stacklevel=2) | |
10 |
|
11 | |||
11 | from inspect import BoundArguments, Parameter, Signature, signature |
|
12 | from inspect import BoundArguments, Parameter, Signature, signature |
@@ -66,62 +66,42 b' def teardown():' | |||||
66 | shutil.rmtree(TMP_TEST_DIR) |
|
66 | shutil.rmtree(TMP_TEST_DIR) | |
67 | sys.path = old_syspath |
|
67 | sys.path = old_syspath | |
68 |
|
68 | |||
69 |
|
||||
70 | def test_get_init_1(): |
|
|||
71 | """See if get_init can find __init__.py in this testdir""" |
|
|||
72 | with make_tempfile(join(TMP_TEST_DIR, "__init__.py")): |
|
|||
73 | assert mp.get_init(TMP_TEST_DIR) |
|
|||
74 |
|
||||
75 | def test_get_init_2(): |
|
|||
76 | """See if get_init can find __init__.pyw in this testdir""" |
|
|||
77 | with make_tempfile(join(TMP_TEST_DIR, "__init__.pyw")): |
|
|||
78 | assert mp.get_init(TMP_TEST_DIR) |
|
|||
79 |
|
||||
80 | def test_get_init_3(): |
|
|||
81 | """get_init can't find __init__.pyc in this testdir""" |
|
|||
82 | with make_tempfile(join(TMP_TEST_DIR, "__init__.pyc")): |
|
|||
83 | nt.assert_is_none(mp.get_init(TMP_TEST_DIR)) |
|
|||
84 |
|
||||
85 | def test_get_init_4(): |
|
|||
86 | """get_init can't find __init__ in empty testdir""" |
|
|||
87 | nt.assert_is_none(mp.get_init(TMP_TEST_DIR)) |
|
|||
88 |
|
||||
89 |
|
||||
90 | def test_find_mod_1(): |
|
69 | def test_find_mod_1(): | |
|
70 | """ | |||
|
71 | Search for a directory's file path. | |||
|
72 | Expected output: a path to that directory's __init__.py file. | |||
|
73 | """ | |||
91 | modpath = join(TMP_TEST_DIR, "xmod", "__init__.py") |
|
74 | modpath = join(TMP_TEST_DIR, "xmod", "__init__.py") | |
92 | nt.assert_equal(mp.find_mod("xmod"), modpath) |
|
75 | nt.assert_equal(mp.find_mod("xmod"), modpath) | |
93 |
|
76 | |||
94 | def test_find_mod_2(): |
|
77 | def test_find_mod_2(): | |
|
78 | """ | |||
|
79 | Search for a directory's file path. | |||
|
80 | Expected output: a path to that directory's __init__.py file. | |||
|
81 | TODO: Confirm why this is a duplicate test. | |||
|
82 | """ | |||
95 | modpath = join(TMP_TEST_DIR, "xmod", "__init__.py") |
|
83 | modpath = join(TMP_TEST_DIR, "xmod", "__init__.py") | |
96 | nt.assert_equal(mp.find_mod("xmod"), modpath) |
|
84 | nt.assert_equal(mp.find_mod("xmod"), modpath) | |
97 |
|
85 | |||
98 | def test_find_mod_3(): |
|
86 | def test_find_mod_3(): | |
|
87 | """ | |||
|
88 | Search for a directory + a filename without its .py extension | |||
|
89 | Expected output: full path with .py extension. | |||
|
90 | """ | |||
99 | modpath = join(TMP_TEST_DIR, "xmod", "sub.py") |
|
91 | modpath = join(TMP_TEST_DIR, "xmod", "sub.py") | |
100 | nt.assert_equal(mp.find_mod("xmod.sub"), modpath) |
|
92 | nt.assert_equal(mp.find_mod("xmod.sub"), modpath) | |
101 |
|
93 | |||
102 | def test_find_mod_4(): |
|
94 | def test_find_mod_4(): | |
|
95 | """ | |||
|
96 | Search for a filename without its .py extension | |||
|
97 | Expected output: full path with .py extension | |||
|
98 | """ | |||
103 | modpath = join(TMP_TEST_DIR, "pack.py") |
|
99 | modpath = join(TMP_TEST_DIR, "pack.py") | |
104 | nt.assert_equal(mp.find_mod("pack"), modpath) |
|
100 | nt.assert_equal(mp.find_mod("pack"), modpath) | |
105 |
|
101 | |||
106 | def test_find_mod_5(): |
|
102 | def test_find_mod_5(): | |
107 | modpath = join(TMP_TEST_DIR, "packpyc.pyc") |
|
103 | """ | |
108 | nt.assert_equal(mp.find_mod("packpyc"), modpath) |
|
104 | Search for a filename with a .pyc extension | |
109 |
|
105 | Expected output: TODO: do we exclude or include .pyc files? | ||
110 | def test_find_module_1(): |
|
106 | """ | |
111 | modpath = join(TMP_TEST_DIR, "xmod") |
|
107 | nt.assert_equal(mp.find_mod("packpyc"), None) | |
112 | nt.assert_equal(mp.find_module("xmod"), modpath) |
|
|||
113 |
|
||||
114 | def test_find_module_2(): |
|
|||
115 | """Testing sys.path that is empty""" |
|
|||
116 | nt.assert_is_none(mp.find_module("xmod", [])) |
|
|||
117 |
|
||||
118 | def test_find_module_3(): |
|
|||
119 | """Testing sys.path that is empty""" |
|
|||
120 | nt.assert_is_none(mp.find_module(None, None)) |
|
|||
121 |
|
||||
122 | def test_find_module_4(): |
|
|||
123 | """Testing sys.path that is empty""" |
|
|||
124 | nt.assert_is_none(mp.find_module(None)) |
|
|||
125 |
|
||||
126 | def test_find_module_5(): |
|
|||
127 | nt.assert_is_none(mp.find_module("xmod.nopack")) |
|
@@ -588,7 +588,7 b' class DollarFormatter(FullEvalFormatter):' | |||||
588 | In [4]: f.format('$a or {b}', a=1, b=2) |
|
588 | In [4]: f.format('$a or {b}', a=1, b=2) | |
589 | Out[4]: '1 or 2' |
|
589 | Out[4]: '1 or 2' | |
590 | """ |
|
590 | """ | |
591 | _dollar_pattern_ignore_single_quote = re.compile("(.*?)\$(\$?[\w\.]+)(?=([^']*'[^']*')*[^']*$)") |
|
591 | _dollar_pattern_ignore_single_quote = re.compile(r"(.*?)\$(\$?[\w\.]+)(?=([^']*'[^']*')*[^']*$)") | |
592 | def parse(self, fmt_string): |
|
592 | def parse(self, fmt_string): | |
593 | for literal_txt, field_name, format_spec, conversion \ |
|
593 | for literal_txt, field_name, format_spec, conversion \ | |
594 | in Formatter.parse(self, fmt_string): |
|
594 | in Formatter.parse(self, fmt_string): |
@@ -55,7 +55,7 b' Or see the `development installation docs' | |||||
55 | for the latest revision on read the docs. |
|
55 | for the latest revision on read the docs. | |
56 |
|
56 | |||
57 | Documentation and installation instructions for older version of IPython can be |
|
57 | Documentation and installation instructions for older version of IPython can be | |
58 | found on the `IPython website <http://ipython.org/documentation.html>`_ |
|
58 | found on the `IPython website <https://ipython.org/documentation.html>`_ | |
59 |
|
59 | |||
60 |
|
60 | |||
61 |
|
61 | |||
@@ -87,7 +87,7 b' manager.' | |||||
87 |
|
87 | |||
88 | For more information see one of our blog posts: |
|
88 | For more information see one of our blog posts: | |
89 |
|
89 | |||
90 | http://blog.jupyter.org/2016/07/08/ipython-5-0-released/ |
|
90 | https://blog.jupyter.org/2016/07/08/ipython-5-0-released/ | |
91 |
|
91 | |||
92 | As well as the following Pull-Request for discussion: |
|
92 | As well as the following Pull-Request for discussion: | |
93 |
|
93 |
@@ -34,7 +34,7 b' backport to.' | |||||
34 |
|
34 | |||
35 | .. note:: |
|
35 | .. note:: | |
36 |
|
36 | |||
37 |
The ``@`` and ``[ |
|
37 | The ``@`` and ``[bot]`` when mentioning the bot should be optional and can | |
38 | be omitted. |
|
38 | be omitted. | |
39 |
|
39 | |||
40 | If the pull request cannot be automatically backported, the bot should tell you |
|
40 | If the pull request cannot be automatically backported, the bot should tell you | |
@@ -44,7 +44,7 b' so on the PR and apply a "Need manual backport" tag to the origin PR.' | |||||
44 | Backport with ghpro |
|
44 | Backport with ghpro | |
45 | ------------------- |
|
45 | ------------------- | |
46 |
|
46 | |||
47 | We can also use `ghpro <https://pypi.python.org/pypi/ghpro>` |
|
47 | We can also use `ghpro <https://pypi.python.org/pypi/ghpro>`_ | |
48 | to automatically list and apply the PR on other branches. For example: |
|
48 | to automatically list and apply the PR on other branches. For example: | |
49 |
|
49 | |||
50 | .. code-block:: bash |
|
50 | .. code-block:: bash |
@@ -22,7 +22,7 b' interactively. Its main components are:' | |||||
22 | :align: center |
|
22 | :align: center | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | * A `Jupyter <http://jupyter.org/>`_ kernel to work with Python code in Jupyter |
|
25 | * A `Jupyter <https://jupyter.org/>`_ kernel to work with Python code in Jupyter | |
26 | notebooks and other interactive frontends. |
|
26 | notebooks and other interactive frontends. | |
27 |
|
27 | |||
28 | The enhanced interactive Python shells and kernel have the following main |
|
28 | The enhanced interactive Python shells and kernel have the following main |
@@ -28,7 +28,7 b' Overview' | |||||
28 |
|
28 | |||
29 | This document describes in detail the steps required to install IPython. For a |
|
29 | This document describes in detail the steps required to install IPython. For a | |
30 | few quick ways to get started with package managers or full Python |
|
30 | few quick ways to get started with package managers or full Python | |
31 | distributions, see `the install page <http://ipython.org/install.html>`_ of the |
|
31 | distributions, see `the install page <https://ipython.org/install.html>`_ of the | |
32 | IPython website. |
|
32 | IPython website. | |
33 |
|
33 | |||
34 | Please let us know if you have problems installing IPython or any of its |
|
34 | Please let us know if you have problems installing IPython or any of its |
@@ -27,5 +27,5 b' done some work in the classic Python REPL.' | |||||
27 |
|
27 | |||
28 | .. seealso:: |
|
28 | .. seealso:: | |
29 |
|
29 | |||
30 | `A Qt Console for Jupyter <http://jupyter.org/qtconsole/>`__ |
|
30 | `A Qt Console for Jupyter <https://jupyter.org/qtconsole/>`__ | |
31 | `The Jupyter Notebook <http://jupyter-notebook.readthedocs.io/en/latest/>`__ |
|
31 | `The Jupyter Notebook <http://jupyter-notebook.readthedocs.io/en/latest/>`__ |
@@ -17,11 +17,11 b'' | |||||
17 | NOTE: Some of these were taken from the nipy links compendium. |
|
17 | NOTE: Some of these were taken from the nipy links compendium. | |
18 |
|
18 | |||
19 | .. Main IPython links |
|
19 | .. Main IPython links | |
20 | .. _ipython: http://ipython.org |
|
20 | .. _ipython: https://ipython.org | |
21 | .. _`ipython manual`: http://ipython.org/documentation.html |
|
21 | .. _`ipython manual`: https://ipython.org/documentation.html | |
22 | .. _ipython_github: http://github.com/ipython/ipython/ |
|
22 | .. _ipython_github: http://github.com/ipython/ipython/ | |
23 | .. _ipython_github_repo: http://github.com/ipython/ipython/ |
|
23 | .. _ipython_github_repo: http://github.com/ipython/ipython/ | |
24 | .. _ipython_downloads: http://ipython.org/download.html |
|
24 | .. _ipython_downloads: https://ipython.org/download.html | |
25 | .. _ipython_pypi: http://pypi.python.org/pypi/ipython |
|
25 | .. _ipython_pypi: http://pypi.python.org/pypi/ipython | |
26 | .. _nbviewer: http://nbviewer.ipython.org |
|
26 | .. _nbviewer: http://nbviewer.ipython.org | |
27 |
|
27 |
@@ -218,7 +218,7 b' which will be something like ``--existing kernel-19732.json`` but with' | |||||
218 | different numbers which correspond to the Process ID of the kernel. |
|
218 | different numbers which correspond to the Process ID of the kernel. | |
219 |
|
219 | |||
220 | You can read more about using `jupyter qtconsole |
|
220 | You can read more about using `jupyter qtconsole | |
221 | <http://jupyter.org/qtconsole/>`_, and |
|
221 | <https://jupyter.org/qtconsole/>`_, and | |
222 | `jupyter notebook <http://jupyter-notebook.readthedocs.io/en/latest/>`_. There |
|
222 | `jupyter notebook <http://jupyter-notebook.readthedocs.io/en/latest/>`_. There | |
223 | is also a :ref:`message spec <messaging>` which documents the protocol for |
|
223 | is also a :ref:`message spec <messaging>` which documents the protocol for | |
224 | communication between kernels |
|
224 | communication between kernels |
@@ -1416,7 +1416,7 b' Issues (434):' | |||||
1416 | * :ghissue:`4759`: Application._load_config_files log parameter default fails |
|
1416 | * :ghissue:`4759`: Application._load_config_files log parameter default fails | |
1417 | * :ghissue:`3153`: docs / file menu: explain how to exit the notebook |
|
1417 | * :ghissue:`3153`: docs / file menu: explain how to exit the notebook | |
1418 | * :ghissue:`4791`: Did updates to ipython_directive bork support for cython magic snippets? |
|
1418 | * :ghissue:`4791`: Did updates to ipython_directive bork support for cython magic snippets? | |
1419 | * :ghissue:`4385`: "Part 4 - Markdown Cells.ipynb" nbviewer example seems not well referenced in current online documentation page http://ipython.org/ipython-doc/stable/interactive/notebook.htm |
|
1419 | * :ghissue:`4385`: "Part 4 - Markdown Cells.ipynb" nbviewer example seems not well referenced in current online documentation page https://ipython.org/ipython-doc/stable/interactive/notebook.htm | |
1420 | * :ghissue:`4655`: prefer marked to pandoc for markdown2html |
|
1420 | * :ghissue:`4655`: prefer marked to pandoc for markdown2html | |
1421 | * :ghissue:`3441`: Fix focus related problems in the notebook |
|
1421 | * :ghissue:`3441`: Fix focus related problems in the notebook | |
1422 | * :ghissue:`3402`: Feature Request: Save As (latex, html,..etc) as a menu option in Notebook rather than explicit need to invoke nbconvert |
|
1422 | * :ghissue:`3402`: Feature Request: Save As (latex, html,..etc) as a menu option in Notebook rather than explicit need to invoke nbconvert |
@@ -232,7 +232,7 b' may also offer a slightly more featureful application (with menus and other GUI' | |||||
232 | elements), but we remain committed to always shipping this easy to embed |
|
232 | elements), but we remain committed to always shipping this easy to embed | |
233 | widget. |
|
233 | widget. | |
234 |
|
234 | |||
235 | See the `Jupyter Qt Console site <http://jupyter.org/qtconsole>`_ for a detailed |
|
235 | See the `Jupyter Qt Console site <https://jupyter.org/qtconsole>`_ for a detailed | |
236 | description of the console's features and use. |
|
236 | description of the console's features and use. | |
237 |
|
237 | |||
238 |
|
238 |
@@ -2,6 +2,18 b'' | |||||
2 | 6.x Series |
|
2 | 6.x Series | |
3 | ============ |
|
3 | ============ | |
4 |
|
4 | |||
|
5 | .. _whatsnew650: | |||
|
6 | ||||
|
7 | IPython 6.5.0 | |||
|
8 | ============= | |||
|
9 | ||||
|
10 | Miscellaneous bug fixes and compatibility with Python 3.7. | |||
|
11 | ||||
|
12 | * Autocompletion fix for modules with out ``__init__.py`` :ghpull:`11227` | |||
|
13 | * update the ``%pastebin`` magic to use ``dpaste.com`` instead og GitHub Gist | |||
|
14 | which now requires authentication :ghpull:`11182` | |||
|
15 | * Fix crash with multiprocessing :ghpull:`11185` | |||
|
16 | ||||
5 | .. _whatsnew640: |
|
17 | .. _whatsnew640: | |
6 |
|
18 | |||
7 | IPython 6.4.0 |
|
19 | IPython 6.4.0 |
@@ -3058,7 +3058,7 b'' | |||||
3058 | " <iframe\n", |
|
3058 | " <iframe\n", | |
3059 | " width=\"100%\"\n", |
|
3059 | " width=\"100%\"\n", | |
3060 | " height=\"350\"\n", |
|
3060 | " height=\"350\"\n", | |
3061 | " src=\"http://jupyter.org\"\n", |
|
3061 | " src=\"https://jupyter.org\"\n", | |
3062 | " frameborder=\"0\"\n", |
|
3062 | " frameborder=\"0\"\n", | |
3063 | " allowfullscreen\n", |
|
3063 | " allowfullscreen\n", | |
3064 | " ></iframe>\n", |
|
3064 | " ></iframe>\n", | |
@@ -3075,7 +3075,7 b'' | |||||
3075 | ], |
|
3075 | ], | |
3076 | "source": [ |
|
3076 | "source": [ | |
3077 | "from IPython.display import IFrame\n", |
|
3077 | "from IPython.display import IFrame\n", | |
3078 | "IFrame('http://jupyter.org', width='100%', height=350)" |
|
3078 | "IFrame('https://jupyter.org', width='100%', height=350)" | |
3079 | ] |
|
3079 | ] | |
3080 | }, |
|
3080 | }, | |
3081 | { |
|
3081 | { | |
@@ -3263,7 +3263,7 b'' | |||||
3263 | "* When you open a notebook, rich output is only displayed if it doesn't contain security vulberabilities, ...\n", |
|
3263 | "* When you open a notebook, rich output is only displayed if it doesn't contain security vulberabilities, ...\n", | |
3264 | "* ... or if you have trusted a notebook, all rich output will run upon opening it.\n", |
|
3264 | "* ... or if you have trusted a notebook, all rich output will run upon opening it.\n", | |
3265 | "\n", |
|
3265 | "\n", | |
3266 | "A full description of the IPython security model can be found on [this page](http://ipython.org/ipython-doc/dev/notebook/security.html)." |
|
3266 | "A full description of the IPython security model can be found on [this page](https://ipython.org/ipython-doc/dev/notebook/security.html)." | |
3267 | ] |
|
3267 | ] | |
3268 | }, |
|
3268 | }, | |
3269 | { |
|
3269 | { |
@@ -18,7 +18,7 b'' | |||||
18 | "cell_type": "markdown", |
|
18 | "cell_type": "markdown", | |
19 | "metadata": {}, |
|
19 | "metadata": {}, | |
20 | "source": [ |
|
20 | "source": [ | |
21 | "This directory contains IPython's notebook-based documentation. This augments our [Sphinx-based documentation](http://ipython.org/ipython-doc/stable/index.html) with notebooks that contain interactive tutorials and examples. Over time, more of our documentation will be pulled into this format." |
|
21 | "This directory contains IPython's notebook-based documentation. This augments our [Sphinx-based documentation](https://ipython.org/ipython-doc/stable/index.html) with notebooks that contain interactive tutorials and examples. Over time, more of our documentation will be pulled into this format." | |
22 | ] |
|
22 | ] | |
23 | }, |
|
23 | }, | |
24 | { |
|
24 | { |
@@ -183,7 +183,7 b'' | |||||
183 | " <iframe\n", |
|
183 | " <iframe\n", | |
184 | " width=\"900\"\n", |
|
184 | " width=\"900\"\n", | |
185 | " height=\"400\"\n", |
|
185 | " height=\"400\"\n", | |
186 | " src=\"http://ipython.org\"\n", |
|
186 | " src=\"https://ipython.org\"\n", | |
187 | " frameborder=\"0\"\n", |
|
187 | " frameborder=\"0\"\n", | |
188 | " allowfullscreen\n", |
|
188 | " allowfullscreen\n", | |
189 | " ></iframe>\n", |
|
189 | " ></iframe>\n", | |
@@ -199,7 +199,7 b'' | |||||
199 | } |
|
199 | } | |
200 | ], |
|
200 | ], | |
201 | "source": [ |
|
201 | "source": [ | |
202 | "IFrame(src=\"http://ipython.org\", width=900, height=400)" |
|
202 | "IFrame(src=\"https://ipython.org\", width=900, height=400)" | |
203 | ] |
|
203 | ] | |
204 | }, |
|
204 | }, | |
205 | { |
|
205 | { |
@@ -1993,7 +1993,7 b'' | |||||
1993 | "\n", |
|
1993 | "\n", | |
1994 | "var mdcell = new IPython.MarkdownCell();\n", |
|
1994 | "var mdcell = new IPython.MarkdownCell();\n", | |
1995 | "mdcell.create_element();\n", |
|
1995 | "mdcell.create_element();\n", | |
1996 | "mdcell.set_text('\\n![Alternate Text](http://ipython.org/_static/IPy_header.png)\\n');\n", |
|
1996 | "mdcell.set_text('\\n![Alternate Text](https://ipython.org/_static/IPy_header.png)\\n');\n", | |
1997 | "mdcell.render();\n", |
|
1997 | "mdcell.render();\n", | |
1998 | "$(element).append(mdcell.element)\n", |
|
1998 | "$(element).append(mdcell.element)\n", | |
1999 | ".removeClass()\n", |
|
1999 | ".removeClass()\n", | |
@@ -2022,10 +2022,10 b'' | |||||
2022 | "text/html": [ |
|
2022 | "text/html": [ | |
2023 | "<div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #AAFFAA; width: 100%;'>NBConvert Latex Output</div><pre class='prettyprint lang-tex' style='background: #EEFFEE; border: 1px solid #DDEEDD;'><xmp>\\begin{figure}[htbp]\n", |
|
2023 | "<div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #AAFFAA; width: 100%;'>NBConvert Latex Output</div><pre class='prettyprint lang-tex' style='background: #EEFFEE; border: 1px solid #DDEEDD;'><xmp>\\begin{figure}[htbp]\n", | |
2024 | "\\centering\n", |
|
2024 | "\\centering\n", | |
2025 | "\\includegraphics{http://ipython.org/_static/IPy_header.png}\n", |
|
2025 | "\\includegraphics{https://ipython.org/_static/IPy_header.png}\n", | |
2026 | "\\caption{Alternate Text}\n", |
|
2026 | "\\caption{Alternate Text}\n", | |
2027 | "\\end{figure}</xmp></pre></div><div style='display: inline-block; width: 2%;'></div><div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #FFAAAA; width: 100%;'>NBViewer Output</div><div style='display: inline-block; width: 100%;'><div class=\"figure\">\n", |
|
2027 | "\\end{figure}</xmp></pre></div><div style='display: inline-block; width: 2%;'></div><div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #FFAAAA; width: 100%;'>NBViewer Output</div><div style='display: inline-block; width: 100%;'><div class=\"figure\">\n", | |
2028 | "<img src=\"http://ipython.org/_static/IPy_header.png\" alt=\"Alternate Text\" /><p class=\"caption\">Alternate Text</p>\n", |
|
2028 | "<img src=\"https://ipython.org/_static/IPy_header.png\" alt=\"Alternate Text\" /><p class=\"caption\">Alternate Text</p>\n", | |
2029 | "</div></div></div>" |
|
2029 | "</div></div></div>" | |
2030 | ], |
|
2030 | ], | |
2031 | "text/plain": [ |
|
2031 | "text/plain": [ | |
@@ -2051,7 +2051,7 b'' | |||||
2051 | ], |
|
2051 | ], | |
2052 | "source": [ |
|
2052 | "source": [ | |
2053 | "compare_render(r\"\"\"\n", |
|
2053 | "compare_render(r\"\"\"\n", | |
2054 | "![Alternate Text](http://ipython.org/_static/IPy_header.png)\n", |
|
2054 | "![Alternate Text](https://ipython.org/_static/IPy_header.png)\n", | |
2055 | "\"\"\")" |
|
2055 | "\"\"\")" | |
2056 | ] |
|
2056 | ] | |
2057 | }, |
|
2057 | }, | |
@@ -2075,7 +2075,7 b'' | |||||
2075 | "\n", |
|
2075 | "\n", | |
2076 | "var mdcell = new IPython.MarkdownCell();\n", |
|
2076 | "var mdcell = new IPython.MarkdownCell();\n", | |
2077 | "mdcell.create_element();\n", |
|
2077 | "mdcell.create_element();\n", | |
2078 | "mdcell.set_text('\\n<img src=\"http://ipython.org/_static/IPy_header.png\">\\n');\n", |
|
2078 | "mdcell.set_text('\\n<img src=\"https://ipython.org/_static/IPy_header.png\">\\n');\n", | |
2079 | "mdcell.render();\n", |
|
2079 | "mdcell.render();\n", | |
2080 | "$(element).append(mdcell.element)\n", |
|
2080 | "$(element).append(mdcell.element)\n", | |
2081 | ".removeClass()\n", |
|
2081 | ".removeClass()\n", | |
@@ -2102,7 +2102,7 b'' | |||||
2102 | { |
|
2102 | { | |
2103 | "data": { |
|
2103 | "data": { | |
2104 | "text/html": [ |
|
2104 | "text/html": [ | |
2105 | "<div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #AAFFAA; width: 100%;'>NBConvert Latex Output</div><pre class='prettyprint lang-tex' style='background: #EEFFEE; border: 1px solid #DDEEDD;'><xmp></xmp></pre></div><div style='display: inline-block; width: 2%;'></div><div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #FFAAAA; width: 100%;'>NBViewer Output</div><div style='display: inline-block; width: 100%;'><p><img src=\"http://ipython.org/_static/IPy_header.png\"></p></div></div>" |
|
2105 | "<div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #AAFFAA; width: 100%;'>NBConvert Latex Output</div><pre class='prettyprint lang-tex' style='background: #EEFFEE; border: 1px solid #DDEEDD;'><xmp></xmp></pre></div><div style='display: inline-block; width: 2%;'></div><div style='display: inline-block; width: 30%; vertical-align: top;'><div style='background: #FFAAAA; width: 100%;'>NBViewer Output</div><div style='display: inline-block; width: 100%;'><p><img src=\"https://ipython.org/_static/IPy_header.png\"></p></div></div>" | |
2106 | ], |
|
2106 | ], | |
2107 | "text/plain": [ |
|
2107 | "text/plain": [ | |
2108 | "<IPython.core.display.HTML at 0x21ac450>" |
|
2108 | "<IPython.core.display.HTML at 0x21ac450>" | |
@@ -2127,7 +2127,7 b'' | |||||
2127 | ], |
|
2127 | ], | |
2128 | "source": [ |
|
2128 | "source": [ | |
2129 | "compare_render(r\"\"\"\n", |
|
2129 | "compare_render(r\"\"\"\n", | |
2130 | "<img src=\"http://ipython.org/_static/IPy_header.png\">\n", |
|
2130 | "<img src=\"https://ipython.org/_static/IPy_header.png\">\n", | |
2131 | "\"\"\")" |
|
2131 | "\"\"\")" | |
2132 | ] |
|
2132 | ] | |
2133 | }, |
|
2133 | }, |
General Comments 0
You need to be logged in to leave comments.
Login now