aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/ipython/py3/IPython/utils
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/python/ipython/py3/IPython/utils
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/python/ipython/py3/IPython/utils')
-rw-r--r--contrib/python/ipython/py3/IPython/utils/PyColorize.py662
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_process_cli.py156
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_process_common.py424
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_process_posix.py450
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_process_win32.py410
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_process_win32_controller.py1146
-rw-r--r--contrib/python/ipython/py3/IPython/utils/_sysinfo.py4
-rw-r--r--contrib/python/ipython/py3/IPython/utils/capture.py340
-rw-r--r--contrib/python/ipython/py3/IPython/utils/colorable.py50
-rw-r--r--contrib/python/ipython/py3/IPython/utils/coloransi.py374
-rw-r--r--contrib/python/ipython/py3/IPython/utils/contexts.py148
-rw-r--r--contrib/python/ipython/py3/IPython/utils/daemonize.py8
-rw-r--r--contrib/python/ipython/py3/IPython/utils/data.py60
-rw-r--r--contrib/python/ipython/py3/IPython/utils/decorators.py116
-rw-r--r--contrib/python/ipython/py3/IPython/utils/dir2.py168
-rw-r--r--contrib/python/ipython/py3/IPython/utils/encoding.py142
-rw-r--r--contrib/python/ipython/py3/IPython/utils/eventful.py12
-rw-r--r--contrib/python/ipython/py3/IPython/utils/frame.py188
-rw-r--r--contrib/python/ipython/py3/IPython/utils/generics.py60
-rw-r--r--contrib/python/ipython/py3/IPython/utils/importstring.py78
-rw-r--r--contrib/python/ipython/py3/IPython/utils/io.py496
-rw-r--r--contrib/python/ipython/py3/IPython/utils/ipstruct.py782
-rw-r--r--contrib/python/ipython/py3/IPython/utils/jsonutil.py10
-rw-r--r--contrib/python/ipython/py3/IPython/utils/localinterfaces.py10
-rw-r--r--contrib/python/ipython/py3/IPython/utils/log.py12
-rw-r--r--contrib/python/ipython/py3/IPython/utils/module_paths.py140
-rw-r--r--contrib/python/ipython/py3/IPython/utils/openpy.py206
-rw-r--r--contrib/python/ipython/py3/IPython/utils/path.py872
-rw-r--r--contrib/python/ipython/py3/IPython/utils/pickleutil.py10
-rw-r--r--contrib/python/ipython/py3/IPython/utils/process.py138
-rw-r--r--contrib/python/ipython/py3/IPython/utils/py3compat.py382
-rw-r--r--contrib/python/ipython/py3/IPython/utils/sentinel.py34
-rw-r--r--contrib/python/ipython/py3/IPython/utils/shimmodule.py188
-rw-r--r--contrib/python/ipython/py3/IPython/utils/signatures.py24
-rw-r--r--contrib/python/ipython/py3/IPython/utils/strdispatch.py136
-rw-r--r--contrib/python/ipython/py3/IPython/utils/sysinfo.py332
-rw-r--r--contrib/python/ipython/py3/IPython/utils/syspathcontext.py124
-rw-r--r--contrib/python/ipython/py3/IPython/utils/tempdir.py114
-rw-r--r--contrib/python/ipython/py3/IPython/utils/terminal.py258
-rw-r--r--contrib/python/ipython/py3/IPython/utils/text.py1526
-rw-r--r--contrib/python/ipython/py3/IPython/utils/timing.py244
-rw-r--r--contrib/python/ipython/py3/IPython/utils/tokenutil.py260
-rw-r--r--contrib/python/ipython/py3/IPython/utils/traitlets.py12
-rw-r--r--contrib/python/ipython/py3/IPython/utils/tz.py92
-rw-r--r--contrib/python/ipython/py3/IPython/utils/ulinecache.py42
-rw-r--r--contrib/python/ipython/py3/IPython/utils/version.py72
-rw-r--r--contrib/python/ipython/py3/IPython/utils/wildcard.py222
47 files changed, 5867 insertions, 5867 deletions
diff --git a/contrib/python/ipython/py3/IPython/utils/PyColorize.py b/contrib/python/ipython/py3/IPython/utils/PyColorize.py
index 3fd5e77fb2..86bb9af4c1 100644
--- a/contrib/python/ipython/py3/IPython/utils/PyColorize.py
+++ b/contrib/python/ipython/py3/IPython/utils/PyColorize.py
@@ -1,331 +1,331 @@
-# -*- coding: utf-8 -*-
-"""
-Class and program to colorize python source code for ANSI terminals.
-
-Based on an HTML code highlighter by Jurgen Hermann found at:
-http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
-
-Modifications by Fernando Perez (fperez@colorado.edu).
-
-Information on the original HTML highlighter follows:
-
-MoinMoin - Python Source Parser
-
-Title: Colorize Python source using the built-in tokenizer
-
-Submitter: Jurgen Hermann
-Last Updated:2001/04/06
-
-Version no:1.2
-
-Description:
-
-This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
-Python source code to HTML markup, rendering comments, keywords,
-operators, numeric and string literals in different colors.
-
-It shows how to use the built-in keyword, token and tokenize modules to
-scan Python source code and re-emit it with no changes to its original
-formatting (which is the hard part).
-"""
-
-__all__ = ['ANSICodeColors', 'Parser']
-
-_scheme_default = 'Linux'
-
-
-# Imports
-import keyword
-import os
-import sys
-import token
-import tokenize
-
-generate_tokens = tokenize.generate_tokens
-
-from IPython.utils.coloransi import TermColors, InputTermColors,ColorScheme, ColorSchemeTable
-from .colorable import Colorable
-from io import StringIO
-
-#############################################################################
-### Python Source Parser (does Highlighting)
-#############################################################################
-
-_KEYWORD = token.NT_OFFSET + 1
-_TEXT = token.NT_OFFSET + 2
-
-#****************************************************************************
-# Builtin color schemes
-
-Colors = TermColors # just a shorthand
-
-# Build a few color schemes
-NoColor = ColorScheme(
- 'NoColor',{
- 'header' : Colors.NoColor,
- token.NUMBER : Colors.NoColor,
- token.OP : Colors.NoColor,
- token.STRING : Colors.NoColor,
- tokenize.COMMENT : Colors.NoColor,
- token.NAME : Colors.NoColor,
- token.ERRORTOKEN : Colors.NoColor,
-
- _KEYWORD : Colors.NoColor,
- _TEXT : Colors.NoColor,
-
- 'in_prompt' : InputTermColors.NoColor, # Input prompt
- 'in_number' : InputTermColors.NoColor, # Input prompt number
- 'in_prompt2' : InputTermColors.NoColor, # Continuation prompt
- 'in_normal' : InputTermColors.NoColor, # color off (usu. Colors.Normal)
-
- 'out_prompt' : Colors.NoColor, # Output prompt
- 'out_number' : Colors.NoColor, # Output prompt number
-
- 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
- } )
-
-LinuxColors = ColorScheme(
- 'Linux',{
- 'header' : Colors.LightRed,
- token.NUMBER : Colors.LightCyan,
- token.OP : Colors.Yellow,
- token.STRING : Colors.LightBlue,
- tokenize.COMMENT : Colors.LightRed,
- token.NAME : Colors.Normal,
- token.ERRORTOKEN : Colors.Red,
-
- _KEYWORD : Colors.LightGreen,
- _TEXT : Colors.Yellow,
-
- 'in_prompt' : InputTermColors.Green,
- 'in_number' : InputTermColors.LightGreen,
- 'in_prompt2' : InputTermColors.Green,
- 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
-
- 'out_prompt' : Colors.Red,
- 'out_number' : Colors.LightRed,
-
- 'normal' : Colors.Normal # color off (usu. Colors.Normal)
- } )
-
-NeutralColors = ColorScheme(
- 'Neutral',{
- 'header' : Colors.Red,
- token.NUMBER : Colors.Cyan,
- token.OP : Colors.Blue,
- token.STRING : Colors.Blue,
- tokenize.COMMENT : Colors.Red,
- token.NAME : Colors.Normal,
- token.ERRORTOKEN : Colors.Red,
-
- _KEYWORD : Colors.Green,
- _TEXT : Colors.Blue,
-
- 'in_prompt' : InputTermColors.Blue,
- 'in_number' : InputTermColors.LightBlue,
- 'in_prompt2' : InputTermColors.Blue,
- 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
-
- 'out_prompt' : Colors.Red,
- 'out_number' : Colors.LightRed,
-
- 'normal' : Colors.Normal # color off (usu. Colors.Normal)
- } )
-
-# Hack: the 'neutral' colours are not very visible on a dark background on
-# Windows. Since Windows command prompts have a dark background by default, and
-# relatively few users are likely to alter that, we will use the 'Linux' colours,
-# designed for a dark background, as the default on Windows. Changing it here
-# avoids affecting the prompt colours rendered by prompt_toolkit, where the
-# neutral defaults do work OK.
-
-if os.name == 'nt':
- NeutralColors = LinuxColors.copy(name='Neutral')
-
-LightBGColors = ColorScheme(
- 'LightBG',{
- 'header' : Colors.Red,
- token.NUMBER : Colors.Cyan,
- token.OP : Colors.Blue,
- token.STRING : Colors.Blue,
- tokenize.COMMENT : Colors.Red,
- token.NAME : Colors.Normal,
- token.ERRORTOKEN : Colors.Red,
-
-
- _KEYWORD : Colors.Green,
- _TEXT : Colors.Blue,
-
- 'in_prompt' : InputTermColors.Blue,
- 'in_number' : InputTermColors.LightBlue,
- 'in_prompt2' : InputTermColors.Blue,
- 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
-
- 'out_prompt' : Colors.Red,
- 'out_number' : Colors.LightRed,
-
- 'normal' : Colors.Normal # color off (usu. Colors.Normal)
- } )
-
-# Build table of color schemes (needed by the parser)
-ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors, NeutralColors],
- _scheme_default)
-
-Undefined = object()
-
-class Parser(Colorable):
- """ Format colored Python source.
- """
-
- def __init__(self, color_table=None, out = sys.stdout, parent=None, style=None):
- """ Create a parser with a specified color table and output channel.
-
- Call format() to process code.
- """
-
- super(Parser, self).__init__(parent=parent)
-
- self.color_table = color_table if color_table else ANSICodeColors
- self.out = out
- self.pos = None
- self.lines = None
- self.raw = None
- if not style:
- self.style = self.default_style
- else:
- self.style = style
-
-
- def format(self, raw, out=None, scheme=Undefined):
- import warnings
- if scheme is not Undefined:
- warnings.warn('The `scheme` argument of IPython.utils.PyColorize:Parser.format is deprecated since IPython 6.0.'
- 'It will have no effect. Set the parser `style` directly.',
- stacklevel=2)
- return self.format2(raw, out)[0]
-
- def format2(self, raw, out = None):
- """ Parse and send the colored source.
-
- If out and scheme are not specified, the defaults (given to
- constructor) are used.
-
- out should be a file-type object. Optionally, out can be given as the
- string 'str' and the parser will automatically return the output in a
- string."""
-
- string_output = 0
- if out == 'str' or self.out == 'str' or \
- isinstance(self.out, StringIO):
- # XXX - I don't really like this state handling logic, but at this
- # point I don't want to make major changes, so adding the
- # isinstance() check is the simplest I can do to ensure correct
- # behavior.
- out_old = self.out
- self.out = StringIO()
- string_output = 1
- elif out is not None:
- self.out = out
- else:
- raise ValueError('`out` or `self.out` should be file-like or the value `"str"`')
-
- # Fast return of the unmodified input for NoColor scheme
- if self.style == 'NoColor':
- error = False
- self.out.write(raw)
- if string_output:
- return raw, error
- return None, error
-
- # local shorthands
- colors = self.color_table[self.style].colors
- self.colors = colors # put in object so __call__ sees it
-
- # Remove trailing whitespace and normalize tabs
- self.raw = raw.expandtabs().rstrip()
-
- # store line offsets in self.lines
- self.lines = [0, 0]
- pos = 0
- raw_find = self.raw.find
- lines_append = self.lines.append
- while True:
- pos = raw_find('\n', pos) + 1
- if not pos:
- break
- lines_append(pos)
- lines_append(len(self.raw))
-
- # parse the source and write it
- self.pos = 0
- text = StringIO(self.raw)
-
- error = False
- try:
- for atoken in generate_tokens(text.readline):
- self(*atoken)
- except tokenize.TokenError as ex:
- msg = ex.args[0]
- line = ex.args[1][0]
- self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
- (colors[token.ERRORTOKEN],
- msg, self.raw[self.lines[line]:],
- colors.normal)
- )
- error = True
- self.out.write(colors.normal+'\n')
- if string_output:
- output = self.out.getvalue()
- self.out = out_old
- return (output, error)
- return (None, error)
-
-
- def _inner_call_(self, toktype, toktext, start_pos):
- """like call but write to a temporary buffer"""
- buff = StringIO()
- srow, scol = start_pos
- colors = self.colors
- owrite = buff.write
-
- # line separator, so this works across platforms
- linesep = os.linesep
-
- # calculate new positions
- oldpos = self.pos
- newpos = self.lines[srow] + scol
- self.pos = newpos + len(toktext)
-
- # send the original whitespace, if needed
- if newpos > oldpos:
- owrite(self.raw[oldpos:newpos])
-
- # skip indenting tokens
- if toktype in [token.INDENT, token.DEDENT]:
- self.pos = newpos
- buff.seek(0)
- return buff.read()
-
- # map token type to a color group
- if token.LPAR <= toktype <= token.OP:
- toktype = token.OP
- elif toktype == token.NAME and keyword.iskeyword(toktext):
- toktype = _KEYWORD
- color = colors.get(toktype, colors[_TEXT])
-
- # Triple quoted strings must be handled carefully so that backtracking
- # in pagers works correctly. We need color terminators on _each_ line.
- if linesep in toktext:
- toktext = toktext.replace(linesep, '%s%s%s' %
- (colors.normal,linesep,color))
-
- # send text
- owrite('%s%s%s' % (color,toktext,colors.normal))
- buff.seek(0)
- return buff.read()
-
-
- def __call__(self, toktype, toktext, start_pos, end_pos, line):
- """ Token handler, with syntax highlighting."""
- self.out.write(
- self._inner_call_(toktype, toktext, start_pos))
+# -*- coding: utf-8 -*-
+"""
+Class and program to colorize python source code for ANSI terminals.
+
+Based on an HTML code highlighter by Jurgen Hermann found at:
+http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
+
+Modifications by Fernando Perez (fperez@colorado.edu).
+
+Information on the original HTML highlighter follows:
+
+MoinMoin - Python Source Parser
+
+Title: Colorize Python source using the built-in tokenizer
+
+Submitter: Jurgen Hermann
+Last Updated:2001/04/06
+
+Version no:1.2
+
+Description:
+
+This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
+Python source code to HTML markup, rendering comments, keywords,
+operators, numeric and string literals in different colors.
+
+It shows how to use the built-in keyword, token and tokenize modules to
+scan Python source code and re-emit it with no changes to its original
+formatting (which is the hard part).
+"""
+
+__all__ = ['ANSICodeColors', 'Parser']
+
+_scheme_default = 'Linux'
+
+
+# Imports
+import keyword
+import os
+import sys
+import token
+import tokenize
+
+generate_tokens = tokenize.generate_tokens
+
+from IPython.utils.coloransi import TermColors, InputTermColors,ColorScheme, ColorSchemeTable
+from .colorable import Colorable
+from io import StringIO
+
+#############################################################################
+### Python Source Parser (does Highlighting)
+#############################################################################
+
+_KEYWORD = token.NT_OFFSET + 1
+_TEXT = token.NT_OFFSET + 2
+
+#****************************************************************************
+# Builtin color schemes
+
+Colors = TermColors # just a shorthand
+
+# Build a few color schemes
+NoColor = ColorScheme(
+ 'NoColor',{
+ 'header' : Colors.NoColor,
+ token.NUMBER : Colors.NoColor,
+ token.OP : Colors.NoColor,
+ token.STRING : Colors.NoColor,
+ tokenize.COMMENT : Colors.NoColor,
+ token.NAME : Colors.NoColor,
+ token.ERRORTOKEN : Colors.NoColor,
+
+ _KEYWORD : Colors.NoColor,
+ _TEXT : Colors.NoColor,
+
+ 'in_prompt' : InputTermColors.NoColor, # Input prompt
+ 'in_number' : InputTermColors.NoColor, # Input prompt number
+ 'in_prompt2' : InputTermColors.NoColor, # Continuation prompt
+ 'in_normal' : InputTermColors.NoColor, # color off (usu. Colors.Normal)
+
+ 'out_prompt' : Colors.NoColor, # Output prompt
+ 'out_number' : Colors.NoColor, # Output prompt number
+
+ 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
+ } )
+
+LinuxColors = ColorScheme(
+ 'Linux',{
+ 'header' : Colors.LightRed,
+ token.NUMBER : Colors.LightCyan,
+ token.OP : Colors.Yellow,
+ token.STRING : Colors.LightBlue,
+ tokenize.COMMENT : Colors.LightRed,
+ token.NAME : Colors.Normal,
+ token.ERRORTOKEN : Colors.Red,
+
+ _KEYWORD : Colors.LightGreen,
+ _TEXT : Colors.Yellow,
+
+ 'in_prompt' : InputTermColors.Green,
+ 'in_number' : InputTermColors.LightGreen,
+ 'in_prompt2' : InputTermColors.Green,
+ 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
+
+ 'out_prompt' : Colors.Red,
+ 'out_number' : Colors.LightRed,
+
+ 'normal' : Colors.Normal # color off (usu. Colors.Normal)
+ } )
+
+NeutralColors = ColorScheme(
+ 'Neutral',{
+ 'header' : Colors.Red,
+ token.NUMBER : Colors.Cyan,
+ token.OP : Colors.Blue,
+ token.STRING : Colors.Blue,
+ tokenize.COMMENT : Colors.Red,
+ token.NAME : Colors.Normal,
+ token.ERRORTOKEN : Colors.Red,
+
+ _KEYWORD : Colors.Green,
+ _TEXT : Colors.Blue,
+
+ 'in_prompt' : InputTermColors.Blue,
+ 'in_number' : InputTermColors.LightBlue,
+ 'in_prompt2' : InputTermColors.Blue,
+ 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
+
+ 'out_prompt' : Colors.Red,
+ 'out_number' : Colors.LightRed,
+
+ 'normal' : Colors.Normal # color off (usu. Colors.Normal)
+ } )
+
+# Hack: the 'neutral' colours are not very visible on a dark background on
+# Windows. Since Windows command prompts have a dark background by default, and
+# relatively few users are likely to alter that, we will use the 'Linux' colours,
+# designed for a dark background, as the default on Windows. Changing it here
+# avoids affecting the prompt colours rendered by prompt_toolkit, where the
+# neutral defaults do work OK.
+
+if os.name == 'nt':
+ NeutralColors = LinuxColors.copy(name='Neutral')
+
+LightBGColors = ColorScheme(
+ 'LightBG',{
+ 'header' : Colors.Red,
+ token.NUMBER : Colors.Cyan,
+ token.OP : Colors.Blue,
+ token.STRING : Colors.Blue,
+ tokenize.COMMENT : Colors.Red,
+ token.NAME : Colors.Normal,
+ token.ERRORTOKEN : Colors.Red,
+
+
+ _KEYWORD : Colors.Green,
+ _TEXT : Colors.Blue,
+
+ 'in_prompt' : InputTermColors.Blue,
+ 'in_number' : InputTermColors.LightBlue,
+ 'in_prompt2' : InputTermColors.Blue,
+ 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
+
+ 'out_prompt' : Colors.Red,
+ 'out_number' : Colors.LightRed,
+
+ 'normal' : Colors.Normal # color off (usu. Colors.Normal)
+ } )
+
+# Build table of color schemes (needed by the parser)
+ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors, NeutralColors],
+ _scheme_default)
+
+Undefined = object()
+
+class Parser(Colorable):
+ """ Format colored Python source.
+ """
+
+ def __init__(self, color_table=None, out = sys.stdout, parent=None, style=None):
+ """ Create a parser with a specified color table and output channel.
+
+ Call format() to process code.
+ """
+
+ super(Parser, self).__init__(parent=parent)
+
+ self.color_table = color_table if color_table else ANSICodeColors
+ self.out = out
+ self.pos = None
+ self.lines = None
+ self.raw = None
+ if not style:
+ self.style = self.default_style
+ else:
+ self.style = style
+
+
+ def format(self, raw, out=None, scheme=Undefined):
+ import warnings
+ if scheme is not Undefined:
+ warnings.warn('The `scheme` argument of IPython.utils.PyColorize:Parser.format is deprecated since IPython 6.0.'
+ 'It will have no effect. Set the parser `style` directly.',
+ stacklevel=2)
+ return self.format2(raw, out)[0]
+
+ def format2(self, raw, out = None):
+ """ Parse and send the colored source.
+
+ If out and scheme are not specified, the defaults (given to
+ constructor) are used.
+
+ out should be a file-type object. Optionally, out can be given as the
+ string 'str' and the parser will automatically return the output in a
+ string."""
+
+ string_output = 0
+ if out == 'str' or self.out == 'str' or \
+ isinstance(self.out, StringIO):
+ # XXX - I don't really like this state handling logic, but at this
+ # point I don't want to make major changes, so adding the
+ # isinstance() check is the simplest I can do to ensure correct
+ # behavior.
+ out_old = self.out
+ self.out = StringIO()
+ string_output = 1
+ elif out is not None:
+ self.out = out
+ else:
+ raise ValueError('`out` or `self.out` should be file-like or the value `"str"`')
+
+ # Fast return of the unmodified input for NoColor scheme
+ if self.style == 'NoColor':
+ error = False
+ self.out.write(raw)
+ if string_output:
+ return raw, error
+ return None, error
+
+ # local shorthands
+ colors = self.color_table[self.style].colors
+ self.colors = colors # put in object so __call__ sees it
+
+ # Remove trailing whitespace and normalize tabs
+ self.raw = raw.expandtabs().rstrip()
+
+ # store line offsets in self.lines
+ self.lines = [0, 0]
+ pos = 0
+ raw_find = self.raw.find
+ lines_append = self.lines.append
+ while True:
+ pos = raw_find('\n', pos) + 1
+ if not pos:
+ break
+ lines_append(pos)
+ lines_append(len(self.raw))
+
+ # parse the source and write it
+ self.pos = 0
+ text = StringIO(self.raw)
+
+ error = False
+ try:
+ for atoken in generate_tokens(text.readline):
+ self(*atoken)
+ except tokenize.TokenError as ex:
+ msg = ex.args[0]
+ line = ex.args[1][0]
+ self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
+ (colors[token.ERRORTOKEN],
+ msg, self.raw[self.lines[line]:],
+ colors.normal)
+ )
+ error = True
+ self.out.write(colors.normal+'\n')
+ if string_output:
+ output = self.out.getvalue()
+ self.out = out_old
+ return (output, error)
+ return (None, error)
+
+
+ def _inner_call_(self, toktype, toktext, start_pos):
+ """like call but write to a temporary buffer"""
+ buff = StringIO()
+ srow, scol = start_pos
+ colors = self.colors
+ owrite = buff.write
+
+ # line separator, so this works across platforms
+ linesep = os.linesep
+
+ # calculate new positions
+ oldpos = self.pos
+ newpos = self.lines[srow] + scol
+ self.pos = newpos + len(toktext)
+
+ # send the original whitespace, if needed
+ if newpos > oldpos:
+ owrite(self.raw[oldpos:newpos])
+
+ # skip indenting tokens
+ if toktype in [token.INDENT, token.DEDENT]:
+ self.pos = newpos
+ buff.seek(0)
+ return buff.read()
+
+ # map token type to a color group
+ if token.LPAR <= toktype <= token.OP:
+ toktype = token.OP
+ elif toktype == token.NAME and keyword.iskeyword(toktext):
+ toktype = _KEYWORD
+ color = colors.get(toktype, colors[_TEXT])
+
+ # Triple quoted strings must be handled carefully so that backtracking
+ # in pagers works correctly. We need color terminators on _each_ line.
+ if linesep in toktext:
+ toktext = toktext.replace(linesep, '%s%s%s' %
+ (colors.normal,linesep,color))
+
+ # send text
+ owrite('%s%s%s' % (color,toktext,colors.normal))
+ buff.seek(0)
+ return buff.read()
+
+
+ def __call__(self, toktype, toktext, start_pos, end_pos, line):
+ """ Token handler, with syntax highlighting."""
+ self.out.write(
+ self._inner_call_(toktype, toktext, start_pos))
diff --git a/contrib/python/ipython/py3/IPython/utils/_process_cli.py b/contrib/python/ipython/py3/IPython/utils/_process_cli.py
index a8e2179cdb..89a31c3164 100644
--- a/contrib/python/ipython/py3/IPython/utils/_process_cli.py
+++ b/contrib/python/ipython/py3/IPython/utils/_process_cli.py
@@ -1,78 +1,78 @@
-"""cli-specific implementation of process utilities.
-
-cli - Common Language Infrastructure for IronPython. Code
- can run on any operating system. Check os.name for os-
- specific settings.
-
-This file is only meant to be imported by process.py, not by end-users.
-
-This file is largely untested. To become a full drop-in process
-interface for IronPython will probably require you to help fill
-in the details.
-"""
-
-# Import cli libraries:
-import clr
-import System
-
-# Import Python libraries:
-import os
-
-# Import IPython libraries:
-from IPython.utils import py3compat
-from ._process_common import arg_split
-
-def _find_cmd(cmd):
- """Find the full path to a command using which."""
- paths = System.Environment.GetEnvironmentVariable("PATH").Split(os.pathsep)
- for path in paths:
- filename = os.path.join(path, cmd)
- if System.IO.File.Exists(filename):
- return py3compat.decode(filename)
- raise OSError("command %r not found" % cmd)
-
-def system(cmd):
- """
- system(cmd) should work in a cli environment on Mac OSX, Linux,
- and Windows
- """
- psi = System.Diagnostics.ProcessStartInfo(cmd)
- psi.RedirectStandardOutput = True
- psi.RedirectStandardError = True
- psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
- psi.UseShellExecute = False
- # Start up process:
- reg = System.Diagnostics.Process.Start(psi)
-
-def getoutput(cmd):
- """
- getoutput(cmd) should work in a cli environment on Mac OSX, Linux,
- and Windows
- """
- psi = System.Diagnostics.ProcessStartInfo(cmd)
- psi.RedirectStandardOutput = True
- psi.RedirectStandardError = True
- psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
- psi.UseShellExecute = False
- # Start up process:
- reg = System.Diagnostics.Process.Start(psi)
- myOutput = reg.StandardOutput
- output = myOutput.ReadToEnd()
- myError = reg.StandardError
- error = myError.ReadToEnd()
- return output
-
-def check_pid(pid):
- """
- Check if a process with the given PID (pid) exists
- """
- try:
- System.Diagnostics.Process.GetProcessById(pid)
- # process with given pid is running
- return True
- except System.InvalidOperationException:
- # process wasn't started by this object (but is running)
- return True
- except System.ArgumentException:
- # process with given pid isn't running
- return False
+"""cli-specific implementation of process utilities.
+
+cli - Common Language Infrastructure for IronPython. Code
+ can run on any operating system. Check os.name for os-
+ specific settings.
+
+This file is only meant to be imported by process.py, not by end-users.
+
+This file is largely untested. To become a full drop-in process
+interface for IronPython will probably require you to help fill
+in the details.
+"""
+
+# Import cli libraries:
+import clr
+import System
+
+# Import Python libraries:
+import os
+
+# Import IPython libraries:
+from IPython.utils import py3compat
+from ._process_common import arg_split
+
+def _find_cmd(cmd):
+ """Find the full path to a command using which."""
+ paths = System.Environment.GetEnvironmentVariable("PATH").Split(os.pathsep)
+ for path in paths:
+ filename = os.path.join(path, cmd)
+ if System.IO.File.Exists(filename):
+ return py3compat.decode(filename)
+ raise OSError("command %r not found" % cmd)
+
+def system(cmd):
+ """
+ system(cmd) should work in a cli environment on Mac OSX, Linux,
+ and Windows
+ """
+ psi = System.Diagnostics.ProcessStartInfo(cmd)
+ psi.RedirectStandardOutput = True
+ psi.RedirectStandardError = True
+ psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
+ psi.UseShellExecute = False
+ # Start up process:
+ reg = System.Diagnostics.Process.Start(psi)
+
+def getoutput(cmd):
+ """
+ getoutput(cmd) should work in a cli environment on Mac OSX, Linux,
+ and Windows
+ """
+ psi = System.Diagnostics.ProcessStartInfo(cmd)
+ psi.RedirectStandardOutput = True
+ psi.RedirectStandardError = True
+ psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
+ psi.UseShellExecute = False
+ # Start up process:
+ reg = System.Diagnostics.Process.Start(psi)
+ myOutput = reg.StandardOutput
+ output = myOutput.ReadToEnd()
+ myError = reg.StandardError
+ error = myError.ReadToEnd()
+ return output
+
+def check_pid(pid):
+ """
+ Check if a process with the given PID (pid) exists
+ """
+ try:
+ System.Diagnostics.Process.GetProcessById(pid)
+ # process with given pid is running
+ return True
+ except System.InvalidOperationException:
+ # process wasn't started by this object (but is running)
+ return True
+ except System.ArgumentException:
+ # process with given pid isn't running
+ return False
diff --git a/contrib/python/ipython/py3/IPython/utils/_process_common.py b/contrib/python/ipython/py3/IPython/utils/_process_common.py
index 1cb4b7cd08..2a647dc7fa 100644
--- a/contrib/python/ipython/py3/IPython/utils/_process_common.py
+++ b/contrib/python/ipython/py3/IPython/utils/_process_common.py
@@ -1,212 +1,212 @@
-"""Common utilities for the various process_* implementations.
-
-This file is only meant to be imported by the platform-specific implementations
-of subprocess utilities, and it contains tools that are common to all of them.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2010-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-import subprocess
-import shlex
-import sys
-import os
-
-from IPython.utils import py3compat
-
-#-----------------------------------------------------------------------------
-# Function definitions
-#-----------------------------------------------------------------------------
-
-def read_no_interrupt(p):
- """Read from a pipe ignoring EINTR errors.
-
- This is necessary because when reading from pipes with GUI event loops
- running in the background, often interrupts are raised that stop the
- command from completing."""
- import errno
-
- try:
- return p.read()
- except IOError as err:
- if err.errno != errno.EINTR:
- raise
-
-
-def process_handler(cmd, callback, stderr=subprocess.PIPE):
- """Open a command in a shell subprocess and execute a callback.
-
- This function provides common scaffolding for creating subprocess.Popen()
- calls. It creates a Popen object and then calls the callback with it.
-
- Parameters
- ----------
- cmd : str or list
- A command to be executed by the system, using :class:`subprocess.Popen`.
- If a string is passed, it will be run in the system shell. If a list is
- passed, it will be used directly as arguments.
-
- callback : callable
- A one-argument function that will be called with the Popen object.
-
- stderr : file descriptor number, optional
- By default this is set to ``subprocess.PIPE``, but you can also pass the
- value ``subprocess.STDOUT`` to force the subprocess' stderr to go into
- the same file descriptor as its stdout. This is useful to read stdout
- and stderr combined in the order they are generated.
-
- Returns
- -------
- The return value of the provided callback is returned.
- """
- sys.stdout.flush()
- sys.stderr.flush()
- # On win32, close_fds can't be true when using pipes for stdin/out/err
- close_fds = sys.platform != 'win32'
- # Determine if cmd should be run with system shell.
- shell = isinstance(cmd, str)
- # On POSIX systems run shell commands with user-preferred shell.
- executable = None
- if shell and os.name == 'posix' and 'SHELL' in os.environ:
- executable = os.environ['SHELL']
- p = subprocess.Popen(cmd, shell=shell,
- executable=executable,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=stderr,
- close_fds=close_fds)
-
- try:
- out = callback(p)
- except KeyboardInterrupt:
- print('^C')
- sys.stdout.flush()
- sys.stderr.flush()
- out = None
- finally:
- # Make really sure that we don't leave processes behind, in case the
- # call above raises an exception
- # We start by assuming the subprocess finished (to avoid NameErrors
- # later depending on the path taken)
- if p.returncode is None:
- try:
- p.terminate()
- p.poll()
- except OSError:
- pass
- # One last try on our way out
- if p.returncode is None:
- try:
- p.kill()
- except OSError:
- pass
-
- return out
-
-
-def getoutput(cmd):
- """Run a command and return its stdout/stderr as a string.
-
- Parameters
- ----------
- cmd : str or list
- A command to be executed in the system shell.
-
- Returns
- -------
- output : str
- A string containing the combination of stdout and stderr from the
- subprocess, in whatever order the subprocess originally wrote to its
- file descriptors (so the order of the information in this string is the
- correct order as would be seen if running the command in a terminal).
- """
- out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT)
- if out is None:
- return ''
- return py3compat.decode(out)
-
-
-def getoutputerror(cmd):
- """Return (standard output, standard error) of executing cmd in a shell.
-
- Accepts the same arguments as os.system().
-
- Parameters
- ----------
- cmd : str or list
- A command to be executed in the system shell.
-
- Returns
- -------
- stdout : str
- stderr : str
- """
- return get_output_error_code(cmd)[:2]
-
-def get_output_error_code(cmd):
- """Return (standard output, standard error, return code) of executing cmd
- in a shell.
-
- Accepts the same arguments as os.system().
-
- Parameters
- ----------
- cmd : str or list
- A command to be executed in the system shell.
-
- Returns
- -------
- stdout : str
- stderr : str
- returncode: int
- """
-
- out_err, p = process_handler(cmd, lambda p: (p.communicate(), p))
- if out_err is None:
- return '', '', p.returncode
- out, err = out_err
- return py3compat.decode(out), py3compat.decode(err), p.returncode
-
-def arg_split(s, posix=False, strict=True):
- """Split a command line's arguments in a shell-like manner.
-
- This is a modified version of the standard library's shlex.split()
- function, but with a default of posix=False for splitting, so that quotes
- in inputs are respected.
-
- if strict=False, then any errors shlex.split would raise will result in the
- unparsed remainder being the last element of the list, rather than raising.
- This is because we sometimes use arg_split to parse things other than
- command-line args.
- """
-
- lex = shlex.shlex(s, posix=posix)
- lex.whitespace_split = True
- # Extract tokens, ensuring that things like leaving open quotes
- # does not cause this to raise. This is important, because we
- # sometimes pass Python source through this (e.g. %timeit f(" ")),
- # and it shouldn't raise an exception.
- # It may be a bad idea to parse things that are not command-line args
- # through this function, but we do, so let's be safe about it.
- lex.commenters='' #fix for GH-1269
- tokens = []
- while True:
- try:
- tokens.append(next(lex))
- except StopIteration:
- break
- except ValueError:
- if strict:
- raise
- # couldn't parse, get remaining blob as last token
- tokens.append(lex.token)
- break
-
- return tokens
+"""Common utilities for the various process_* implementations.
+
+This file is only meant to be imported by the platform-specific implementations
+of subprocess utilities, and it contains tools that are common to all of them.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2010-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+import subprocess
+import shlex
+import sys
+import os
+
+from IPython.utils import py3compat
+
+#-----------------------------------------------------------------------------
+# Function definitions
+#-----------------------------------------------------------------------------
+
+def read_no_interrupt(p):
+ """Read from a pipe ignoring EINTR errors.
+
+ This is necessary because when reading from pipes with GUI event loops
+ running in the background, often interrupts are raised that stop the
+ command from completing."""
+ import errno
+
+ try:
+ return p.read()
+ except IOError as err:
+ if err.errno != errno.EINTR:
+ raise
+
+
+def process_handler(cmd, callback, stderr=subprocess.PIPE):
+ """Open a command in a shell subprocess and execute a callback.
+
+ This function provides common scaffolding for creating subprocess.Popen()
+ calls. It creates a Popen object and then calls the callback with it.
+
+ Parameters
+ ----------
+ cmd : str or list
+ A command to be executed by the system, using :class:`subprocess.Popen`.
+ If a string is passed, it will be run in the system shell. If a list is
+ passed, it will be used directly as arguments.
+
+ callback : callable
+ A one-argument function that will be called with the Popen object.
+
+ stderr : file descriptor number, optional
+ By default this is set to ``subprocess.PIPE``, but you can also pass the
+ value ``subprocess.STDOUT`` to force the subprocess' stderr to go into
+ the same file descriptor as its stdout. This is useful to read stdout
+ and stderr combined in the order they are generated.
+
+ Returns
+ -------
+ The return value of the provided callback is returned.
+ """
+ sys.stdout.flush()
+ sys.stderr.flush()
+ # On win32, close_fds can't be true when using pipes for stdin/out/err
+ close_fds = sys.platform != 'win32'
+ # Determine if cmd should be run with system shell.
+ shell = isinstance(cmd, str)
+ # On POSIX systems run shell commands with user-preferred shell.
+ executable = None
+ if shell and os.name == 'posix' and 'SHELL' in os.environ:
+ executable = os.environ['SHELL']
+ p = subprocess.Popen(cmd, shell=shell,
+ executable=executable,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=stderr,
+ close_fds=close_fds)
+
+ try:
+ out = callback(p)
+ except KeyboardInterrupt:
+ print('^C')
+ sys.stdout.flush()
+ sys.stderr.flush()
+ out = None
+ finally:
+ # Make really sure that we don't leave processes behind, in case the
+ # call above raises an exception
+ # We start by assuming the subprocess finished (to avoid NameErrors
+ # later depending on the path taken)
+ if p.returncode is None:
+ try:
+ p.terminate()
+ p.poll()
+ except OSError:
+ pass
+ # One last try on our way out
+ if p.returncode is None:
+ try:
+ p.kill()
+ except OSError:
+ pass
+
+ return out
+
+
+def getoutput(cmd):
+ """Run a command and return its stdout/stderr as a string.
+
+ Parameters
+ ----------
+ cmd : str or list
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ output : str
+ A string containing the combination of stdout and stderr from the
+ subprocess, in whatever order the subprocess originally wrote to its
+ file descriptors (so the order of the information in this string is the
+ correct order as would be seen if running the command in a terminal).
+ """
+ out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT)
+ if out is None:
+ return ''
+ return py3compat.decode(out)
+
+
+def getoutputerror(cmd):
+ """Return (standard output, standard error) of executing cmd in a shell.
+
+ Accepts the same arguments as os.system().
+
+ Parameters
+ ----------
+ cmd : str or list
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ stdout : str
+ stderr : str
+ """
+ return get_output_error_code(cmd)[:2]
+
+def get_output_error_code(cmd):
+ """Return (standard output, standard error, return code) of executing cmd
+ in a shell.
+
+ Accepts the same arguments as os.system().
+
+ Parameters
+ ----------
+ cmd : str or list
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ stdout : str
+ stderr : str
+ returncode: int
+ """
+
+ out_err, p = process_handler(cmd, lambda p: (p.communicate(), p))
+ if out_err is None:
+ return '', '', p.returncode
+ out, err = out_err
+ return py3compat.decode(out), py3compat.decode(err), p.returncode
+
+def arg_split(s, posix=False, strict=True):
+ """Split a command line's arguments in a shell-like manner.
+
+ This is a modified version of the standard library's shlex.split()
+ function, but with a default of posix=False for splitting, so that quotes
+ in inputs are respected.
+
+ if strict=False, then any errors shlex.split would raise will result in the
+ unparsed remainder being the last element of the list, rather than raising.
+ This is because we sometimes use arg_split to parse things other than
+ command-line args.
+ """
+
+ lex = shlex.shlex(s, posix=posix)
+ lex.whitespace_split = True
+ # Extract tokens, ensuring that things like leaving open quotes
+ # does not cause this to raise. This is important, because we
+ # sometimes pass Python source through this (e.g. %timeit f(" ")),
+ # and it shouldn't raise an exception.
+ # It may be a bad idea to parse things that are not command-line args
+ # through this function, but we do, so let's be safe about it.
+ lex.commenters='' #fix for GH-1269
+ tokens = []
+ while True:
+ try:
+ tokens.append(next(lex))
+ except StopIteration:
+ break
+ except ValueError:
+ if strict:
+ raise
+ # couldn't parse, get remaining blob as last token
+ tokens.append(lex.token)
+ break
+
+ return tokens
diff --git a/contrib/python/ipython/py3/IPython/utils/_process_posix.py b/contrib/python/ipython/py3/IPython/utils/_process_posix.py
index 8a4bf737c3..a11cad7697 100644
--- a/contrib/python/ipython/py3/IPython/utils/_process_posix.py
+++ b/contrib/python/ipython/py3/IPython/utils/_process_posix.py
@@ -1,225 +1,225 @@
-"""Posix-specific implementation of process utilities.
-
-This file is only meant to be imported by process.py, not by end-users.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2010-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-# Stdlib
-import errno
-import os
-import subprocess as sp
-import sys
-
-import pexpect
-
-# Our own
-from ._process_common import getoutput, arg_split
-from IPython.utils import py3compat
-from IPython.utils.encoding import DEFAULT_ENCODING
-
-#-----------------------------------------------------------------------------
-# Function definitions
-#-----------------------------------------------------------------------------
-
-def _find_cmd(cmd):
- """Find the full path to a command using which."""
-
- path = sp.Popen(['/usr/bin/env', 'which', cmd],
- stdout=sp.PIPE, stderr=sp.PIPE).communicate()[0]
- return py3compat.decode(path)
-
-
-class ProcessHandler(object):
- """Execute subprocesses under the control of pexpect.
- """
- # Timeout in seconds to wait on each reading of the subprocess' output.
- # This should not be set too low to avoid cpu overusage from our side,
- # since we read in a loop whose period is controlled by this timeout.
- read_timeout = 0.05
-
- # Timeout to give a process if we receive SIGINT, between sending the
- # SIGINT to the process and forcefully terminating it.
- terminate_timeout = 0.2
-
- # File object where stdout and stderr of the subprocess will be written
- logfile = None
-
- # Shell to call for subprocesses to execute
- _sh = None
-
- @property
- def sh(self):
- if self._sh is None:
- shell_name = os.environ.get("SHELL", "sh")
- self._sh = pexpect.which(shell_name)
- if self._sh is None:
- raise OSError('"{}" shell not found'.format(shell_name))
-
- return self._sh
-
- def __init__(self, logfile=None, read_timeout=None, terminate_timeout=None):
- """Arguments are used for pexpect calls."""
- self.read_timeout = (ProcessHandler.read_timeout if read_timeout is
- None else read_timeout)
- self.terminate_timeout = (ProcessHandler.terminate_timeout if
- terminate_timeout is None else
- terminate_timeout)
- self.logfile = sys.stdout if logfile is None else logfile
-
- def getoutput(self, cmd):
- """Run a command and return its stdout/stderr as a string.
-
- Parameters
- ----------
- cmd : str
- A command to be executed in the system shell.
-
- Returns
- -------
- output : str
- A string containing the combination of stdout and stderr from the
- subprocess, in whatever order the subprocess originally wrote to its
- file descriptors (so the order of the information in this string is the
- correct order as would be seen if running the command in a terminal).
- """
- try:
- return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n')
- except KeyboardInterrupt:
- print('^C', file=sys.stderr, end='')
-
- def getoutput_pexpect(self, cmd):
- """Run a command and return its stdout/stderr as a string.
-
- Parameters
- ----------
- cmd : str
- A command to be executed in the system shell.
-
- Returns
- -------
- output : str
- A string containing the combination of stdout and stderr from the
- subprocess, in whatever order the subprocess originally wrote to its
- file descriptors (so the order of the information in this string is the
- correct order as would be seen if running the command in a terminal).
- """
- try:
- return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n')
- except KeyboardInterrupt:
- print('^C', file=sys.stderr, end='')
-
- def system(self, cmd):
- """Execute a command in a subshell.
-
- Parameters
- ----------
- cmd : str
- A command to be executed in the system shell.
-
- Returns
- -------
- int : child's exitstatus
- """
- # Get likely encoding for the output.
- enc = DEFAULT_ENCODING
-
- # Patterns to match on the output, for pexpect. We read input and
- # allow either a short timeout or EOF
- patterns = [pexpect.TIMEOUT, pexpect.EOF]
- # the index of the EOF pattern in the list.
- # even though we know it's 1, this call means we don't have to worry if
- # we change the above list, and forget to change this value:
- EOF_index = patterns.index(pexpect.EOF)
- # The size of the output stored so far in the process output buffer.
- # Since pexpect only appends to this buffer, each time we print we
- # record how far we've printed, so that next time we only print *new*
- # content from the buffer.
- out_size = 0
- try:
- # Since we're not really searching the buffer for text patterns, we
- # can set pexpect's search window to be tiny and it won't matter.
- # We only search for the 'patterns' timeout or EOF, which aren't in
- # the text itself.
- #child = pexpect.spawn(pcmd, searchwindowsize=1)
- if hasattr(pexpect, 'spawnb'):
- child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U
- else:
- child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect
- flush = sys.stdout.flush
- while True:
- # res is the index of the pattern that caused the match, so we
- # know whether we've finished (if we matched EOF) or not
- res_idx = child.expect_list(patterns, self.read_timeout)
- print(child.before[out_size:].decode(enc, 'replace'), end='')
- flush()
- if res_idx==EOF_index:
- break
- # Update the pointer to what we've already printed
- out_size = len(child.before)
- except KeyboardInterrupt:
- # We need to send ^C to the process. The ascii code for '^C' is 3
- # (the character is known as ETX for 'End of Text', see
- # curses.ascii.ETX).
- child.sendline(chr(3))
- # Read and print any more output the program might produce on its
- # way out.
- try:
- out_size = len(child.before)
- child.expect_list(patterns, self.terminate_timeout)
- print(child.before[out_size:].decode(enc, 'replace'), end='')
- sys.stdout.flush()
- except KeyboardInterrupt:
- # Impatient users tend to type it multiple times
- pass
- finally:
- # Ensure the subprocess really is terminated
- child.terminate(force=True)
- # add isalive check, to ensure exitstatus is set:
- child.isalive()
-
- # We follow the subprocess pattern, returning either the exit status
- # as a positive number, or the terminating signal as a negative
- # number.
- # on Linux, sh returns 128+n for signals terminating child processes on Linux
- # on BSD (OS X), the signal code is set instead
- if child.exitstatus is None:
- # on WIFSIGNALED, pexpect sets signalstatus, leaving exitstatus=None
- if child.signalstatus is None:
- # this condition may never occur,
- # but let's be certain we always return an integer.
- return 0
- return -child.signalstatus
- if child.exitstatus > 128:
- return -(child.exitstatus - 128)
- return child.exitstatus
-
-
-# Make system() with a functional interface for outside use. Note that we use
-# getoutput() from the _common utils, which is built on top of popen(). Using
-# pexpect to get subprocess output produces difficult to parse output, since
-# programs think they are talking to a tty and produce highly formatted output
-# (ls is a good example) that makes them hard.
-system = ProcessHandler().system
-
-def check_pid(pid):
- try:
- os.kill(pid, 0)
- except OSError as err:
- if err.errno == errno.ESRCH:
- return False
- elif err.errno == errno.EPERM:
- # Don't have permission to signal the process - probably means it exists
- return True
- raise
- else:
- return True
+"""Posix-specific implementation of process utilities.
+
+This file is only meant to be imported by process.py, not by end-users.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2010-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+# Stdlib
+import errno
+import os
+import subprocess as sp
+import sys
+
+import pexpect
+
+# Our own
+from ._process_common import getoutput, arg_split
+from IPython.utils import py3compat
+from IPython.utils.encoding import DEFAULT_ENCODING
+
+#-----------------------------------------------------------------------------
+# Function definitions
+#-----------------------------------------------------------------------------
+
+def _find_cmd(cmd):
+ """Find the full path to a command using which."""
+
+ path = sp.Popen(['/usr/bin/env', 'which', cmd],
+ stdout=sp.PIPE, stderr=sp.PIPE).communicate()[0]
+ return py3compat.decode(path)
+
+
+class ProcessHandler(object):
+ """Execute subprocesses under the control of pexpect.
+ """
+ # Timeout in seconds to wait on each reading of the subprocess' output.
+ # This should not be set too low to avoid cpu overusage from our side,
+ # since we read in a loop whose period is controlled by this timeout.
+ read_timeout = 0.05
+
+ # Timeout to give a process if we receive SIGINT, between sending the
+ # SIGINT to the process and forcefully terminating it.
+ terminate_timeout = 0.2
+
+ # File object where stdout and stderr of the subprocess will be written
+ logfile = None
+
+ # Shell to call for subprocesses to execute
+ _sh = None
+
+ @property
+ def sh(self):
+ if self._sh is None:
+ shell_name = os.environ.get("SHELL", "sh")
+ self._sh = pexpect.which(shell_name)
+ if self._sh is None:
+ raise OSError('"{}" shell not found'.format(shell_name))
+
+ return self._sh
+
+ def __init__(self, logfile=None, read_timeout=None, terminate_timeout=None):
+ """Arguments are used for pexpect calls."""
+ self.read_timeout = (ProcessHandler.read_timeout if read_timeout is
+ None else read_timeout)
+ self.terminate_timeout = (ProcessHandler.terminate_timeout if
+ terminate_timeout is None else
+ terminate_timeout)
+ self.logfile = sys.stdout if logfile is None else logfile
+
+ def getoutput(self, cmd):
+ """Run a command and return its stdout/stderr as a string.
+
+ Parameters
+ ----------
+ cmd : str
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ output : str
+ A string containing the combination of stdout and stderr from the
+ subprocess, in whatever order the subprocess originally wrote to its
+ file descriptors (so the order of the information in this string is the
+ correct order as would be seen if running the command in a terminal).
+ """
+ try:
+ return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n')
+ except KeyboardInterrupt:
+ print('^C', file=sys.stderr, end='')
+
+ def getoutput_pexpect(self, cmd):
+ """Run a command and return its stdout/stderr as a string.
+
+ Parameters
+ ----------
+ cmd : str
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ output : str
+ A string containing the combination of stdout and stderr from the
+ subprocess, in whatever order the subprocess originally wrote to its
+ file descriptors (so the order of the information in this string is the
+ correct order as would be seen if running the command in a terminal).
+ """
+ try:
+ return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n')
+ except KeyboardInterrupt:
+ print('^C', file=sys.stderr, end='')
+
+ def system(self, cmd):
+ """Execute a command in a subshell.
+
+ Parameters
+ ----------
+ cmd : str
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ int : child's exitstatus
+ """
+ # Get likely encoding for the output.
+ enc = DEFAULT_ENCODING
+
+ # Patterns to match on the output, for pexpect. We read input and
+ # allow either a short timeout or EOF
+ patterns = [pexpect.TIMEOUT, pexpect.EOF]
+ # the index of the EOF pattern in the list.
+ # even though we know it's 1, this call means we don't have to worry if
+ # we change the above list, and forget to change this value:
+ EOF_index = patterns.index(pexpect.EOF)
+ # The size of the output stored so far in the process output buffer.
+ # Since pexpect only appends to this buffer, each time we print we
+ # record how far we've printed, so that next time we only print *new*
+ # content from the buffer.
+ out_size = 0
+ try:
+ # Since we're not really searching the buffer for text patterns, we
+ # can set pexpect's search window to be tiny and it won't matter.
+ # We only search for the 'patterns' timeout or EOF, which aren't in
+ # the text itself.
+ #child = pexpect.spawn(pcmd, searchwindowsize=1)
+ if hasattr(pexpect, 'spawnb'):
+ child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U
+ else:
+ child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect
+ flush = sys.stdout.flush
+ while True:
+ # res is the index of the pattern that caused the match, so we
+ # know whether we've finished (if we matched EOF) or not
+ res_idx = child.expect_list(patterns, self.read_timeout)
+ print(child.before[out_size:].decode(enc, 'replace'), end='')
+ flush()
+ if res_idx==EOF_index:
+ break
+ # Update the pointer to what we've already printed
+ out_size = len(child.before)
+ except KeyboardInterrupt:
+ # We need to send ^C to the process. The ascii code for '^C' is 3
+ # (the character is known as ETX for 'End of Text', see
+ # curses.ascii.ETX).
+ child.sendline(chr(3))
+ # Read and print any more output the program might produce on its
+ # way out.
+ try:
+ out_size = len(child.before)
+ child.expect_list(patterns, self.terminate_timeout)
+ print(child.before[out_size:].decode(enc, 'replace'), end='')
+ sys.stdout.flush()
+ except KeyboardInterrupt:
+ # Impatient users tend to type it multiple times
+ pass
+ finally:
+ # Ensure the subprocess really is terminated
+ child.terminate(force=True)
+ # add isalive check, to ensure exitstatus is set:
+ child.isalive()
+
+ # We follow the subprocess pattern, returning either the exit status
+ # as a positive number, or the terminating signal as a negative
+ # number.
+ # on Linux, sh returns 128+n for signals terminating child processes on Linux
+ # on BSD (OS X), the signal code is set instead
+ if child.exitstatus is None:
+ # on WIFSIGNALED, pexpect sets signalstatus, leaving exitstatus=None
+ if child.signalstatus is None:
+ # this condition may never occur,
+ # but let's be certain we always return an integer.
+ return 0
+ return -child.signalstatus
+ if child.exitstatus > 128:
+ return -(child.exitstatus - 128)
+ return child.exitstatus
+
+
+# Make system() with a functional interface for outside use. Note that we use
+# getoutput() from the _common utils, which is built on top of popen(). Using
+# pexpect to get subprocess output produces difficult to parse output, since
+# programs think they are talking to a tty and produce highly formatted output
+# (ls is a good example) that makes them hard.
+system = ProcessHandler().system
+
+def check_pid(pid):
+ try:
+ os.kill(pid, 0)
+ except OSError as err:
+ if err.errno == errno.ESRCH:
+ return False
+ elif err.errno == errno.EPERM:
+ # Don't have permission to signal the process - probably means it exists
+ return True
+ raise
+ else:
+ return True
diff --git a/contrib/python/ipython/py3/IPython/utils/_process_win32.py b/contrib/python/ipython/py3/IPython/utils/_process_win32.py
index 275694db30..6d05bdaa12 100644
--- a/contrib/python/ipython/py3/IPython/utils/_process_win32.py
+++ b/contrib/python/ipython/py3/IPython/utils/_process_win32.py
@@ -1,205 +1,205 @@
-"""Windows-specific implementation of process utilities.
-
-This file is only meant to be imported by process.py, not by end-users.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2010-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-# stdlib
-import os
-import sys
-import ctypes
-import time
-
-from ctypes import c_int, POINTER
-from ctypes.wintypes import LPCWSTR, HLOCAL
-from subprocess import STDOUT, TimeoutExpired
-from threading import Thread
-
-# our own imports
-from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
-from . import py3compat
-from .encoding import DEFAULT_ENCODING
-
-#-----------------------------------------------------------------------------
-# Function definitions
-#-----------------------------------------------------------------------------
-
-class AvoidUNCPath(object):
- """A context manager to protect command execution from UNC paths.
-
- In the Win32 API, commands can't be invoked with the cwd being a UNC path.
- This context manager temporarily changes directory to the 'C:' drive on
- entering, and restores the original working directory on exit.
-
- The context manager returns the starting working directory *if* it made a
- change and None otherwise, so that users can apply the necessary adjustment
- to their system calls in the event of a change.
-
- Examples
- --------
- ::
- cmd = 'dir'
- with AvoidUNCPath() as path:
- if path is not None:
- cmd = '"pushd %s &&"%s' % (path, cmd)
- os.system(cmd)
- """
- def __enter__(self):
- self.path = os.getcwd()
- self.is_unc_path = self.path.startswith(r"\\")
- if self.is_unc_path:
- # change to c drive (as cmd.exe cannot handle UNC addresses)
- os.chdir("C:")
- return self.path
- else:
- # We return None to signal that there was no change in the working
- # directory
- return None
-
- def __exit__(self, exc_type, exc_value, traceback):
- if self.is_unc_path:
- os.chdir(self.path)
-
-
-def _find_cmd(cmd):
- """Find the full path to a .bat or .exe using the win32api module."""
- try:
- from win32api import SearchPath
- except ImportError:
- raise ImportError('you need to have pywin32 installed for this to work')
- else:
- PATH = os.environ['PATH']
- extensions = ['.exe', '.com', '.bat', '.py']
- path = None
- for ext in extensions:
- try:
- path = SearchPath(PATH, cmd, ext)[0]
- except:
- pass
- if path is None:
- raise OSError("command %r not found" % cmd)
- else:
- return path
-
-
-def _system_body(p):
- """Callback for _system."""
- enc = DEFAULT_ENCODING
-
- def stdout_read():
- for line in read_no_interrupt(p.stdout).splitlines():
- line = line.decode(enc, 'replace')
- print(line, file=sys.stdout)
-
- def stderr_read():
- for line in read_no_interrupt(p.stderr).splitlines():
- line = line.decode(enc, 'replace')
- print(line, file=sys.stderr)
-
- Thread(target=stdout_read).start()
- Thread(target=stderr_read).start()
-
- # Wait to finish for returncode. Unfortunately, Python has a bug where
- # wait() isn't interruptible (https://bugs.python.org/issue28168) so poll in
- # a loop instead of just doing `return p.wait()`.
- while True:
- result = p.poll()
- if result is None:
- time.sleep(0.01)
- else:
- return result
-
-
-def system(cmd):
- """Win32 version of os.system() that works with network shares.
-
- Note that this implementation returns None, as meant for use in IPython.
-
- Parameters
- ----------
- cmd : str or list
- A command to be executed in the system shell.
-
- Returns
- -------
- int : child process' exit code.
- """
- # The controller provides interactivity with both
- # stdin and stdout
- #import _process_win32_controller
- #_process_win32_controller.system(cmd)
-
- with AvoidUNCPath() as path:
- if path is not None:
- cmd = '"pushd %s &&"%s' % (path, cmd)
- return process_handler(cmd, _system_body)
-
-def getoutput(cmd):
- """Return standard output of executing cmd in a shell.
-
- Accepts the same arguments as os.system().
-
- Parameters
- ----------
- cmd : str or list
- A command to be executed in the system shell.
-
- Returns
- -------
- stdout : str
- """
-
- with AvoidUNCPath() as path:
- if path is not None:
- cmd = '"pushd %s &&"%s' % (path, cmd)
- out = process_handler(cmd, lambda p: p.communicate()[0], STDOUT)
-
- if out is None:
- out = b''
- return py3compat.decode(out)
-
-try:
- CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
- CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)]
- CommandLineToArgvW.restype = POINTER(LPCWSTR)
- LocalFree = ctypes.windll.kernel32.LocalFree
- LocalFree.res_type = HLOCAL
- LocalFree.arg_types = [HLOCAL]
-
- def arg_split(commandline, posix=False, strict=True):
- """Split a command line's arguments in a shell-like manner.
-
- This is a special version for windows that use a ctypes call to CommandLineToArgvW
- to do the argv splitting. The posix parameter is ignored.
-
- If strict=False, process_common.arg_split(...strict=False) is used instead.
- """
- #CommandLineToArgvW returns path to executable if called with empty string.
- if commandline.strip() == "":
- return []
- if not strict:
- # not really a cl-arg, fallback on _process_common
- return py_arg_split(commandline, posix=posix, strict=strict)
- argvn = c_int()
- result_pointer = CommandLineToArgvW(py3compat.cast_unicode(commandline.lstrip()), ctypes.byref(argvn))
- result_array_type = LPCWSTR * argvn.value
- result = [arg for arg in result_array_type.from_address(ctypes.addressof(result_pointer.contents))]
- retval = LocalFree(result_pointer)
- return result
-except AttributeError:
- arg_split = py_arg_split
-
-def check_pid(pid):
- # OpenProcess returns 0 if no such process (of ours) exists
- # positive int otherwise
- return bool(ctypes.windll.kernel32.OpenProcess(1,0,pid))
+"""Windows-specific implementation of process utilities.
+
+This file is only meant to be imported by process.py, not by end-users.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2010-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+# stdlib
+import os
+import sys
+import ctypes
+import time
+
+from ctypes import c_int, POINTER
+from ctypes.wintypes import LPCWSTR, HLOCAL
+from subprocess import STDOUT, TimeoutExpired
+from threading import Thread
+
+# our own imports
+from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
+from . import py3compat
+from .encoding import DEFAULT_ENCODING
+
+#-----------------------------------------------------------------------------
+# Function definitions
+#-----------------------------------------------------------------------------
+
+class AvoidUNCPath(object):
+ """A context manager to protect command execution from UNC paths.
+
+ In the Win32 API, commands can't be invoked with the cwd being a UNC path.
+ This context manager temporarily changes directory to the 'C:' drive on
+ entering, and restores the original working directory on exit.
+
+ The context manager returns the starting working directory *if* it made a
+ change and None otherwise, so that users can apply the necessary adjustment
+ to their system calls in the event of a change.
+
+ Examples
+ --------
+ ::
+ cmd = 'dir'
+ with AvoidUNCPath() as path:
+ if path is not None:
+ cmd = '"pushd %s &&"%s' % (path, cmd)
+ os.system(cmd)
+ """
+ def __enter__(self):
+ self.path = os.getcwd()
+ self.is_unc_path = self.path.startswith(r"\\")
+ if self.is_unc_path:
+ # change to c drive (as cmd.exe cannot handle UNC addresses)
+ os.chdir("C:")
+ return self.path
+ else:
+ # We return None to signal that there was no change in the working
+ # directory
+ return None
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ if self.is_unc_path:
+ os.chdir(self.path)
+
+
+def _find_cmd(cmd):
+ """Find the full path to a .bat or .exe using the win32api module."""
+ try:
+ from win32api import SearchPath
+ except ImportError:
+ raise ImportError('you need to have pywin32 installed for this to work')
+ else:
+ PATH = os.environ['PATH']
+ extensions = ['.exe', '.com', '.bat', '.py']
+ path = None
+ for ext in extensions:
+ try:
+ path = SearchPath(PATH, cmd, ext)[0]
+ except:
+ pass
+ if path is None:
+ raise OSError("command %r not found" % cmd)
+ else:
+ return path
+
+
+def _system_body(p):
+ """Callback for _system."""
+ enc = DEFAULT_ENCODING
+
+ def stdout_read():
+ for line in read_no_interrupt(p.stdout).splitlines():
+ line = line.decode(enc, 'replace')
+ print(line, file=sys.stdout)
+
+ def stderr_read():
+ for line in read_no_interrupt(p.stderr).splitlines():
+ line = line.decode(enc, 'replace')
+ print(line, file=sys.stderr)
+
+ Thread(target=stdout_read).start()
+ Thread(target=stderr_read).start()
+
+ # Wait to finish for returncode. Unfortunately, Python has a bug where
+ # wait() isn't interruptible (https://bugs.python.org/issue28168) so poll in
+ # a loop instead of just doing `return p.wait()`.
+ while True:
+ result = p.poll()
+ if result is None:
+ time.sleep(0.01)
+ else:
+ return result
+
+
+def system(cmd):
+ """Win32 version of os.system() that works with network shares.
+
+ Note that this implementation returns None, as meant for use in IPython.
+
+ Parameters
+ ----------
+ cmd : str or list
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ int : child process' exit code.
+ """
+ # The controller provides interactivity with both
+ # stdin and stdout
+ #import _process_win32_controller
+ #_process_win32_controller.system(cmd)
+
+ with AvoidUNCPath() as path:
+ if path is not None:
+ cmd = '"pushd %s &&"%s' % (path, cmd)
+ return process_handler(cmd, _system_body)
+
+def getoutput(cmd):
+ """Return standard output of executing cmd in a shell.
+
+ Accepts the same arguments as os.system().
+
+ Parameters
+ ----------
+ cmd : str or list
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ stdout : str
+ """
+
+ with AvoidUNCPath() as path:
+ if path is not None:
+ cmd = '"pushd %s &&"%s' % (path, cmd)
+ out = process_handler(cmd, lambda p: p.communicate()[0], STDOUT)
+
+ if out is None:
+ out = b''
+ return py3compat.decode(out)
+
+try:
+ CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
+ CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)]
+ CommandLineToArgvW.restype = POINTER(LPCWSTR)
+ LocalFree = ctypes.windll.kernel32.LocalFree
+ LocalFree.res_type = HLOCAL
+ LocalFree.arg_types = [HLOCAL]
+
+ def arg_split(commandline, posix=False, strict=True):
+ """Split a command line's arguments in a shell-like manner.
+
+ This is a special version for windows that use a ctypes call to CommandLineToArgvW
+ to do the argv splitting. The posix parameter is ignored.
+
+ If strict=False, process_common.arg_split(...strict=False) is used instead.
+ """
+ #CommandLineToArgvW returns path to executable if called with empty string.
+ if commandline.strip() == "":
+ return []
+ if not strict:
+ # not really a cl-arg, fallback on _process_common
+ return py_arg_split(commandline, posix=posix, strict=strict)
+ argvn = c_int()
+ result_pointer = CommandLineToArgvW(py3compat.cast_unicode(commandline.lstrip()), ctypes.byref(argvn))
+ result_array_type = LPCWSTR * argvn.value
+ result = [arg for arg in result_array_type.from_address(ctypes.addressof(result_pointer.contents))]
+ retval = LocalFree(result_pointer)
+ return result
+except AttributeError:
+ arg_split = py_arg_split
+
+def check_pid(pid):
+ # OpenProcess returns 0 if no such process (of ours) exists
+ # positive int otherwise
+ return bool(ctypes.windll.kernel32.OpenProcess(1,0,pid))
diff --git a/contrib/python/ipython/py3/IPython/utils/_process_win32_controller.py b/contrib/python/ipython/py3/IPython/utils/_process_win32_controller.py
index e2889800de..c2e2329c45 100644
--- a/contrib/python/ipython/py3/IPython/utils/_process_win32_controller.py
+++ b/contrib/python/ipython/py3/IPython/utils/_process_win32_controller.py
@@ -1,573 +1,573 @@
-"""Windows-specific implementation of process utilities with direct WinAPI.
-
-This file is meant to be used by process.py
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2010-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-
-# stdlib
-import os, sys, threading
-import ctypes, msvcrt
-
-# Win32 API types needed for the API calls
-from ctypes import POINTER
-from ctypes.wintypes import HANDLE, HLOCAL, LPVOID, WORD, DWORD, BOOL, \
- ULONG, LPCWSTR
-LPDWORD = POINTER(DWORD)
-LPHANDLE = POINTER(HANDLE)
-ULONG_PTR = POINTER(ULONG)
-class SECURITY_ATTRIBUTES(ctypes.Structure):
- _fields_ = [("nLength", DWORD),
- ("lpSecurityDescriptor", LPVOID),
- ("bInheritHandle", BOOL)]
-LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES)
-class STARTUPINFO(ctypes.Structure):
- _fields_ = [("cb", DWORD),
- ("lpReserved", LPCWSTR),
- ("lpDesktop", LPCWSTR),
- ("lpTitle", LPCWSTR),
- ("dwX", DWORD),
- ("dwY", DWORD),
- ("dwXSize", DWORD),
- ("dwYSize", DWORD),
- ("dwXCountChars", DWORD),
- ("dwYCountChars", DWORD),
- ("dwFillAttribute", DWORD),
- ("dwFlags", DWORD),
- ("wShowWindow", WORD),
- ("cbReserved2", WORD),
- ("lpReserved2", LPVOID),
- ("hStdInput", HANDLE),
- ("hStdOutput", HANDLE),
- ("hStdError", HANDLE)]
-LPSTARTUPINFO = POINTER(STARTUPINFO)
-class PROCESS_INFORMATION(ctypes.Structure):
- _fields_ = [("hProcess", HANDLE),
- ("hThread", HANDLE),
- ("dwProcessId", DWORD),
- ("dwThreadId", DWORD)]
-LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)
-
-# Win32 API constants needed
-ERROR_HANDLE_EOF = 38
-ERROR_BROKEN_PIPE = 109
-ERROR_NO_DATA = 232
-HANDLE_FLAG_INHERIT = 0x0001
-STARTF_USESTDHANDLES = 0x0100
-CREATE_SUSPENDED = 0x0004
-CREATE_NEW_CONSOLE = 0x0010
-CREATE_NO_WINDOW = 0x08000000
-STILL_ACTIVE = 259
-WAIT_TIMEOUT = 0x0102
-WAIT_FAILED = 0xFFFFFFFF
-INFINITE = 0xFFFFFFFF
-DUPLICATE_SAME_ACCESS = 0x00000002
-ENABLE_ECHO_INPUT = 0x0004
-ENABLE_LINE_INPUT = 0x0002
-ENABLE_PROCESSED_INPUT = 0x0001
-
-# Win32 API functions needed
-GetLastError = ctypes.windll.kernel32.GetLastError
-GetLastError.argtypes = []
-GetLastError.restype = DWORD
-
-CreateFile = ctypes.windll.kernel32.CreateFileW
-CreateFile.argtypes = [LPCWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE]
-CreateFile.restype = HANDLE
-
-CreatePipe = ctypes.windll.kernel32.CreatePipe
-CreatePipe.argtypes = [POINTER(HANDLE), POINTER(HANDLE),
- LPSECURITY_ATTRIBUTES, DWORD]
-CreatePipe.restype = BOOL
-
-CreateProcess = ctypes.windll.kernel32.CreateProcessW
-CreateProcess.argtypes = [LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES,
- LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFO,
- LPPROCESS_INFORMATION]
-CreateProcess.restype = BOOL
-
-GetExitCodeProcess = ctypes.windll.kernel32.GetExitCodeProcess
-GetExitCodeProcess.argtypes = [HANDLE, LPDWORD]
-GetExitCodeProcess.restype = BOOL
-
-GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
-GetCurrentProcess.argtypes = []
-GetCurrentProcess.restype = HANDLE
-
-ResumeThread = ctypes.windll.kernel32.ResumeThread
-ResumeThread.argtypes = [HANDLE]
-ResumeThread.restype = DWORD
-
-ReadFile = ctypes.windll.kernel32.ReadFile
-ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
-ReadFile.restype = BOOL
-
-WriteFile = ctypes.windll.kernel32.WriteFile
-WriteFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
-WriteFile.restype = BOOL
-
-GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode
-GetConsoleMode.argtypes = [HANDLE, LPDWORD]
-GetConsoleMode.restype = BOOL
-
-SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode
-SetConsoleMode.argtypes = [HANDLE, DWORD]
-SetConsoleMode.restype = BOOL
-
-FlushConsoleInputBuffer = ctypes.windll.kernel32.FlushConsoleInputBuffer
-FlushConsoleInputBuffer.argtypes = [HANDLE]
-FlushConsoleInputBuffer.restype = BOOL
-
-WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
-WaitForSingleObject.argtypes = [HANDLE, DWORD]
-WaitForSingleObject.restype = DWORD
-
-DuplicateHandle = ctypes.windll.kernel32.DuplicateHandle
-DuplicateHandle.argtypes = [HANDLE, HANDLE, HANDLE, LPHANDLE,
- DWORD, BOOL, DWORD]
-DuplicateHandle.restype = BOOL
-
-SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
-SetHandleInformation.argtypes = [HANDLE, DWORD, DWORD]
-SetHandleInformation.restype = BOOL
-
-CloseHandle = ctypes.windll.kernel32.CloseHandle
-CloseHandle.argtypes = [HANDLE]
-CloseHandle.restype = BOOL
-
-CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
-CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(ctypes.c_int)]
-CommandLineToArgvW.restype = POINTER(LPCWSTR)
-
-LocalFree = ctypes.windll.kernel32.LocalFree
-LocalFree.argtypes = [HLOCAL]
-LocalFree.restype = HLOCAL
-
-class AvoidUNCPath(object):
- """A context manager to protect command execution from UNC paths.
-
- In the Win32 API, commands can't be invoked with the cwd being a UNC path.
- This context manager temporarily changes directory to the 'C:' drive on
- entering, and restores the original working directory on exit.
-
- The context manager returns the starting working directory *if* it made a
- change and None otherwise, so that users can apply the necessary adjustment
- to their system calls in the event of a change.
-
- Examples
- --------
- ::
- cmd = 'dir'
- with AvoidUNCPath() as path:
- if path is not None:
- cmd = '"pushd %s &&"%s' % (path, cmd)
- os.system(cmd)
- """
- def __enter__(self):
- self.path = os.getcwd()
- self.is_unc_path = self.path.startswith(r"\\")
- if self.is_unc_path:
- # change to c drive (as cmd.exe cannot handle UNC addresses)
- os.chdir("C:")
- return self.path
- else:
- # We return None to signal that there was no change in the working
- # directory
- return None
-
- def __exit__(self, exc_type, exc_value, traceback):
- if self.is_unc_path:
- os.chdir(self.path)
-
-
-class Win32ShellCommandController(object):
- """Runs a shell command in a 'with' context.
-
- This implementation is Win32-specific.
-
- Example:
- # Runs the command interactively with default console stdin/stdout
- with ShellCommandController('python -i') as scc:
- scc.run()
-
- # Runs the command using the provided functions for stdin/stdout
- def my_stdout_func(s):
- # print or save the string 's'
- write_to_stdout(s)
- def my_stdin_func():
- # If input is available, return it as a string.
- if input_available():
- return get_input()
- # If no input available, return None after a short delay to
- # keep from blocking.
- else:
- time.sleep(0.01)
- return None
-
- with ShellCommandController('python -i') as scc:
- scc.run(my_stdout_func, my_stdin_func)
- """
-
- def __init__(self, cmd, mergeout = True):
- """Initializes the shell command controller.
-
- The cmd is the program to execute, and mergeout is
- whether to blend stdout and stderr into one output
- in stdout. Merging them together in this fashion more
- reliably keeps stdout and stderr in the correct order
- especially for interactive shell usage.
- """
- self.cmd = cmd
- self.mergeout = mergeout
-
- def __enter__(self):
- cmd = self.cmd
- mergeout = self.mergeout
-
- self.hstdout, self.hstdin, self.hstderr = None, None, None
- self.piProcInfo = None
- try:
- p_hstdout, c_hstdout, p_hstderr, \
- c_hstderr, p_hstdin, c_hstdin = [None]*6
-
- # SECURITY_ATTRIBUTES with inherit handle set to True
- saAttr = SECURITY_ATTRIBUTES()
- saAttr.nLength = ctypes.sizeof(saAttr)
- saAttr.bInheritHandle = True
- saAttr.lpSecurityDescriptor = None
-
- def create_pipe(uninherit):
- """Creates a Windows pipe, which consists of two handles.
-
- The 'uninherit' parameter controls which handle is not
- inherited by the child process.
- """
- handles = HANDLE(), HANDLE()
- if not CreatePipe(ctypes.byref(handles[0]),
- ctypes.byref(handles[1]), ctypes.byref(saAttr), 0):
- raise ctypes.WinError()
- if not SetHandleInformation(handles[uninherit],
- HANDLE_FLAG_INHERIT, 0):
- raise ctypes.WinError()
- return handles[0].value, handles[1].value
-
- p_hstdout, c_hstdout = create_pipe(uninherit=0)
- # 'mergeout' signals that stdout and stderr should be merged.
- # We do that by using one pipe for both of them.
- if mergeout:
- c_hstderr = HANDLE()
- if not DuplicateHandle(GetCurrentProcess(), c_hstdout,
- GetCurrentProcess(), ctypes.byref(c_hstderr),
- 0, True, DUPLICATE_SAME_ACCESS):
- raise ctypes.WinError()
- else:
- p_hstderr, c_hstderr = create_pipe(uninherit=0)
- c_hstdin, p_hstdin = create_pipe(uninherit=1)
-
- # Create the process object
- piProcInfo = PROCESS_INFORMATION()
- siStartInfo = STARTUPINFO()
- siStartInfo.cb = ctypes.sizeof(siStartInfo)
- siStartInfo.hStdInput = c_hstdin
- siStartInfo.hStdOutput = c_hstdout
- siStartInfo.hStdError = c_hstderr
- siStartInfo.dwFlags = STARTF_USESTDHANDLES
- dwCreationFlags = CREATE_SUSPENDED | CREATE_NO_WINDOW # | CREATE_NEW_CONSOLE
-
- if not CreateProcess(None,
- u"cmd.exe /c " + cmd,
- None, None, True, dwCreationFlags,
- None, None, ctypes.byref(siStartInfo),
- ctypes.byref(piProcInfo)):
- raise ctypes.WinError()
-
- # Close this process's versions of the child handles
- CloseHandle(c_hstdin)
- c_hstdin = None
- CloseHandle(c_hstdout)
- c_hstdout = None
- if c_hstderr is not None:
- CloseHandle(c_hstderr)
- c_hstderr = None
-
- # Transfer ownership of the parent handles to the object
- self.hstdin = p_hstdin
- p_hstdin = None
- self.hstdout = p_hstdout
- p_hstdout = None
- if not mergeout:
- self.hstderr = p_hstderr
- p_hstderr = None
- self.piProcInfo = piProcInfo
-
- finally:
- if p_hstdin:
- CloseHandle(p_hstdin)
- if c_hstdin:
- CloseHandle(c_hstdin)
- if p_hstdout:
- CloseHandle(p_hstdout)
- if c_hstdout:
- CloseHandle(c_hstdout)
- if p_hstderr:
- CloseHandle(p_hstderr)
- if c_hstderr:
- CloseHandle(c_hstderr)
-
- return self
-
- def _stdin_thread(self, handle, hprocess, func, stdout_func):
- exitCode = DWORD()
- bytesWritten = DWORD(0)
- while True:
- #print("stdin thread loop start")
- # Get the input string (may be bytes or unicode)
- data = func()
-
- # None signals to poll whether the process has exited
- if data is None:
- #print("checking for process completion")
- if not GetExitCodeProcess(hprocess, ctypes.byref(exitCode)):
- raise ctypes.WinError()
- if exitCode.value != STILL_ACTIVE:
- return
- # TESTING: Does zero-sized writefile help?
- if not WriteFile(handle, "", 0,
- ctypes.byref(bytesWritten), None):
- raise ctypes.WinError()
- continue
- #print("\nGot str %s\n" % repr(data), file=sys.stderr)
-
- # Encode the string to the console encoding
- if isinstance(data, unicode): #FIXME: Python3
- data = data.encode('utf_8')
-
- # What we have now must be a string of bytes
- if not isinstance(data, str): #FIXME: Python3
- raise RuntimeError("internal stdin function string error")
-
- # An empty string signals EOF
- if len(data) == 0:
- return
-
- # In a windows console, sometimes the input is echoed,
- # but sometimes not. How do we determine when to do this?
- stdout_func(data)
- # WriteFile may not accept all the data at once.
- # Loop until everything is processed
- while len(data) != 0:
- #print("Calling writefile")
- if not WriteFile(handle, data, len(data),
- ctypes.byref(bytesWritten), None):
- # This occurs at exit
- if GetLastError() == ERROR_NO_DATA:
- return
- raise ctypes.WinError()
- #print("Called writefile")
- data = data[bytesWritten.value:]
-
- def _stdout_thread(self, handle, func):
- # Allocate the output buffer
- data = ctypes.create_string_buffer(4096)
- while True:
- bytesRead = DWORD(0)
- if not ReadFile(handle, data, 4096,
- ctypes.byref(bytesRead), None):
- le = GetLastError()
- if le == ERROR_BROKEN_PIPE:
- return
- else:
- raise ctypes.WinError()
- # FIXME: Python3
- s = data.value[0:bytesRead.value]
- #print("\nv: %s" % repr(s), file=sys.stderr)
- func(s.decode('utf_8', 'replace'))
-
- def run(self, stdout_func = None, stdin_func = None, stderr_func = None):
- """Runs the process, using the provided functions for I/O.
-
- The function stdin_func should return strings whenever a
- character or characters become available.
- The functions stdout_func and stderr_func are called whenever
- something is printed to stdout or stderr, respectively.
- These functions are called from different threads (but not
- concurrently, because of the GIL).
- """
- if stdout_func is None and stdin_func is None and stderr_func is None:
- return self._run_stdio()
-
- if stderr_func is not None and self.mergeout:
- raise RuntimeError("Shell command was initiated with "
- "merged stdin/stdout, but a separate stderr_func "
- "was provided to the run() method")
-
- # Create a thread for each input/output handle
- stdin_thread = None
- threads = []
- if stdin_func:
- stdin_thread = threading.Thread(target=self._stdin_thread,
- args=(self.hstdin, self.piProcInfo.hProcess,
- stdin_func, stdout_func))
- threads.append(threading.Thread(target=self._stdout_thread,
- args=(self.hstdout, stdout_func)))
- if not self.mergeout:
- if stderr_func is None:
- stderr_func = stdout_func
- threads.append(threading.Thread(target=self._stdout_thread,
- args=(self.hstderr, stderr_func)))
- # Start the I/O threads and the process
- if ResumeThread(self.piProcInfo.hThread) == 0xFFFFFFFF:
- raise ctypes.WinError()
- if stdin_thread is not None:
- stdin_thread.start()
- for thread in threads:
- thread.start()
- # Wait for the process to complete
- if WaitForSingleObject(self.piProcInfo.hProcess, INFINITE) == \
- WAIT_FAILED:
- raise ctypes.WinError()
- # Wait for the I/O threads to complete
- for thread in threads:
- thread.join()
-
- # Wait for the stdin thread to complete
- if stdin_thread is not None:
- stdin_thread.join()
-
- def _stdin_raw_nonblock(self):
- """Use the raw Win32 handle of sys.stdin to do non-blocking reads"""
- # WARNING: This is experimental, and produces inconsistent results.
- # It's possible for the handle not to be appropriate for use
- # with WaitForSingleObject, among other things.
- handle = msvcrt.get_osfhandle(sys.stdin.fileno())
- result = WaitForSingleObject(handle, 100)
- if result == WAIT_FAILED:
- raise ctypes.WinError()
- elif result == WAIT_TIMEOUT:
- print(".", end='')
- return None
- else:
- data = ctypes.create_string_buffer(256)
- bytesRead = DWORD(0)
- print('?', end='')
-
- if not ReadFile(handle, data, 256,
- ctypes.byref(bytesRead), None):
- raise ctypes.WinError()
- # This ensures the non-blocking works with an actual console
- # Not checking the error, so the processing will still work with
- # other handle types
- FlushConsoleInputBuffer(handle)
-
- data = data.value
- data = data.replace('\r\n', '\n')
- data = data.replace('\r', '\n')
- print(repr(data) + " ", end='')
- return data
-
- def _stdin_raw_block(self):
- """Use a blocking stdin read"""
- # The big problem with the blocking read is that it doesn't
- # exit when it's supposed to in all contexts. An extra
- # key-press may be required to trigger the exit.
- try:
- data = sys.stdin.read(1)
- data = data.replace('\r', '\n')
- return data
- except WindowsError as we:
- if we.winerror == ERROR_NO_DATA:
- # This error occurs when the pipe is closed
- return None
- else:
- # Otherwise let the error propagate
- raise we
-
- def _stdout_raw(self, s):
- """Writes the string to stdout"""
- print(s, end='', file=sys.stdout)
- sys.stdout.flush()
-
- def _stderr_raw(self, s):
- """Writes the string to stdout"""
- print(s, end='', file=sys.stderr)
- sys.stderr.flush()
-
- def _run_stdio(self):
- """Runs the process using the system standard I/O.
-
- IMPORTANT: stdin needs to be asynchronous, so the Python
- sys.stdin object is not used. Instead,
- msvcrt.kbhit/getwch are used asynchronously.
- """
- # Disable Line and Echo mode
- #lpMode = DWORD()
- #handle = msvcrt.get_osfhandle(sys.stdin.fileno())
- #if GetConsoleMode(handle, ctypes.byref(lpMode)):
- # set_console_mode = True
- # if not SetConsoleMode(handle, lpMode.value &
- # ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)):
- # raise ctypes.WinError()
-
- if self.mergeout:
- return self.run(stdout_func = self._stdout_raw,
- stdin_func = self._stdin_raw_block)
- else:
- return self.run(stdout_func = self._stdout_raw,
- stdin_func = self._stdin_raw_block,
- stderr_func = self._stderr_raw)
-
- # Restore the previous console mode
- #if set_console_mode:
- # if not SetConsoleMode(handle, lpMode.value):
- # raise ctypes.WinError()
-
- def __exit__(self, exc_type, exc_value, traceback):
- if self.hstdin:
- CloseHandle(self.hstdin)
- self.hstdin = None
- if self.hstdout:
- CloseHandle(self.hstdout)
- self.hstdout = None
- if self.hstderr:
- CloseHandle(self.hstderr)
- self.hstderr = None
- if self.piProcInfo is not None:
- CloseHandle(self.piProcInfo.hProcess)
- CloseHandle(self.piProcInfo.hThread)
- self.piProcInfo = None
-
-
-def system(cmd):
- """Win32 version of os.system() that works with network shares.
-
- Note that this implementation returns None, as meant for use in IPython.
-
- Parameters
- ----------
- cmd : str
- A command to be executed in the system shell.
-
- Returns
- -------
- None : we explicitly do NOT return the subprocess status code, as this
- utility is meant to be used extensively in IPython, where any return value
- would trigger :func:`sys.displayhook` calls.
- """
- with AvoidUNCPath() as path:
- if path is not None:
- cmd = '"pushd %s &&"%s' % (path, cmd)
- with Win32ShellCommandController(cmd) as scc:
- scc.run()
-
-
-if __name__ == "__main__":
- print("Test starting!")
- #system("cmd")
- system("python -i")
- print("Test finished!")
+"""Windows-specific implementation of process utilities with direct WinAPI.
+
+This file is meant to be used by process.py
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2010-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+
+# stdlib
+import os, sys, threading
+import ctypes, msvcrt
+
+# Win32 API types needed for the API calls
+from ctypes import POINTER
+from ctypes.wintypes import HANDLE, HLOCAL, LPVOID, WORD, DWORD, BOOL, \
+ ULONG, LPCWSTR
+LPDWORD = POINTER(DWORD)
+LPHANDLE = POINTER(HANDLE)
+ULONG_PTR = POINTER(ULONG)
+class SECURITY_ATTRIBUTES(ctypes.Structure):
+ _fields_ = [("nLength", DWORD),
+ ("lpSecurityDescriptor", LPVOID),
+ ("bInheritHandle", BOOL)]
+LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES)
+class STARTUPINFO(ctypes.Structure):
+ _fields_ = [("cb", DWORD),
+ ("lpReserved", LPCWSTR),
+ ("lpDesktop", LPCWSTR),
+ ("lpTitle", LPCWSTR),
+ ("dwX", DWORD),
+ ("dwY", DWORD),
+ ("dwXSize", DWORD),
+ ("dwYSize", DWORD),
+ ("dwXCountChars", DWORD),
+ ("dwYCountChars", DWORD),
+ ("dwFillAttribute", DWORD),
+ ("dwFlags", DWORD),
+ ("wShowWindow", WORD),
+ ("cbReserved2", WORD),
+ ("lpReserved2", LPVOID),
+ ("hStdInput", HANDLE),
+ ("hStdOutput", HANDLE),
+ ("hStdError", HANDLE)]
+LPSTARTUPINFO = POINTER(STARTUPINFO)
+class PROCESS_INFORMATION(ctypes.Structure):
+ _fields_ = [("hProcess", HANDLE),
+ ("hThread", HANDLE),
+ ("dwProcessId", DWORD),
+ ("dwThreadId", DWORD)]
+LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)
+
+# Win32 API constants needed
+ERROR_HANDLE_EOF = 38
+ERROR_BROKEN_PIPE = 109
+ERROR_NO_DATA = 232
+HANDLE_FLAG_INHERIT = 0x0001
+STARTF_USESTDHANDLES = 0x0100
+CREATE_SUSPENDED = 0x0004
+CREATE_NEW_CONSOLE = 0x0010
+CREATE_NO_WINDOW = 0x08000000
+STILL_ACTIVE = 259
+WAIT_TIMEOUT = 0x0102
+WAIT_FAILED = 0xFFFFFFFF
+INFINITE = 0xFFFFFFFF
+DUPLICATE_SAME_ACCESS = 0x00000002
+ENABLE_ECHO_INPUT = 0x0004
+ENABLE_LINE_INPUT = 0x0002
+ENABLE_PROCESSED_INPUT = 0x0001
+
+# Win32 API functions needed
+GetLastError = ctypes.windll.kernel32.GetLastError
+GetLastError.argtypes = []
+GetLastError.restype = DWORD
+
+CreateFile = ctypes.windll.kernel32.CreateFileW
+CreateFile.argtypes = [LPCWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE]
+CreateFile.restype = HANDLE
+
+CreatePipe = ctypes.windll.kernel32.CreatePipe
+CreatePipe.argtypes = [POINTER(HANDLE), POINTER(HANDLE),
+ LPSECURITY_ATTRIBUTES, DWORD]
+CreatePipe.restype = BOOL
+
+CreateProcess = ctypes.windll.kernel32.CreateProcessW
+CreateProcess.argtypes = [LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES,
+ LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFO,
+ LPPROCESS_INFORMATION]
+CreateProcess.restype = BOOL
+
+GetExitCodeProcess = ctypes.windll.kernel32.GetExitCodeProcess
+GetExitCodeProcess.argtypes = [HANDLE, LPDWORD]
+GetExitCodeProcess.restype = BOOL
+
+GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
+GetCurrentProcess.argtypes = []
+GetCurrentProcess.restype = HANDLE
+
+ResumeThread = ctypes.windll.kernel32.ResumeThread
+ResumeThread.argtypes = [HANDLE]
+ResumeThread.restype = DWORD
+
+ReadFile = ctypes.windll.kernel32.ReadFile
+ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
+ReadFile.restype = BOOL
+
+WriteFile = ctypes.windll.kernel32.WriteFile
+WriteFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
+WriteFile.restype = BOOL
+
+GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode
+GetConsoleMode.argtypes = [HANDLE, LPDWORD]
+GetConsoleMode.restype = BOOL
+
+SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode
+SetConsoleMode.argtypes = [HANDLE, DWORD]
+SetConsoleMode.restype = BOOL
+
+FlushConsoleInputBuffer = ctypes.windll.kernel32.FlushConsoleInputBuffer
+FlushConsoleInputBuffer.argtypes = [HANDLE]
+FlushConsoleInputBuffer.restype = BOOL
+
+WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
+WaitForSingleObject.argtypes = [HANDLE, DWORD]
+WaitForSingleObject.restype = DWORD
+
+DuplicateHandle = ctypes.windll.kernel32.DuplicateHandle
+DuplicateHandle.argtypes = [HANDLE, HANDLE, HANDLE, LPHANDLE,
+ DWORD, BOOL, DWORD]
+DuplicateHandle.restype = BOOL
+
+SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
+SetHandleInformation.argtypes = [HANDLE, DWORD, DWORD]
+SetHandleInformation.restype = BOOL
+
+CloseHandle = ctypes.windll.kernel32.CloseHandle
+CloseHandle.argtypes = [HANDLE]
+CloseHandle.restype = BOOL
+
+CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
+CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(ctypes.c_int)]
+CommandLineToArgvW.restype = POINTER(LPCWSTR)
+
+LocalFree = ctypes.windll.kernel32.LocalFree
+LocalFree.argtypes = [HLOCAL]
+LocalFree.restype = HLOCAL
+
+class AvoidUNCPath(object):
+ """A context manager to protect command execution from UNC paths.
+
+ In the Win32 API, commands can't be invoked with the cwd being a UNC path.
+ This context manager temporarily changes directory to the 'C:' drive on
+ entering, and restores the original working directory on exit.
+
+ The context manager returns the starting working directory *if* it made a
+ change and None otherwise, so that users can apply the necessary adjustment
+ to their system calls in the event of a change.
+
+ Examples
+ --------
+ ::
+ cmd = 'dir'
+ with AvoidUNCPath() as path:
+ if path is not None:
+ cmd = '"pushd %s &&"%s' % (path, cmd)
+ os.system(cmd)
+ """
+ def __enter__(self):
+ self.path = os.getcwd()
+ self.is_unc_path = self.path.startswith(r"\\")
+ if self.is_unc_path:
+ # change to c drive (as cmd.exe cannot handle UNC addresses)
+ os.chdir("C:")
+ return self.path
+ else:
+ # We return None to signal that there was no change in the working
+ # directory
+ return None
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ if self.is_unc_path:
+ os.chdir(self.path)
+
+
+class Win32ShellCommandController(object):
+ """Runs a shell command in a 'with' context.
+
+ This implementation is Win32-specific.
+
+ Example:
+ # Runs the command interactively with default console stdin/stdout
+ with ShellCommandController('python -i') as scc:
+ scc.run()
+
+ # Runs the command using the provided functions for stdin/stdout
+ def my_stdout_func(s):
+ # print or save the string 's'
+ write_to_stdout(s)
+ def my_stdin_func():
+ # If input is available, return it as a string.
+ if input_available():
+ return get_input()
+ # If no input available, return None after a short delay to
+ # keep from blocking.
+ else:
+ time.sleep(0.01)
+ return None
+
+ with ShellCommandController('python -i') as scc:
+ scc.run(my_stdout_func, my_stdin_func)
+ """
+
+ def __init__(self, cmd, mergeout = True):
+ """Initializes the shell command controller.
+
+ The cmd is the program to execute, and mergeout is
+ whether to blend stdout and stderr into one output
+ in stdout. Merging them together in this fashion more
+ reliably keeps stdout and stderr in the correct order
+ especially for interactive shell usage.
+ """
+ self.cmd = cmd
+ self.mergeout = mergeout
+
+ def __enter__(self):
+ cmd = self.cmd
+ mergeout = self.mergeout
+
+ self.hstdout, self.hstdin, self.hstderr = None, None, None
+ self.piProcInfo = None
+ try:
+ p_hstdout, c_hstdout, p_hstderr, \
+ c_hstderr, p_hstdin, c_hstdin = [None]*6
+
+ # SECURITY_ATTRIBUTES with inherit handle set to True
+ saAttr = SECURITY_ATTRIBUTES()
+ saAttr.nLength = ctypes.sizeof(saAttr)
+ saAttr.bInheritHandle = True
+ saAttr.lpSecurityDescriptor = None
+
+ def create_pipe(uninherit):
+ """Creates a Windows pipe, which consists of two handles.
+
+ The 'uninherit' parameter controls which handle is not
+ inherited by the child process.
+ """
+ handles = HANDLE(), HANDLE()
+ if not CreatePipe(ctypes.byref(handles[0]),
+ ctypes.byref(handles[1]), ctypes.byref(saAttr), 0):
+ raise ctypes.WinError()
+ if not SetHandleInformation(handles[uninherit],
+ HANDLE_FLAG_INHERIT, 0):
+ raise ctypes.WinError()
+ return handles[0].value, handles[1].value
+
+ p_hstdout, c_hstdout = create_pipe(uninherit=0)
+ # 'mergeout' signals that stdout and stderr should be merged.
+ # We do that by using one pipe for both of them.
+ if mergeout:
+ c_hstderr = HANDLE()
+ if not DuplicateHandle(GetCurrentProcess(), c_hstdout,
+ GetCurrentProcess(), ctypes.byref(c_hstderr),
+ 0, True, DUPLICATE_SAME_ACCESS):
+ raise ctypes.WinError()
+ else:
+ p_hstderr, c_hstderr = create_pipe(uninherit=0)
+ c_hstdin, p_hstdin = create_pipe(uninherit=1)
+
+ # Create the process object
+ piProcInfo = PROCESS_INFORMATION()
+ siStartInfo = STARTUPINFO()
+ siStartInfo.cb = ctypes.sizeof(siStartInfo)
+ siStartInfo.hStdInput = c_hstdin
+ siStartInfo.hStdOutput = c_hstdout
+ siStartInfo.hStdError = c_hstderr
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES
+ dwCreationFlags = CREATE_SUSPENDED | CREATE_NO_WINDOW # | CREATE_NEW_CONSOLE
+
+ if not CreateProcess(None,
+ u"cmd.exe /c " + cmd,
+ None, None, True, dwCreationFlags,
+ None, None, ctypes.byref(siStartInfo),
+ ctypes.byref(piProcInfo)):
+ raise ctypes.WinError()
+
+ # Close this process's versions of the child handles
+ CloseHandle(c_hstdin)
+ c_hstdin = None
+ CloseHandle(c_hstdout)
+ c_hstdout = None
+ if c_hstderr is not None:
+ CloseHandle(c_hstderr)
+ c_hstderr = None
+
+ # Transfer ownership of the parent handles to the object
+ self.hstdin = p_hstdin
+ p_hstdin = None
+ self.hstdout = p_hstdout
+ p_hstdout = None
+ if not mergeout:
+ self.hstderr = p_hstderr
+ p_hstderr = None
+ self.piProcInfo = piProcInfo
+
+ finally:
+ if p_hstdin:
+ CloseHandle(p_hstdin)
+ if c_hstdin:
+ CloseHandle(c_hstdin)
+ if p_hstdout:
+ CloseHandle(p_hstdout)
+ if c_hstdout:
+ CloseHandle(c_hstdout)
+ if p_hstderr:
+ CloseHandle(p_hstderr)
+ if c_hstderr:
+ CloseHandle(c_hstderr)
+
+ return self
+
+ def _stdin_thread(self, handle, hprocess, func, stdout_func):
+ exitCode = DWORD()
+ bytesWritten = DWORD(0)
+ while True:
+ #print("stdin thread loop start")
+ # Get the input string (may be bytes or unicode)
+ data = func()
+
+ # None signals to poll whether the process has exited
+ if data is None:
+ #print("checking for process completion")
+ if not GetExitCodeProcess(hprocess, ctypes.byref(exitCode)):
+ raise ctypes.WinError()
+ if exitCode.value != STILL_ACTIVE:
+ return
+ # TESTING: Does zero-sized writefile help?
+ if not WriteFile(handle, "", 0,
+ ctypes.byref(bytesWritten), None):
+ raise ctypes.WinError()
+ continue
+ #print("\nGot str %s\n" % repr(data), file=sys.stderr)
+
+ # Encode the string to the console encoding
+ if isinstance(data, unicode): #FIXME: Python3
+ data = data.encode('utf_8')
+
+ # What we have now must be a string of bytes
+ if not isinstance(data, str): #FIXME: Python3
+ raise RuntimeError("internal stdin function string error")
+
+ # An empty string signals EOF
+ if len(data) == 0:
+ return
+
+ # In a windows console, sometimes the input is echoed,
+ # but sometimes not. How do we determine when to do this?
+ stdout_func(data)
+ # WriteFile may not accept all the data at once.
+ # Loop until everything is processed
+ while len(data) != 0:
+ #print("Calling writefile")
+ if not WriteFile(handle, data, len(data),
+ ctypes.byref(bytesWritten), None):
+ # This occurs at exit
+ if GetLastError() == ERROR_NO_DATA:
+ return
+ raise ctypes.WinError()
+ #print("Called writefile")
+ data = data[bytesWritten.value:]
+
+ def _stdout_thread(self, handle, func):
+ # Allocate the output buffer
+ data = ctypes.create_string_buffer(4096)
+ while True:
+ bytesRead = DWORD(0)
+ if not ReadFile(handle, data, 4096,
+ ctypes.byref(bytesRead), None):
+ le = GetLastError()
+ if le == ERROR_BROKEN_PIPE:
+ return
+ else:
+ raise ctypes.WinError()
+ # FIXME: Python3
+ s = data.value[0:bytesRead.value]
+ #print("\nv: %s" % repr(s), file=sys.stderr)
+ func(s.decode('utf_8', 'replace'))
+
+ def run(self, stdout_func = None, stdin_func = None, stderr_func = None):
+ """Runs the process, using the provided functions for I/O.
+
+ The function stdin_func should return strings whenever a
+ character or characters become available.
+ The functions stdout_func and stderr_func are called whenever
+ something is printed to stdout or stderr, respectively.
+ These functions are called from different threads (but not
+ concurrently, because of the GIL).
+ """
+ if stdout_func is None and stdin_func is None and stderr_func is None:
+ return self._run_stdio()
+
+ if stderr_func is not None and self.mergeout:
+ raise RuntimeError("Shell command was initiated with "
+ "merged stdin/stdout, but a separate stderr_func "
+ "was provided to the run() method")
+
+ # Create a thread for each input/output handle
+ stdin_thread = None
+ threads = []
+ if stdin_func:
+ stdin_thread = threading.Thread(target=self._stdin_thread,
+ args=(self.hstdin, self.piProcInfo.hProcess,
+ stdin_func, stdout_func))
+ threads.append(threading.Thread(target=self._stdout_thread,
+ args=(self.hstdout, stdout_func)))
+ if not self.mergeout:
+ if stderr_func is None:
+ stderr_func = stdout_func
+ threads.append(threading.Thread(target=self._stdout_thread,
+ args=(self.hstderr, stderr_func)))
+ # Start the I/O threads and the process
+ if ResumeThread(self.piProcInfo.hThread) == 0xFFFFFFFF:
+ raise ctypes.WinError()
+ if stdin_thread is not None:
+ stdin_thread.start()
+ for thread in threads:
+ thread.start()
+ # Wait for the process to complete
+ if WaitForSingleObject(self.piProcInfo.hProcess, INFINITE) == \
+ WAIT_FAILED:
+ raise ctypes.WinError()
+ # Wait for the I/O threads to complete
+ for thread in threads:
+ thread.join()
+
+ # Wait for the stdin thread to complete
+ if stdin_thread is not None:
+ stdin_thread.join()
+
+ def _stdin_raw_nonblock(self):
+ """Use the raw Win32 handle of sys.stdin to do non-blocking reads"""
+ # WARNING: This is experimental, and produces inconsistent results.
+ # It's possible for the handle not to be appropriate for use
+ # with WaitForSingleObject, among other things.
+ handle = msvcrt.get_osfhandle(sys.stdin.fileno())
+ result = WaitForSingleObject(handle, 100)
+ if result == WAIT_FAILED:
+ raise ctypes.WinError()
+ elif result == WAIT_TIMEOUT:
+ print(".", end='')
+ return None
+ else:
+ data = ctypes.create_string_buffer(256)
+ bytesRead = DWORD(0)
+ print('?', end='')
+
+ if not ReadFile(handle, data, 256,
+ ctypes.byref(bytesRead), None):
+ raise ctypes.WinError()
+ # This ensures the non-blocking works with an actual console
+ # Not checking the error, so the processing will still work with
+ # other handle types
+ FlushConsoleInputBuffer(handle)
+
+ data = data.value
+ data = data.replace('\r\n', '\n')
+ data = data.replace('\r', '\n')
+ print(repr(data) + " ", end='')
+ return data
+
+ def _stdin_raw_block(self):
+ """Use a blocking stdin read"""
+ # The big problem with the blocking read is that it doesn't
+ # exit when it's supposed to in all contexts. An extra
+ # key-press may be required to trigger the exit.
+ try:
+ data = sys.stdin.read(1)
+ data = data.replace('\r', '\n')
+ return data
+ except WindowsError as we:
+ if we.winerror == ERROR_NO_DATA:
+ # This error occurs when the pipe is closed
+ return None
+ else:
+ # Otherwise let the error propagate
+ raise we
+
+ def _stdout_raw(self, s):
+ """Writes the string to stdout"""
+ print(s, end='', file=sys.stdout)
+ sys.stdout.flush()
+
+ def _stderr_raw(self, s):
+ """Writes the string to stdout"""
+ print(s, end='', file=sys.stderr)
+ sys.stderr.flush()
+
+ def _run_stdio(self):
+ """Runs the process using the system standard I/O.
+
+ IMPORTANT: stdin needs to be asynchronous, so the Python
+ sys.stdin object is not used. Instead,
+ msvcrt.kbhit/getwch are used asynchronously.
+ """
+ # Disable Line and Echo mode
+ #lpMode = DWORD()
+ #handle = msvcrt.get_osfhandle(sys.stdin.fileno())
+ #if GetConsoleMode(handle, ctypes.byref(lpMode)):
+ # set_console_mode = True
+ # if not SetConsoleMode(handle, lpMode.value &
+ # ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)):
+ # raise ctypes.WinError()
+
+ if self.mergeout:
+ return self.run(stdout_func = self._stdout_raw,
+ stdin_func = self._stdin_raw_block)
+ else:
+ return self.run(stdout_func = self._stdout_raw,
+ stdin_func = self._stdin_raw_block,
+ stderr_func = self._stderr_raw)
+
+ # Restore the previous console mode
+ #if set_console_mode:
+ # if not SetConsoleMode(handle, lpMode.value):
+ # raise ctypes.WinError()
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ if self.hstdin:
+ CloseHandle(self.hstdin)
+ self.hstdin = None
+ if self.hstdout:
+ CloseHandle(self.hstdout)
+ self.hstdout = None
+ if self.hstderr:
+ CloseHandle(self.hstderr)
+ self.hstderr = None
+ if self.piProcInfo is not None:
+ CloseHandle(self.piProcInfo.hProcess)
+ CloseHandle(self.piProcInfo.hThread)
+ self.piProcInfo = None
+
+
+def system(cmd):
+ """Win32 version of os.system() that works with network shares.
+
+ Note that this implementation returns None, as meant for use in IPython.
+
+ Parameters
+ ----------
+ cmd : str
+ A command to be executed in the system shell.
+
+ Returns
+ -------
+ None : we explicitly do NOT return the subprocess status code, as this
+ utility is meant to be used extensively in IPython, where any return value
+ would trigger :func:`sys.displayhook` calls.
+ """
+ with AvoidUNCPath() as path:
+ if path is not None:
+ cmd = '"pushd %s &&"%s' % (path, cmd)
+ with Win32ShellCommandController(cmd) as scc:
+ scc.run()
+
+
+if __name__ == "__main__":
+ print("Test starting!")
+ #system("cmd")
+ system("python -i")
+ print("Test finished!")
diff --git a/contrib/python/ipython/py3/IPython/utils/_sysinfo.py b/contrib/python/ipython/py3/IPython/utils/_sysinfo.py
index 13aad2ca5b..084b3b16a1 100644
--- a/contrib/python/ipython/py3/IPython/utils/_sysinfo.py
+++ b/contrib/python/ipython/py3/IPython/utils/_sysinfo.py
@@ -1,2 +1,2 @@
-# GENERATED BY setup.py
-commit = u"e321e760a"
+# GENERATED BY setup.py
+commit = u"e321e760a"
diff --git a/contrib/python/ipython/py3/IPython/utils/capture.py b/contrib/python/ipython/py3/IPython/utils/capture.py
index 34f79a76db..97b6336688 100644
--- a/contrib/python/ipython/py3/IPython/utils/capture.py
+++ b/contrib/python/ipython/py3/IPython/utils/capture.py
@@ -1,170 +1,170 @@
-# encoding: utf-8
-"""IO capturing utilities."""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-
-import sys
-from io import StringIO
-
-#-----------------------------------------------------------------------------
-# Classes and functions
-#-----------------------------------------------------------------------------
-
-
-class RichOutput(object):
- def __init__(self, data=None, metadata=None, transient=None, update=False):
- self.data = data or {}
- self.metadata = metadata or {}
- self.transient = transient or {}
- self.update = update
-
- def display(self):
- from IPython.display import publish_display_data
- publish_display_data(data=self.data, metadata=self.metadata,
- transient=self.transient, update=self.update)
-
- def _repr_mime_(self, mime):
- if mime not in self.data:
- return
- data = self.data[mime]
- if mime in self.metadata:
- return data, self.metadata[mime]
- else:
- return data
-
- def _repr_mimebundle_(self, include=None, exclude=None):
- return self.data, self.metadata
-
- def _repr_html_(self):
- return self._repr_mime_("text/html")
-
- def _repr_latex_(self):
- return self._repr_mime_("text/latex")
-
- def _repr_json_(self):
- return self._repr_mime_("application/json")
-
- def _repr_javascript_(self):
- return self._repr_mime_("application/javascript")
-
- def _repr_png_(self):
- return self._repr_mime_("image/png")
-
- def _repr_jpeg_(self):
- return self._repr_mime_("image/jpeg")
-
- def _repr_svg_(self):
- return self._repr_mime_("image/svg+xml")
-
-
-class CapturedIO(object):
- """Simple object for containing captured stdout/err and rich display StringIO objects
-
- Each instance `c` has three attributes:
-
- - ``c.stdout`` : standard output as a string
- - ``c.stderr`` : standard error as a string
- - ``c.outputs``: a list of rich display outputs
-
- Additionally, there's a ``c.show()`` method which will print all of the
- above in the same order, and can be invoked simply via ``c()``.
- """
-
- def __init__(self, stdout, stderr, outputs=None):
- self._stdout = stdout
- self._stderr = stderr
- if outputs is None:
- outputs = []
- self._outputs = outputs
-
- def __str__(self):
- return self.stdout
-
- @property
- def stdout(self):
- "Captured standard output"
- if not self._stdout:
- return ''
- return self._stdout.getvalue()
-
- @property
- def stderr(self):
- "Captured standard error"
- if not self._stderr:
- return ''
- return self._stderr.getvalue()
-
- @property
- def outputs(self):
- """A list of the captured rich display outputs, if any.
-
- If you have a CapturedIO object ``c``, these can be displayed in IPython
- using::
-
- from IPython.display import display
- for o in c.outputs:
- display(o)
- """
- return [ RichOutput(**kargs) for kargs in self._outputs ]
-
- def show(self):
- """write my output to sys.stdout/err as appropriate"""
- sys.stdout.write(self.stdout)
- sys.stderr.write(self.stderr)
- sys.stdout.flush()
- sys.stderr.flush()
- for kargs in self._outputs:
- RichOutput(**kargs).display()
-
- __call__ = show
-
-
-class capture_output(object):
- """context manager for capturing stdout/err"""
- stdout = True
- stderr = True
- display = True
-
- def __init__(self, stdout=True, stderr=True, display=True):
- self.stdout = stdout
- self.stderr = stderr
- self.display = display
- self.shell = None
-
- def __enter__(self):
- from IPython.core.getipython import get_ipython
- from IPython.core.displaypub import CapturingDisplayPublisher
- from IPython.core.displayhook import CapturingDisplayHook
-
- self.sys_stdout = sys.stdout
- self.sys_stderr = sys.stderr
-
- if self.display:
- self.shell = get_ipython()
- if self.shell is None:
- self.save_display_pub = None
- self.display = False
-
- stdout = stderr = outputs = None
- if self.stdout:
- stdout = sys.stdout = StringIO()
- if self.stderr:
- stderr = sys.stderr = StringIO()
- if self.display:
- self.save_display_pub = self.shell.display_pub
- self.shell.display_pub = CapturingDisplayPublisher()
- outputs = self.shell.display_pub.outputs
- self.save_display_hook = sys.displayhook
- sys.displayhook = CapturingDisplayHook(shell=self.shell,
- outputs=outputs)
-
- return CapturedIO(stdout, stderr, outputs)
-
- def __exit__(self, exc_type, exc_value, traceback):
- sys.stdout = self.sys_stdout
- sys.stderr = self.sys_stderr
- if self.display and self.shell:
- self.shell.display_pub = self.save_display_pub
- sys.displayhook = self.save_display_hook
+# encoding: utf-8
+"""IO capturing utilities."""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+
+import sys
+from io import StringIO
+
+#-----------------------------------------------------------------------------
+# Classes and functions
+#-----------------------------------------------------------------------------
+
+
+class RichOutput(object):
+ def __init__(self, data=None, metadata=None, transient=None, update=False):
+ self.data = data or {}
+ self.metadata = metadata or {}
+ self.transient = transient or {}
+ self.update = update
+
+ def display(self):
+ from IPython.display import publish_display_data
+ publish_display_data(data=self.data, metadata=self.metadata,
+ transient=self.transient, update=self.update)
+
+ def _repr_mime_(self, mime):
+ if mime not in self.data:
+ return
+ data = self.data[mime]
+ if mime in self.metadata:
+ return data, self.metadata[mime]
+ else:
+ return data
+
+ def _repr_mimebundle_(self, include=None, exclude=None):
+ return self.data, self.metadata
+
+ def _repr_html_(self):
+ return self._repr_mime_("text/html")
+
+ def _repr_latex_(self):
+ return self._repr_mime_("text/latex")
+
+ def _repr_json_(self):
+ return self._repr_mime_("application/json")
+
+ def _repr_javascript_(self):
+ return self._repr_mime_("application/javascript")
+
+ def _repr_png_(self):
+ return self._repr_mime_("image/png")
+
+ def _repr_jpeg_(self):
+ return self._repr_mime_("image/jpeg")
+
+ def _repr_svg_(self):
+ return self._repr_mime_("image/svg+xml")
+
+
+class CapturedIO(object):
+ """Simple object for containing captured stdout/err and rich display StringIO objects
+
+ Each instance `c` has three attributes:
+
+ - ``c.stdout`` : standard output as a string
+ - ``c.stderr`` : standard error as a string
+ - ``c.outputs``: a list of rich display outputs
+
+ Additionally, there's a ``c.show()`` method which will print all of the
+ above in the same order, and can be invoked simply via ``c()``.
+ """
+
+ def __init__(self, stdout, stderr, outputs=None):
+ self._stdout = stdout
+ self._stderr = stderr
+ if outputs is None:
+ outputs = []
+ self._outputs = outputs
+
+ def __str__(self):
+ return self.stdout
+
+ @property
+ def stdout(self):
+ "Captured standard output"
+ if not self._stdout:
+ return ''
+ return self._stdout.getvalue()
+
+ @property
+ def stderr(self):
+ "Captured standard error"
+ if not self._stderr:
+ return ''
+ return self._stderr.getvalue()
+
+ @property
+ def outputs(self):
+ """A list of the captured rich display outputs, if any.
+
+ If you have a CapturedIO object ``c``, these can be displayed in IPython
+ using::
+
+ from IPython.display import display
+ for o in c.outputs:
+ display(o)
+ """
+ return [ RichOutput(**kargs) for kargs in self._outputs ]
+
+ def show(self):
+ """write my output to sys.stdout/err as appropriate"""
+ sys.stdout.write(self.stdout)
+ sys.stderr.write(self.stderr)
+ sys.stdout.flush()
+ sys.stderr.flush()
+ for kargs in self._outputs:
+ RichOutput(**kargs).display()
+
+ __call__ = show
+
+
+class capture_output(object):
+ """context manager for capturing stdout/err"""
+ stdout = True
+ stderr = True
+ display = True
+
+ def __init__(self, stdout=True, stderr=True, display=True):
+ self.stdout = stdout
+ self.stderr = stderr
+ self.display = display
+ self.shell = None
+
+ def __enter__(self):
+ from IPython.core.getipython import get_ipython
+ from IPython.core.displaypub import CapturingDisplayPublisher
+ from IPython.core.displayhook import CapturingDisplayHook
+
+ self.sys_stdout = sys.stdout
+ self.sys_stderr = sys.stderr
+
+ if self.display:
+ self.shell = get_ipython()
+ if self.shell is None:
+ self.save_display_pub = None
+ self.display = False
+
+ stdout = stderr = outputs = None
+ if self.stdout:
+ stdout = sys.stdout = StringIO()
+ if self.stderr:
+ stderr = sys.stderr = StringIO()
+ if self.display:
+ self.save_display_pub = self.shell.display_pub
+ self.shell.display_pub = CapturingDisplayPublisher()
+ outputs = self.shell.display_pub.outputs
+ self.save_display_hook = sys.displayhook
+ sys.displayhook = CapturingDisplayHook(shell=self.shell,
+ outputs=outputs)
+
+ return CapturedIO(stdout, stderr, outputs)
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ sys.stdout = self.sys_stdout
+ sys.stderr = self.sys_stderr
+ if self.display and self.shell:
+ self.shell.display_pub = self.save_display_pub
+ sys.displayhook = self.save_display_hook
diff --git a/contrib/python/ipython/py3/IPython/utils/colorable.py b/contrib/python/ipython/py3/IPython/utils/colorable.py
index 5ff5bc77aa..1e3caef62b 100644
--- a/contrib/python/ipython/py3/IPython/utils/colorable.py
+++ b/contrib/python/ipython/py3/IPython/utils/colorable.py
@@ -1,25 +1,25 @@
-#*****************************************************************************
-# Copyright (C) 2016 The IPython Team <ipython-dev@scipy.org>
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#*****************************************************************************
-
-"""
-Color managing related utilities
-"""
-
-import pygments
-
-from traitlets.config import Configurable
-from traitlets import Unicode
-
-
-available_themes = lambda : [s for s in pygments.styles.get_all_styles()]+['NoColor','LightBG','Linux', 'Neutral']
-
-class Colorable(Configurable):
- """
- A subclass of configurable for all the classes that have a `default_scheme`
- """
- default_style=Unicode('LightBG').tag(config=True)
-
+#*****************************************************************************
+# Copyright (C) 2016 The IPython Team <ipython-dev@scipy.org>
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+"""
+Color managing related utilities
+"""
+
+import pygments
+
+from traitlets.config import Configurable
+from traitlets import Unicode
+
+
+available_themes = lambda : [s for s in pygments.styles.get_all_styles()]+['NoColor','LightBG','Linux', 'Neutral']
+
+class Colorable(Configurable):
+ """
+ A subclass of configurable for all the classes that have a `default_scheme`
+ """
+ default_style=Unicode('LightBG').tag(config=True)
+
diff --git a/contrib/python/ipython/py3/IPython/utils/coloransi.py b/contrib/python/ipython/py3/IPython/utils/coloransi.py
index 597c69fe11..bc8e8377f7 100644
--- a/contrib/python/ipython/py3/IPython/utils/coloransi.py
+++ b/contrib/python/ipython/py3/IPython/utils/coloransi.py
@@ -1,187 +1,187 @@
-# -*- coding: utf-8 -*-
-"""Tools for coloring text in ANSI terminals.
-"""
-
-#*****************************************************************************
-# Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#*****************************************************************************
-
-__all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
-
-import os
-
-from IPython.utils.ipstruct import Struct
-
-color_templates = (
- # Dark colors
- ("Black" , "0;30"),
- ("Red" , "0;31"),
- ("Green" , "0;32"),
- ("Brown" , "0;33"),
- ("Blue" , "0;34"),
- ("Purple" , "0;35"),
- ("Cyan" , "0;36"),
- ("LightGray" , "0;37"),
- # Light colors
- ("DarkGray" , "1;30"),
- ("LightRed" , "1;31"),
- ("LightGreen" , "1;32"),
- ("Yellow" , "1;33"),
- ("LightBlue" , "1;34"),
- ("LightPurple" , "1;35"),
- ("LightCyan" , "1;36"),
- ("White" , "1;37"),
- # Blinking colors. Probably should not be used in anything serious.
- ("BlinkBlack" , "5;30"),
- ("BlinkRed" , "5;31"),
- ("BlinkGreen" , "5;32"),
- ("BlinkYellow" , "5;33"),
- ("BlinkBlue" , "5;34"),
- ("BlinkPurple" , "5;35"),
- ("BlinkCyan" , "5;36"),
- ("BlinkLightGray", "5;37"),
- )
-
-def make_color_table(in_class):
- """Build a set of color attributes in a class.
-
- Helper function for building the :class:`TermColors` and
- :class`InputTermColors`.
- """
- for name,value in color_templates:
- setattr(in_class,name,in_class._base % value)
-
-class TermColors:
- """Color escape sequences.
-
- This class defines the escape sequences for all the standard (ANSI?)
- colors in terminals. Also defines a NoColor escape which is just the null
- string, suitable for defining 'dummy' color schemes in terminals which get
- confused by color escapes.
-
- This class should be used as a mixin for building color schemes."""
-
- NoColor = '' # for color schemes in color-less terminals.
- Normal = '\033[0m' # Reset normal coloring
- _base = '\033[%sm' # Template for all other colors
-
-# Build the actual color table as a set of class attributes:
-make_color_table(TermColors)
-
-class InputTermColors:
- """Color escape sequences for input prompts.
-
- This class is similar to TermColors, but the escapes are wrapped in \001
- and \002 so that readline can properly know the length of each line and
- can wrap lines accordingly. Use this class for any colored text which
- needs to be used in input prompts, such as in calls to raw_input().
-
- This class defines the escape sequences for all the standard (ANSI?)
- colors in terminals. Also defines a NoColor escape which is just the null
- string, suitable for defining 'dummy' color schemes in terminals which get
- confused by color escapes.
-
- This class should be used as a mixin for building color schemes."""
-
- NoColor = '' # for color schemes in color-less terminals.
-
- if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
- # (X)emacs on W32 gets confused with \001 and \002 so we remove them
- Normal = '\033[0m' # Reset normal coloring
- _base = '\033[%sm' # Template for all other colors
- else:
- Normal = '\001\033[0m\002' # Reset normal coloring
- _base = '\001\033[%sm\002' # Template for all other colors
-
-# Build the actual color table as a set of class attributes:
-make_color_table(InputTermColors)
-
-class NoColors:
- """This defines all the same names as the colour classes, but maps them to
- empty strings, so it can easily be substituted to turn off colours."""
- NoColor = ''
- Normal = ''
-
-for name, value in color_templates:
- setattr(NoColors, name, '')
-
-class ColorScheme:
- """Generic color scheme class. Just a name and a Struct."""
- def __init__(self,__scheme_name_,colordict=None,**colormap):
- self.name = __scheme_name_
- if colordict is None:
- self.colors = Struct(**colormap)
- else:
- self.colors = Struct(colordict)
-
- def copy(self,name=None):
- """Return a full copy of the object, optionally renaming it."""
- if name is None:
- name = self.name
- return ColorScheme(name, self.colors.dict())
-
-class ColorSchemeTable(dict):
- """General class to handle tables of color schemes.
-
- It's basically a dict of color schemes with a couple of shorthand
- attributes and some convenient methods.
-
- active_scheme_name -> obvious
- active_colors -> actual color table of the active scheme"""
-
- def __init__(self, scheme_list=None, default_scheme=''):
- """Create a table of color schemes.
-
- The table can be created empty and manually filled or it can be
- created with a list of valid color schemes AND the specification for
- the default active scheme.
- """
-
- # create object attributes to be set later
- self.active_scheme_name = ''
- self.active_colors = None
-
- if scheme_list:
- if default_scheme == '':
- raise ValueError('you must specify the default color scheme')
- for scheme in scheme_list:
- self.add_scheme(scheme)
- self.set_active_scheme(default_scheme)
-
- def copy(self):
- """Return full copy of object"""
- return ColorSchemeTable(self.values(),self.active_scheme_name)
-
- def add_scheme(self,new_scheme):
- """Add a new color scheme to the table."""
- if not isinstance(new_scheme,ColorScheme):
- raise ValueError('ColorSchemeTable only accepts ColorScheme instances')
- self[new_scheme.name] = new_scheme
-
- def set_active_scheme(self,scheme,case_sensitive=0):
- """Set the currently active scheme.
-
- Names are by default compared in a case-insensitive way, but this can
- be changed by setting the parameter case_sensitive to true."""
-
- scheme_names = list(self.keys())
- if case_sensitive:
- valid_schemes = scheme_names
- scheme_test = scheme
- else:
- valid_schemes = [s.lower() for s in scheme_names]
- scheme_test = scheme.lower()
- try:
- scheme_idx = valid_schemes.index(scheme_test)
- except ValueError:
- raise ValueError('Unrecognized color scheme: ' + scheme + \
- '\nValid schemes: '+str(scheme_names).replace("'', ",''))
- else:
- active = scheme_names[scheme_idx]
- self.active_scheme_name = active
- self.active_colors = self[active].colors
- # Now allow using '' as an index for the current active scheme
- self[''] = self[active]
+# -*- coding: utf-8 -*-
+"""Tools for coloring text in ANSI terminals.
+"""
+
+#*****************************************************************************
+# Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+__all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
+
+import os
+
+from IPython.utils.ipstruct import Struct
+
+color_templates = (
+ # Dark colors
+ ("Black" , "0;30"),
+ ("Red" , "0;31"),
+ ("Green" , "0;32"),
+ ("Brown" , "0;33"),
+ ("Blue" , "0;34"),
+ ("Purple" , "0;35"),
+ ("Cyan" , "0;36"),
+ ("LightGray" , "0;37"),
+ # Light colors
+ ("DarkGray" , "1;30"),
+ ("LightRed" , "1;31"),
+ ("LightGreen" , "1;32"),
+ ("Yellow" , "1;33"),
+ ("LightBlue" , "1;34"),
+ ("LightPurple" , "1;35"),
+ ("LightCyan" , "1;36"),
+ ("White" , "1;37"),
+ # Blinking colors. Probably should not be used in anything serious.
+ ("BlinkBlack" , "5;30"),
+ ("BlinkRed" , "5;31"),
+ ("BlinkGreen" , "5;32"),
+ ("BlinkYellow" , "5;33"),
+ ("BlinkBlue" , "5;34"),
+ ("BlinkPurple" , "5;35"),
+ ("BlinkCyan" , "5;36"),
+ ("BlinkLightGray", "5;37"),
+ )
+
+def make_color_table(in_class):
+ """Build a set of color attributes in a class.
+
+ Helper function for building the :class:`TermColors` and
+ :class`InputTermColors`.
+ """
+ for name,value in color_templates:
+ setattr(in_class,name,in_class._base % value)
+
+class TermColors:
+ """Color escape sequences.
+
+ This class defines the escape sequences for all the standard (ANSI?)
+ colors in terminals. Also defines a NoColor escape which is just the null
+ string, suitable for defining 'dummy' color schemes in terminals which get
+ confused by color escapes.
+
+ This class should be used as a mixin for building color schemes."""
+
+ NoColor = '' # for color schemes in color-less terminals.
+ Normal = '\033[0m' # Reset normal coloring
+ _base = '\033[%sm' # Template for all other colors
+
+# Build the actual color table as a set of class attributes:
+make_color_table(TermColors)
+
+class InputTermColors:
+ """Color escape sequences for input prompts.
+
+ This class is similar to TermColors, but the escapes are wrapped in \001
+ and \002 so that readline can properly know the length of each line and
+ can wrap lines accordingly. Use this class for any colored text which
+ needs to be used in input prompts, such as in calls to raw_input().
+
+ This class defines the escape sequences for all the standard (ANSI?)
+ colors in terminals. Also defines a NoColor escape which is just the null
+ string, suitable for defining 'dummy' color schemes in terminals which get
+ confused by color escapes.
+
+ This class should be used as a mixin for building color schemes."""
+
+ NoColor = '' # for color schemes in color-less terminals.
+
+ if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
+ # (X)emacs on W32 gets confused with \001 and \002 so we remove them
+ Normal = '\033[0m' # Reset normal coloring
+ _base = '\033[%sm' # Template for all other colors
+ else:
+ Normal = '\001\033[0m\002' # Reset normal coloring
+ _base = '\001\033[%sm\002' # Template for all other colors
+
+# Build the actual color table as a set of class attributes:
+make_color_table(InputTermColors)
+
+class NoColors:
+ """This defines all the same names as the colour classes, but maps them to
+ empty strings, so it can easily be substituted to turn off colours."""
+ NoColor = ''
+ Normal = ''
+
+for name, value in color_templates:
+ setattr(NoColors, name, '')
+
+class ColorScheme:
+ """Generic color scheme class. Just a name and a Struct."""
+ def __init__(self,__scheme_name_,colordict=None,**colormap):
+ self.name = __scheme_name_
+ if colordict is None:
+ self.colors = Struct(**colormap)
+ else:
+ self.colors = Struct(colordict)
+
+ def copy(self,name=None):
+ """Return a full copy of the object, optionally renaming it."""
+ if name is None:
+ name = self.name
+ return ColorScheme(name, self.colors.dict())
+
+class ColorSchemeTable(dict):
+ """General class to handle tables of color schemes.
+
+ It's basically a dict of color schemes with a couple of shorthand
+ attributes and some convenient methods.
+
+ active_scheme_name -> obvious
+ active_colors -> actual color table of the active scheme"""
+
+ def __init__(self, scheme_list=None, default_scheme=''):
+ """Create a table of color schemes.
+
+ The table can be created empty and manually filled or it can be
+ created with a list of valid color schemes AND the specification for
+ the default active scheme.
+ """
+
+ # create object attributes to be set later
+ self.active_scheme_name = ''
+ self.active_colors = None
+
+ if scheme_list:
+ if default_scheme == '':
+ raise ValueError('you must specify the default color scheme')
+ for scheme in scheme_list:
+ self.add_scheme(scheme)
+ self.set_active_scheme(default_scheme)
+
+ def copy(self):
+ """Return full copy of object"""
+ return ColorSchemeTable(self.values(),self.active_scheme_name)
+
+ def add_scheme(self,new_scheme):
+ """Add a new color scheme to the table."""
+ if not isinstance(new_scheme,ColorScheme):
+ raise ValueError('ColorSchemeTable only accepts ColorScheme instances')
+ self[new_scheme.name] = new_scheme
+
+ def set_active_scheme(self,scheme,case_sensitive=0):
+ """Set the currently active scheme.
+
+ Names are by default compared in a case-insensitive way, but this can
+ be changed by setting the parameter case_sensitive to true."""
+
+ scheme_names = list(self.keys())
+ if case_sensitive:
+ valid_schemes = scheme_names
+ scheme_test = scheme
+ else:
+ valid_schemes = [s.lower() for s in scheme_names]
+ scheme_test = scheme.lower()
+ try:
+ scheme_idx = valid_schemes.index(scheme_test)
+ except ValueError:
+ raise ValueError('Unrecognized color scheme: ' + scheme + \
+ '\nValid schemes: '+str(scheme_names).replace("'', ",''))
+ else:
+ active = scheme_names[scheme_idx]
+ self.active_scheme_name = active
+ self.active_colors = self[active].colors
+ # Now allow using '' as an index for the current active scheme
+ self[''] = self[active]
diff --git a/contrib/python/ipython/py3/IPython/utils/contexts.py b/contrib/python/ipython/py3/IPython/utils/contexts.py
index 214abace2c..4d379b0eda 100644
--- a/contrib/python/ipython/py3/IPython/utils/contexts.py
+++ b/contrib/python/ipython/py3/IPython/utils/contexts.py
@@ -1,74 +1,74 @@
-# encoding: utf-8
-"""Miscellaneous context managers.
-"""
-
-import warnings
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-class preserve_keys(object):
- """Preserve a set of keys in a dictionary.
-
- Upon entering the context manager the current values of the keys
- will be saved. Upon exiting, the dictionary will be updated to
- restore the original value of the preserved keys. Preserved keys
- which did not exist when entering the context manager will be
- deleted.
-
- Examples
- --------
-
- >>> d = {'a': 1, 'b': 2, 'c': 3}
- >>> with preserve_keys(d, 'b', 'c', 'd'):
- ... del d['a']
- ... del d['b'] # will be reset to 2
- ... d['c'] = None # will be reset to 3
- ... d['d'] = 4 # will be deleted
- ... d['e'] = 5
- ... print(sorted(d.items()))
- ...
- [('c', None), ('d', 4), ('e', 5)]
- >>> print(sorted(d.items()))
- [('b', 2), ('c', 3), ('e', 5)]
- """
-
- def __init__(self, dictionary, *keys):
- self.dictionary = dictionary
- self.keys = keys
-
- def __enter__(self):
- # Actions to perform upon exiting.
- to_delete = []
- to_update = {}
-
- d = self.dictionary
- for k in self.keys:
- if k in d:
- to_update[k] = d[k]
- else:
- to_delete.append(k)
-
- self.to_delete = to_delete
- self.to_update = to_update
-
- def __exit__(self, *exc_info):
- d = self.dictionary
-
- for k in self.to_delete:
- d.pop(k, None)
- d.update(self.to_update)
-
-
-class NoOpContext(object):
- """
- Deprecated
-
- Context manager that does nothing."""
-
- def __init__(self):
- warnings.warn("""NoOpContext is deprecated since IPython 5.0 """,
- DeprecationWarning, stacklevel=2)
-
- def __enter__(self): pass
- def __exit__(self, type, value, traceback): pass
+# encoding: utf-8
+"""Miscellaneous context managers.
+"""
+
+import warnings
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+class preserve_keys(object):
+ """Preserve a set of keys in a dictionary.
+
+ Upon entering the context manager the current values of the keys
+ will be saved. Upon exiting, the dictionary will be updated to
+ restore the original value of the preserved keys. Preserved keys
+ which did not exist when entering the context manager will be
+ deleted.
+
+ Examples
+ --------
+
+ >>> d = {'a': 1, 'b': 2, 'c': 3}
+ >>> with preserve_keys(d, 'b', 'c', 'd'):
+ ... del d['a']
+ ... del d['b'] # will be reset to 2
+ ... d['c'] = None # will be reset to 3
+ ... d['d'] = 4 # will be deleted
+ ... d['e'] = 5
+ ... print(sorted(d.items()))
+ ...
+ [('c', None), ('d', 4), ('e', 5)]
+ >>> print(sorted(d.items()))
+ [('b', 2), ('c', 3), ('e', 5)]
+ """
+
+ def __init__(self, dictionary, *keys):
+ self.dictionary = dictionary
+ self.keys = keys
+
+ def __enter__(self):
+ # Actions to perform upon exiting.
+ to_delete = []
+ to_update = {}
+
+ d = self.dictionary
+ for k in self.keys:
+ if k in d:
+ to_update[k] = d[k]
+ else:
+ to_delete.append(k)
+
+ self.to_delete = to_delete
+ self.to_update = to_update
+
+ def __exit__(self, *exc_info):
+ d = self.dictionary
+
+ for k in self.to_delete:
+ d.pop(k, None)
+ d.update(self.to_update)
+
+
+class NoOpContext(object):
+ """
+ Deprecated
+
+ Context manager that does nothing."""
+
+ def __init__(self):
+ warnings.warn("""NoOpContext is deprecated since IPython 5.0 """,
+ DeprecationWarning, stacklevel=2)
+
+ def __enter__(self): pass
+ def __exit__(self, type, value, traceback): pass
diff --git a/contrib/python/ipython/py3/IPython/utils/daemonize.py b/contrib/python/ipython/py3/IPython/utils/daemonize.py
index 9a4a013f0a..44b4a2832e 100644
--- a/contrib/python/ipython/py3/IPython/utils/daemonize.py
+++ b/contrib/python/ipython/py3/IPython/utils/daemonize.py
@@ -1,4 +1,4 @@
-from warnings import warn
-
-warn("IPython.utils.daemonize has moved to ipyparallel.apps.daemonize since IPython 4.0", DeprecationWarning, stacklevel=2)
-from ipyparallel.apps.daemonize import daemonize
+from warnings import warn
+
+warn("IPython.utils.daemonize has moved to ipyparallel.apps.daemonize since IPython 4.0", DeprecationWarning, stacklevel=2)
+from ipyparallel.apps.daemonize import daemonize
diff --git a/contrib/python/ipython/py3/IPython/utils/data.py b/contrib/python/ipython/py3/IPython/utils/data.py
index 7c449e9b83..433c90916c 100644
--- a/contrib/python/ipython/py3/IPython/utils/data.py
+++ b/contrib/python/ipython/py3/IPython/utils/data.py
@@ -1,30 +1,30 @@
-# encoding: utf-8
-"""Utilities for working with data structures like lists, dicts and tuples.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-
-def uniq_stable(elems):
- """uniq_stable(elems) -> list
-
- Return from an iterable, a list of all the unique elements in the input,
- but maintaining the order in which they first appear.
-
- Note: All elements in the input must be hashable for this routine
- to work, as it internally uses a set for efficiency reasons.
- """
- seen = set()
- return [x for x in elems if x not in seen and not seen.add(x)]
-
-
-def chop(seq, size):
- """Chop a sequence into chunks of the given size."""
- return [seq[i:i+size] for i in range(0,len(seq),size)]
-
-
+# encoding: utf-8
+"""Utilities for working with data structures like lists, dicts and tuples.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+
+def uniq_stable(elems):
+ """uniq_stable(elems) -> list
+
+ Return from an iterable, a list of all the unique elements in the input,
+ but maintaining the order in which they first appear.
+
+ Note: All elements in the input must be hashable for this routine
+ to work, as it internally uses a set for efficiency reasons.
+ """
+ seen = set()
+ return [x for x in elems if x not in seen and not seen.add(x)]
+
+
+def chop(seq, size):
+ """Chop a sequence into chunks of the given size."""
+ return [seq[i:i+size] for i in range(0,len(seq),size)]
+
+
diff --git a/contrib/python/ipython/py3/IPython/utils/decorators.py b/contrib/python/ipython/py3/IPython/utils/decorators.py
index 79be8ca1e6..c26485553c 100644
--- a/contrib/python/ipython/py3/IPython/utils/decorators.py
+++ b/contrib/python/ipython/py3/IPython/utils/decorators.py
@@ -1,58 +1,58 @@
-# encoding: utf-8
-"""Decorators that don't go anywhere else.
-
-This module contains misc. decorators that don't really go with another module
-in :mod:`IPython.utils`. Beore putting something here please see if it should
-go into another topical module in :mod:`IPython.utils`.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-
-def flag_calls(func):
- """Wrap a function to detect and flag when it gets called.
-
- This is a decorator which takes a function and wraps it in a function with
- a 'called' attribute. wrapper.called is initialized to False.
-
- The wrapper.called attribute is set to False right before each call to the
- wrapped function, so if the call fails it remains False. After the call
- completes, wrapper.called is set to True and the output is returned.
-
- Testing for truth in wrapper.called allows you to determine if a call to
- func() was attempted and succeeded."""
-
- # don't wrap twice
- if hasattr(func, 'called'):
- return func
-
- def wrapper(*args,**kw):
- wrapper.called = False
- out = func(*args,**kw)
- wrapper.called = True
- return out
-
- wrapper.called = False
- wrapper.__doc__ = func.__doc__
- return wrapper
-
-def undoc(func):
- """Mark a function or class as undocumented.
-
- This is found by inspecting the AST, so for now it must be used directly
- as @undoc, not as e.g. @decorators.undoc
- """
- return func
-
+# encoding: utf-8
+"""Decorators that don't go anywhere else.
+
+This module contains misc. decorators that don't really go with another module
+in :mod:`IPython.utils`. Beore putting something here please see if it should
+go into another topical module in :mod:`IPython.utils`.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+def flag_calls(func):
+ """Wrap a function to detect and flag when it gets called.
+
+ This is a decorator which takes a function and wraps it in a function with
+ a 'called' attribute. wrapper.called is initialized to False.
+
+ The wrapper.called attribute is set to False right before each call to the
+ wrapped function, so if the call fails it remains False. After the call
+ completes, wrapper.called is set to True and the output is returned.
+
+ Testing for truth in wrapper.called allows you to determine if a call to
+ func() was attempted and succeeded."""
+
+ # don't wrap twice
+ if hasattr(func, 'called'):
+ return func
+
+ def wrapper(*args,**kw):
+ wrapper.called = False
+ out = func(*args,**kw)
+ wrapper.called = True
+ return out
+
+ wrapper.called = False
+ wrapper.__doc__ = func.__doc__
+ return wrapper
+
+def undoc(func):
+ """Mark a function or class as undocumented.
+
+ This is found by inspecting the AST, so for now it must be used directly
+ as @undoc, not as e.g. @decorators.undoc
+ """
+ return func
+
diff --git a/contrib/python/ipython/py3/IPython/utils/dir2.py b/contrib/python/ipython/py3/IPython/utils/dir2.py
index 4521baecf4..9f19b2dd84 100644
--- a/contrib/python/ipython/py3/IPython/utils/dir2.py
+++ b/contrib/python/ipython/py3/IPython/utils/dir2.py
@@ -1,84 +1,84 @@
-# encoding: utf-8
-"""A fancy version of Python's builtin :func:`dir` function.
-"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-import inspect
-import types
-
-
-def safe_hasattr(obj, attr):
- """In recent versions of Python, hasattr() only catches AttributeError.
- This catches all errors.
- """
- try:
- getattr(obj, attr)
- return True
- except:
- return False
-
-
-def dir2(obj):
- """dir2(obj) -> list of strings
-
- Extended version of the Python builtin dir(), which does a few extra
- checks.
-
- This version is guaranteed to return only a list of true strings, whereas
- dir() returns anything that objects inject into themselves, even if they
- are later not really valid for attribute access (many extension libraries
- have such bugs).
- """
-
- # Start building the attribute list via dir(), and then complete it
- # with a few extra special-purpose calls.
-
- try:
- words = set(dir(obj))
- except Exception:
- # TypeError: dir(obj) does not return a list
- words = set()
-
- if safe_hasattr(obj, '__class__'):
- words |= set(dir(obj.__class__))
-
- # filter out non-string attributes which may be stuffed by dir() calls
- # and poor coding in third-party modules
-
- words = [w for w in words if isinstance(w, str)]
- return sorted(words)
-
-
-def get_real_method(obj, name):
- """Like getattr, but with a few extra sanity checks:
-
- - If obj is a class, ignore everything except class methods
- - Check if obj is a proxy that claims to have all attributes
- - Catch attribute access failing with any exception
- - Check that the attribute is a callable object
-
- Returns the method or None.
- """
- try:
- canary = getattr(obj, '_ipython_canary_method_should_not_exist_', None)
- except Exception:
- return None
-
- if canary is not None:
- # It claimed to have an attribute it should never have
- return None
-
- try:
- m = getattr(obj, name, None)
- except Exception:
- return None
-
- if inspect.isclass(obj) and not isinstance(m, types.MethodType):
- return None
-
- if callable(m):
- return m
-
- return None
+# encoding: utf-8
+"""A fancy version of Python's builtin :func:`dir` function.
+"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+import inspect
+import types
+
+
+def safe_hasattr(obj, attr):
+ """In recent versions of Python, hasattr() only catches AttributeError.
+ This catches all errors.
+ """
+ try:
+ getattr(obj, attr)
+ return True
+ except:
+ return False
+
+
+def dir2(obj):
+ """dir2(obj) -> list of strings
+
+ Extended version of the Python builtin dir(), which does a few extra
+ checks.
+
+ This version is guaranteed to return only a list of true strings, whereas
+ dir() returns anything that objects inject into themselves, even if they
+ are later not really valid for attribute access (many extension libraries
+ have such bugs).
+ """
+
+ # Start building the attribute list via dir(), and then complete it
+ # with a few extra special-purpose calls.
+
+ try:
+ words = set(dir(obj))
+ except Exception:
+ # TypeError: dir(obj) does not return a list
+ words = set()
+
+ if safe_hasattr(obj, '__class__'):
+ words |= set(dir(obj.__class__))
+
+ # filter out non-string attributes which may be stuffed by dir() calls
+ # and poor coding in third-party modules
+
+ words = [w for w in words if isinstance(w, str)]
+ return sorted(words)
+
+
+def get_real_method(obj, name):
+ """Like getattr, but with a few extra sanity checks:
+
+ - If obj is a class, ignore everything except class methods
+ - Check if obj is a proxy that claims to have all attributes
+ - Catch attribute access failing with any exception
+ - Check that the attribute is a callable object
+
+ Returns the method or None.
+ """
+ try:
+ canary = getattr(obj, '_ipython_canary_method_should_not_exist_', None)
+ except Exception:
+ return None
+
+ if canary is not None:
+ # It claimed to have an attribute it should never have
+ return None
+
+ try:
+ m = getattr(obj, name, None)
+ except Exception:
+ return None
+
+ if inspect.isclass(obj) and not isinstance(m, types.MethodType):
+ return None
+
+ if callable(m):
+ return m
+
+ return None
diff --git a/contrib/python/ipython/py3/IPython/utils/encoding.py b/contrib/python/ipython/py3/IPython/utils/encoding.py
index 84bc80c617..69a319ef0e 100644
--- a/contrib/python/ipython/py3/IPython/utils/encoding.py
+++ b/contrib/python/ipython/py3/IPython/utils/encoding.py
@@ -1,71 +1,71 @@
-# coding: utf-8
-"""
-Utilities for dealing with text encodings
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2012 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-import sys
-import locale
-import warnings
-
-# to deal with the possibility of sys.std* not being a stream at all
-def get_stream_enc(stream, default=None):
- """Return the given stream's encoding or a default.
-
- There are cases where ``sys.std*`` might not actually be a stream, so
- check for the encoding attribute prior to returning it, and return
- a default if it doesn't exist or evaluates as False. ``default``
- is None if not provided.
- """
- if not hasattr(stream, 'encoding') or not stream.encoding:
- return default
- else:
- return stream.encoding
-
-# Less conservative replacement for sys.getdefaultencoding, that will try
-# to match the environment.
-# Defined here as central function, so if we find better choices, we
-# won't need to make changes all over IPython.
-def getdefaultencoding(prefer_stream=True):
- """Return IPython's guess for the default encoding for bytes as text.
-
- If prefer_stream is True (default), asks for stdin.encoding first,
- to match the calling Terminal, but that is often None for subprocesses.
-
- Then fall back on locale.getpreferredencoding(),
- which should be a sensible platform default (that respects LANG environment),
- and finally to sys.getdefaultencoding() which is the most conservative option,
- and usually UTF8 as of Python 3.
- """
- enc = None
- if prefer_stream:
- enc = get_stream_enc(sys.stdin)
- if not enc or enc=='ascii':
- try:
- # There are reports of getpreferredencoding raising errors
- # in some cases, which may well be fixed, but let's be conservative here.
- enc = locale.getpreferredencoding()
- except Exception:
- pass
- enc = enc or sys.getdefaultencoding()
- # On windows `cp0` can be returned to indicate that there is no code page.
- # Since cp0 is an invalid encoding return instead cp1252 which is the
- # Western European default.
- if enc == 'cp0':
- warnings.warn(
- "Invalid code page cp0 detected - using cp1252 instead."
- "If cp1252 is incorrect please ensure a valid code page "
- "is defined for the process.", RuntimeWarning)
- return 'cp1252'
- return enc
-
-DEFAULT_ENCODING = getdefaultencoding()
+# coding: utf-8
+"""
+Utilities for dealing with text encodings
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2012 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+import sys
+import locale
+import warnings
+
+# to deal with the possibility of sys.std* not being a stream at all
+def get_stream_enc(stream, default=None):
+ """Return the given stream's encoding or a default.
+
+ There are cases where ``sys.std*`` might not actually be a stream, so
+ check for the encoding attribute prior to returning it, and return
+ a default if it doesn't exist or evaluates as False. ``default``
+ is None if not provided.
+ """
+ if not hasattr(stream, 'encoding') or not stream.encoding:
+ return default
+ else:
+ return stream.encoding
+
+# Less conservative replacement for sys.getdefaultencoding, that will try
+# to match the environment.
+# Defined here as central function, so if we find better choices, we
+# won't need to make changes all over IPython.
+def getdefaultencoding(prefer_stream=True):
+ """Return IPython's guess for the default encoding for bytes as text.
+
+ If prefer_stream is True (default), asks for stdin.encoding first,
+ to match the calling Terminal, but that is often None for subprocesses.
+
+ Then fall back on locale.getpreferredencoding(),
+ which should be a sensible platform default (that respects LANG environment),
+ and finally to sys.getdefaultencoding() which is the most conservative option,
+ and usually UTF8 as of Python 3.
+ """
+ enc = None
+ if prefer_stream:
+ enc = get_stream_enc(sys.stdin)
+ if not enc or enc=='ascii':
+ try:
+ # There are reports of getpreferredencoding raising errors
+ # in some cases, which may well be fixed, but let's be conservative here.
+ enc = locale.getpreferredencoding()
+ except Exception:
+ pass
+ enc = enc or sys.getdefaultencoding()
+ # On windows `cp0` can be returned to indicate that there is no code page.
+ # Since cp0 is an invalid encoding return instead cp1252 which is the
+ # Western European default.
+ if enc == 'cp0':
+ warnings.warn(
+ "Invalid code page cp0 detected - using cp1252 instead."
+ "If cp1252 is incorrect please ensure a valid code page "
+ "is defined for the process.", RuntimeWarning)
+ return 'cp1252'
+ return enc
+
+DEFAULT_ENCODING = getdefaultencoding()
diff --git a/contrib/python/ipython/py3/IPython/utils/eventful.py b/contrib/python/ipython/py3/IPython/utils/eventful.py
index a5b5841232..661851ed37 100644
--- a/contrib/python/ipython/py3/IPython/utils/eventful.py
+++ b/contrib/python/ipython/py3/IPython/utils/eventful.py
@@ -1,6 +1,6 @@
-
-from warnings import warn
-
-warn("IPython.utils.eventful has moved to traitlets.eventful", stacklevel=2)
-
-from traitlets.eventful import *
+
+from warnings import warn
+
+warn("IPython.utils.eventful has moved to traitlets.eventful", stacklevel=2)
+
+from traitlets.eventful import *
diff --git a/contrib/python/ipython/py3/IPython/utils/frame.py b/contrib/python/ipython/py3/IPython/utils/frame.py
index 04c67527b6..74c6d4197f 100644
--- a/contrib/python/ipython/py3/IPython/utils/frame.py
+++ b/contrib/python/ipython/py3/IPython/utils/frame.py
@@ -1,94 +1,94 @@
-# encoding: utf-8
-"""
-Utilities for working with stack frames.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-import sys
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-
-def extract_vars(*names,**kw):
- """Extract a set of variables by name from another frame.
-
- Parameters
- ----------
- *names : str
- One or more variable names which will be extracted from the caller's
- frame.
-
- depth : integer, optional
- How many frames in the stack to walk when looking for your variables.
- The default is 0, which will use the frame where the call was made.
-
-
- Examples
- --------
- ::
-
- In [2]: def func(x):
- ...: y = 1
- ...: print(sorted(extract_vars('x','y').items()))
- ...:
-
- In [3]: func('hello')
- [('x', 'hello'), ('y', 1)]
- """
-
- depth = kw.get('depth',0)
-
- callerNS = sys._getframe(depth+1).f_locals
- return dict((k,callerNS[k]) for k in names)
-
-
-def extract_vars_above(*names):
- """Extract a set of variables by name from another frame.
-
- Similar to extractVars(), but with a specified depth of 1, so that names
- are extracted exactly from above the caller.
-
- This is simply a convenience function so that the very common case (for us)
- of skipping exactly 1 frame doesn't have to construct a special dict for
- keyword passing."""
-
- callerNS = sys._getframe(2).f_locals
- return dict((k,callerNS[k]) for k in names)
-
-
-def debugx(expr,pre_msg=''):
- """Print the value of an expression from the caller's frame.
-
- Takes an expression, evaluates it in the caller's frame and prints both
- the given expression and the resulting value (as well as a debug mark
- indicating the name of the calling function. The input must be of a form
- suitable for eval().
-
- An optional message can be passed, which will be prepended to the printed
- expr->value pair."""
-
- cf = sys._getframe(1)
- print('[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
- eval(expr,cf.f_globals,cf.f_locals)))
-
-
-# deactivate it by uncommenting the following line, which makes it a no-op
-#def debugx(expr,pre_msg=''): pass
-
-def extract_module_locals(depth=0):
- """Returns (module, locals) of the function `depth` frames away from the caller"""
- f = sys._getframe(depth + 1)
- global_ns = f.f_globals
- module = sys.modules[global_ns['__name__']]
- return (module, f.f_locals)
+# encoding: utf-8
+"""
+Utilities for working with stack frames.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+import sys
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+def extract_vars(*names,**kw):
+ """Extract a set of variables by name from another frame.
+
+ Parameters
+ ----------
+ *names : str
+ One or more variable names which will be extracted from the caller's
+ frame.
+
+ depth : integer, optional
+ How many frames in the stack to walk when looking for your variables.
+ The default is 0, which will use the frame where the call was made.
+
+
+ Examples
+ --------
+ ::
+
+ In [2]: def func(x):
+ ...: y = 1
+ ...: print(sorted(extract_vars('x','y').items()))
+ ...:
+
+ In [3]: func('hello')
+ [('x', 'hello'), ('y', 1)]
+ """
+
+ depth = kw.get('depth',0)
+
+ callerNS = sys._getframe(depth+1).f_locals
+ return dict((k,callerNS[k]) for k in names)
+
+
+def extract_vars_above(*names):
+ """Extract a set of variables by name from another frame.
+
+ Similar to extractVars(), but with a specified depth of 1, so that names
+ are extracted exactly from above the caller.
+
+ This is simply a convenience function so that the very common case (for us)
+ of skipping exactly 1 frame doesn't have to construct a special dict for
+ keyword passing."""
+
+ callerNS = sys._getframe(2).f_locals
+ return dict((k,callerNS[k]) for k in names)
+
+
+def debugx(expr,pre_msg=''):
+ """Print the value of an expression from the caller's frame.
+
+ Takes an expression, evaluates it in the caller's frame and prints both
+ the given expression and the resulting value (as well as a debug mark
+ indicating the name of the calling function. The input must be of a form
+ suitable for eval().
+
+ An optional message can be passed, which will be prepended to the printed
+ expr->value pair."""
+
+ cf = sys._getframe(1)
+ print('[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
+ eval(expr,cf.f_globals,cf.f_locals)))
+
+
+# deactivate it by uncommenting the following line, which makes it a no-op
+#def debugx(expr,pre_msg=''): pass
+
+def extract_module_locals(depth=0):
+ """Returns (module, locals) of the function `depth` frames away from the caller"""
+ f = sys._getframe(depth + 1)
+ global_ns = f.f_globals
+ module = sys.modules[global_ns['__name__']]
+ return (module, f.f_locals)
diff --git a/contrib/python/ipython/py3/IPython/utils/generics.py b/contrib/python/ipython/py3/IPython/utils/generics.py
index 7bff95e7b3..fcada6f44d 100644
--- a/contrib/python/ipython/py3/IPython/utils/generics.py
+++ b/contrib/python/ipython/py3/IPython/utils/generics.py
@@ -1,30 +1,30 @@
-# encoding: utf-8
-"""Generic functions for extending IPython.
-"""
-
-from IPython.core.error import TryNext
-from functools import singledispatch
-
-
-@singledispatch
-def inspect_object(obj):
- """Called when you do obj?"""
- raise TryNext
-
-
-@singledispatch
-def complete_object(obj, prev_completions):
- """Custom completer dispatching for python objects.
-
- Parameters
- ----------
- obj : object
- The object to complete.
- prev_completions : list
- List of attributes discovered so far.
-
- This should return the list of attributes in obj. If you only wish to
- add to the attributes already discovered normally, return
- own_attrs + prev_completions.
- """
- raise TryNext
+# encoding: utf-8
+"""Generic functions for extending IPython.
+"""
+
+from IPython.core.error import TryNext
+from functools import singledispatch
+
+
+@singledispatch
+def inspect_object(obj):
+ """Called when you do obj?"""
+ raise TryNext
+
+
+@singledispatch
+def complete_object(obj, prev_completions):
+ """Custom completer dispatching for python objects.
+
+ Parameters
+ ----------
+ obj : object
+ The object to complete.
+ prev_completions : list
+ List of attributes discovered so far.
+
+ This should return the list of attributes in obj. If you only wish to
+ add to the attributes already discovered normally, return
+ own_attrs + prev_completions.
+ """
+ raise TryNext
diff --git a/contrib/python/ipython/py3/IPython/utils/importstring.py b/contrib/python/ipython/py3/IPython/utils/importstring.py
index 2c7a2a167e..c8e1840eb3 100644
--- a/contrib/python/ipython/py3/IPython/utils/importstring.py
+++ b/contrib/python/ipython/py3/IPython/utils/importstring.py
@@ -1,39 +1,39 @@
-# encoding: utf-8
-"""
-A simple utility to import something by its string name.
-"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-
-def import_item(name):
- """Import and return ``bar`` given the string ``foo.bar``.
-
- Calling ``bar = import_item("foo.bar")`` is the functional equivalent of
- executing the code ``from foo import bar``.
-
- Parameters
- ----------
- name : string
- The fully qualified name of the module/package being imported.
-
- Returns
- -------
- mod : module object
- The module that was imported.
- """
-
- parts = name.rsplit('.', 1)
- if len(parts) == 2:
- # called with 'foo.bar....'
- package, obj = parts
- module = __import__(package, fromlist=[obj])
- try:
- pak = getattr(module, obj)
- except AttributeError:
- raise ImportError('No module named %s' % obj)
- return pak
- else:
- # called with un-dotted string
- return __import__(parts[0])
+# encoding: utf-8
+"""
+A simple utility to import something by its string name.
+"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+
+def import_item(name):
+ """Import and return ``bar`` given the string ``foo.bar``.
+
+ Calling ``bar = import_item("foo.bar")`` is the functional equivalent of
+ executing the code ``from foo import bar``.
+
+ Parameters
+ ----------
+ name : string
+ The fully qualified name of the module/package being imported.
+
+ Returns
+ -------
+ mod : module object
+ The module that was imported.
+ """
+
+ parts = name.rsplit('.', 1)
+ if len(parts) == 2:
+ # called with 'foo.bar....'
+ package, obj = parts
+ module = __import__(package, fromlist=[obj])
+ try:
+ pak = getattr(module, obj)
+ except AttributeError:
+ raise ImportError('No module named %s' % obj)
+ return pak
+ else:
+ # called with un-dotted string
+ return __import__(parts[0])
diff --git a/contrib/python/ipython/py3/IPython/utils/io.py b/contrib/python/ipython/py3/IPython/utils/io.py
index e69abbebf2..fab9bae797 100644
--- a/contrib/python/ipython/py3/IPython/utils/io.py
+++ b/contrib/python/ipython/py3/IPython/utils/io.py
@@ -1,248 +1,248 @@
-# encoding: utf-8
-"""
-IO related utilities.
-"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-
-
-import atexit
-import os
-import sys
-import tempfile
-import warnings
-from warnings import warn
-
-from IPython.utils.decorators import undoc
-from .capture import CapturedIO, capture_output
-
-@undoc
-class IOStream:
-
- def __init__(self, stream, fallback=None):
- warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
- DeprecationWarning, stacklevel=2)
- if not hasattr(stream,'write') or not hasattr(stream,'flush'):
- if fallback is not None:
- stream = fallback
- else:
- raise ValueError("fallback required, but not specified")
- self.stream = stream
- self._swrite = stream.write
-
- # clone all methods not overridden:
- def clone(meth):
- return not hasattr(self, meth) and not meth.startswith('_')
- for meth in filter(clone, dir(stream)):
- try:
- val = getattr(stream, meth)
- except AttributeError:
- pass
- else:
- setattr(self, meth, val)
-
- def __repr__(self):
- cls = self.__class__
- tpl = '{mod}.{cls}({args})'
- return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
-
- def write(self,data):
- warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
- DeprecationWarning, stacklevel=2)
- try:
- self._swrite(data)
- except:
- try:
- # print handles some unicode issues which may trip a plain
- # write() call. Emulate write() by using an empty end
- # argument.
- print(data, end='', file=self.stream)
- except:
- # if we get here, something is seriously broken.
- print('ERROR - failed to write data to stream:', self.stream,
- file=sys.stderr)
-
- def writelines(self, lines):
- warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
- DeprecationWarning, stacklevel=2)
- if isinstance(lines, str):
- lines = [lines]
- for line in lines:
- self.write(line)
-
- # This class used to have a writeln method, but regular files and streams
- # in Python don't have this method. We need to keep this completely
- # compatible so we removed it.
-
- @property
- def closed(self):
- return self.stream.closed
-
- def close(self):
- pass
-
-# setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
-devnull = open(os.devnull, 'w')
-atexit.register(devnull.close)
-
-# io.std* are deprecated, but don't show our own deprecation warnings
-# during initialization of the deprecated API.
-with warnings.catch_warnings():
- warnings.simplefilter('ignore', DeprecationWarning)
- stdin = IOStream(sys.stdin, fallback=devnull)
- stdout = IOStream(sys.stdout, fallback=devnull)
- stderr = IOStream(sys.stderr, fallback=devnull)
-
-class Tee(object):
- """A class to duplicate an output stream to stdout/err.
-
- This works in a manner very similar to the Unix 'tee' command.
-
- When the object is closed or deleted, it closes the original file given to
- it for duplication.
- """
- # Inspired by:
- # http://mail.python.org/pipermail/python-list/2007-May/442737.html
-
- def __init__(self, file_or_name, mode="w", channel='stdout'):
- """Construct a new Tee object.
-
- Parameters
- ----------
- file_or_name : filename or open filehandle (writable)
- File that will be duplicated
-
- mode : optional, valid mode for open().
- If a filename was give, open with this mode.
-
- channel : str, one of ['stdout', 'stderr']
- """
- if channel not in ['stdout', 'stderr']:
- raise ValueError('Invalid channel spec %s' % channel)
-
- if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
- self.file = file_or_name
- else:
- self.file = open(file_or_name, mode)
- self.channel = channel
- self.ostream = getattr(sys, channel)
- setattr(sys, channel, self)
- self._closed = False
-
- def close(self):
- """Close the file and restore the channel."""
- self.flush()
- setattr(sys, self.channel, self.ostream)
- self.file.close()
- self._closed = True
-
- def write(self, data):
- """Write data to both channels."""
- self.file.write(data)
- self.ostream.write(data)
- self.ostream.flush()
-
- def flush(self):
- """Flush both channels."""
- self.file.flush()
- self.ostream.flush()
-
- def __del__(self):
- if not self._closed:
- self.close()
-
-
-def ask_yes_no(prompt, default=None, interrupt=None):
- """Asks a question and returns a boolean (y/n) answer.
-
- If default is given (one of 'y','n'), it is used if the user input is
- empty. If interrupt is given (one of 'y','n'), it is used if the user
- presses Ctrl-C. Otherwise the question is repeated until an answer is
- given.
-
- An EOF is treated as the default answer. If there is no default, an
- exception is raised to prevent infinite loops.
-
- Valid answers are: y/yes/n/no (match is not case sensitive)."""
-
- answers = {'y':True,'n':False,'yes':True,'no':False}
- ans = None
- while ans not in answers.keys():
- try:
- ans = input(prompt+' ').lower()
- if not ans: # response was an empty string
- ans = default
- except KeyboardInterrupt:
- if interrupt:
- ans = interrupt
- print("\r")
- except EOFError:
- if default in answers.keys():
- ans = default
- print()
- else:
- raise
-
- return answers[ans]
-
-
-def temp_pyfile(src, ext='.py'):
- """Make a temporary python file, return filename and filehandle.
-
- Parameters
- ----------
- src : string or list of strings (no need for ending newlines if list)
- Source code to be written to the file.
-
- ext : optional, string
- Extension for the generated file.
-
- Returns
- -------
- (filename, open filehandle)
- It is the caller's responsibility to close the open file and unlink it.
- """
- fname = tempfile.mkstemp(ext)[1]
- with open(fname,'w') as f:
- f.write(src)
- f.flush()
- return fname
-
-@undoc
-def atomic_writing(*args, **kwargs):
- """DEPRECATED: moved to notebook.services.contents.fileio"""
- warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio since IPython 4.0", DeprecationWarning, stacklevel=2)
- from notebook.services.contents.fileio import atomic_writing
- return atomic_writing(*args, **kwargs)
-
-@undoc
-def raw_print(*args, **kw):
- """DEPRECATED: Raw print to sys.__stdout__, otherwise identical interface to print()."""
- warn("IPython.utils.io.raw_print has been deprecated since IPython 7.0", DeprecationWarning, stacklevel=2)
-
- print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
- file=sys.__stdout__)
- sys.__stdout__.flush()
-
-@undoc
-def raw_print_err(*args, **kw):
- """DEPRECATED: Raw print to sys.__stderr__, otherwise identical interface to print()."""
- warn("IPython.utils.io.raw_print_err has been deprecated since IPython 7.0", DeprecationWarning, stacklevel=2)
-
- print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
- file=sys.__stderr__)
- sys.__stderr__.flush()
-
-# used by IPykernel <- 4.9. Removed during IPython 7-dev period and re-added
-# Keep for a version or two then should remove
-rprint = raw_print
-rprinte = raw_print_err
-
-@undoc
-def unicode_std_stream(stream='stdout'):
- """DEPRECATED, moved to nbconvert.utils.io"""
- warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io since IPython 4.0", DeprecationWarning, stacklevel=2)
- from nbconvert.utils.io import unicode_std_stream
- return unicode_std_stream(stream)
+# encoding: utf-8
+"""
+IO related utilities.
+"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+
+
+import atexit
+import os
+import sys
+import tempfile
+import warnings
+from warnings import warn
+
+from IPython.utils.decorators import undoc
+from .capture import CapturedIO, capture_output
+
+@undoc
+class IOStream:
+
+ def __init__(self, stream, fallback=None):
+ warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
+ DeprecationWarning, stacklevel=2)
+ if not hasattr(stream,'write') or not hasattr(stream,'flush'):
+ if fallback is not None:
+ stream = fallback
+ else:
+ raise ValueError("fallback required, but not specified")
+ self.stream = stream
+ self._swrite = stream.write
+
+ # clone all methods not overridden:
+ def clone(meth):
+ return not hasattr(self, meth) and not meth.startswith('_')
+ for meth in filter(clone, dir(stream)):
+ try:
+ val = getattr(stream, meth)
+ except AttributeError:
+ pass
+ else:
+ setattr(self, meth, val)
+
+ def __repr__(self):
+ cls = self.__class__
+ tpl = '{mod}.{cls}({args})'
+ return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
+
+ def write(self,data):
+ warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
+ DeprecationWarning, stacklevel=2)
+ try:
+ self._swrite(data)
+ except:
+ try:
+ # print handles some unicode issues which may trip a plain
+ # write() call. Emulate write() by using an empty end
+ # argument.
+ print(data, end='', file=self.stream)
+ except:
+ # if we get here, something is seriously broken.
+ print('ERROR - failed to write data to stream:', self.stream,
+ file=sys.stderr)
+
+ def writelines(self, lines):
+ warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
+ DeprecationWarning, stacklevel=2)
+ if isinstance(lines, str):
+ lines = [lines]
+ for line in lines:
+ self.write(line)
+
+ # This class used to have a writeln method, but regular files and streams
+ # in Python don't have this method. We need to keep this completely
+ # compatible so we removed it.
+
+ @property
+ def closed(self):
+ return self.stream.closed
+
+ def close(self):
+ pass
+
+# setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
+devnull = open(os.devnull, 'w')
+atexit.register(devnull.close)
+
+# io.std* are deprecated, but don't show our own deprecation warnings
+# during initialization of the deprecated API.
+with warnings.catch_warnings():
+ warnings.simplefilter('ignore', DeprecationWarning)
+ stdin = IOStream(sys.stdin, fallback=devnull)
+ stdout = IOStream(sys.stdout, fallback=devnull)
+ stderr = IOStream(sys.stderr, fallback=devnull)
+
+class Tee(object):
+ """A class to duplicate an output stream to stdout/err.
+
+ This works in a manner very similar to the Unix 'tee' command.
+
+ When the object is closed or deleted, it closes the original file given to
+ it for duplication.
+ """
+ # Inspired by:
+ # http://mail.python.org/pipermail/python-list/2007-May/442737.html
+
+ def __init__(self, file_or_name, mode="w", channel='stdout'):
+ """Construct a new Tee object.
+
+ Parameters
+ ----------
+ file_or_name : filename or open filehandle (writable)
+ File that will be duplicated
+
+ mode : optional, valid mode for open().
+ If a filename was give, open with this mode.
+
+ channel : str, one of ['stdout', 'stderr']
+ """
+ if channel not in ['stdout', 'stderr']:
+ raise ValueError('Invalid channel spec %s' % channel)
+
+ if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
+ self.file = file_or_name
+ else:
+ self.file = open(file_or_name, mode)
+ self.channel = channel
+ self.ostream = getattr(sys, channel)
+ setattr(sys, channel, self)
+ self._closed = False
+
+ def close(self):
+ """Close the file and restore the channel."""
+ self.flush()
+ setattr(sys, self.channel, self.ostream)
+ self.file.close()
+ self._closed = True
+
+ def write(self, data):
+ """Write data to both channels."""
+ self.file.write(data)
+ self.ostream.write(data)
+ self.ostream.flush()
+
+ def flush(self):
+ """Flush both channels."""
+ self.file.flush()
+ self.ostream.flush()
+
+ def __del__(self):
+ if not self._closed:
+ self.close()
+
+
+def ask_yes_no(prompt, default=None, interrupt=None):
+ """Asks a question and returns a boolean (y/n) answer.
+
+ If default is given (one of 'y','n'), it is used if the user input is
+ empty. If interrupt is given (one of 'y','n'), it is used if the user
+ presses Ctrl-C. Otherwise the question is repeated until an answer is
+ given.
+
+ An EOF is treated as the default answer. If there is no default, an
+ exception is raised to prevent infinite loops.
+
+ Valid answers are: y/yes/n/no (match is not case sensitive)."""
+
+ answers = {'y':True,'n':False,'yes':True,'no':False}
+ ans = None
+ while ans not in answers.keys():
+ try:
+ ans = input(prompt+' ').lower()
+ if not ans: # response was an empty string
+ ans = default
+ except KeyboardInterrupt:
+ if interrupt:
+ ans = interrupt
+ print("\r")
+ except EOFError:
+ if default in answers.keys():
+ ans = default
+ print()
+ else:
+ raise
+
+ return answers[ans]
+
+
+def temp_pyfile(src, ext='.py'):
+ """Make a temporary python file, return filename and filehandle.
+
+ Parameters
+ ----------
+ src : string or list of strings (no need for ending newlines if list)
+ Source code to be written to the file.
+
+ ext : optional, string
+ Extension for the generated file.
+
+ Returns
+ -------
+ (filename, open filehandle)
+ It is the caller's responsibility to close the open file and unlink it.
+ """
+ fname = tempfile.mkstemp(ext)[1]
+ with open(fname,'w') as f:
+ f.write(src)
+ f.flush()
+ return fname
+
+@undoc
+def atomic_writing(*args, **kwargs):
+ """DEPRECATED: moved to notebook.services.contents.fileio"""
+ warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio since IPython 4.0", DeprecationWarning, stacklevel=2)
+ from notebook.services.contents.fileio import atomic_writing
+ return atomic_writing(*args, **kwargs)
+
+@undoc
+def raw_print(*args, **kw):
+ """DEPRECATED: Raw print to sys.__stdout__, otherwise identical interface to print()."""
+ warn("IPython.utils.io.raw_print has been deprecated since IPython 7.0", DeprecationWarning, stacklevel=2)
+
+ print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
+ file=sys.__stdout__)
+ sys.__stdout__.flush()
+
+@undoc
+def raw_print_err(*args, **kw):
+ """DEPRECATED: Raw print to sys.__stderr__, otherwise identical interface to print()."""
+ warn("IPython.utils.io.raw_print_err has been deprecated since IPython 7.0", DeprecationWarning, stacklevel=2)
+
+ print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
+ file=sys.__stderr__)
+ sys.__stderr__.flush()
+
+# used by IPykernel <- 4.9. Removed during IPython 7-dev period and re-added
+# Keep for a version or two then should remove
+rprint = raw_print
+rprinte = raw_print_err
+
+@undoc
+def unicode_std_stream(stream='stdout'):
+ """DEPRECATED, moved to nbconvert.utils.io"""
+ warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io since IPython 4.0", DeprecationWarning, stacklevel=2)
+ from nbconvert.utils.io import unicode_std_stream
+ return unicode_std_stream(stream)
diff --git a/contrib/python/ipython/py3/IPython/utils/ipstruct.py b/contrib/python/ipython/py3/IPython/utils/ipstruct.py
index e17760b4f9..e2b3e8fa4c 100644
--- a/contrib/python/ipython/py3/IPython/utils/ipstruct.py
+++ b/contrib/python/ipython/py3/IPython/utils/ipstruct.py
@@ -1,391 +1,391 @@
-# encoding: utf-8
-"""A dict subclass that supports attribute style access.
-
-Authors:
-
-* Fernando Perez (original)
-* Brian Granger (refactoring to a dict subclass)
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-__all__ = ['Struct']
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-
-
-class Struct(dict):
- """A dict subclass with attribute style access.
-
- This dict subclass has a a few extra features:
-
- * Attribute style access.
- * Protection of class members (like keys, items) when using attribute
- style access.
- * The ability to restrict assignment to only existing keys.
- * Intelligent merging.
- * Overloaded operators.
- """
- _allownew = True
- def __init__(self, *args, **kw):
- """Initialize with a dictionary, another Struct, or data.
-
- Parameters
- ----------
- args : dict, Struct
- Initialize with one dict or Struct
- kw : dict
- Initialize with key, value pairs.
-
- Examples
- --------
-
- >>> s = Struct(a=10,b=30)
- >>> s.a
- 10
- >>> s.b
- 30
- >>> s2 = Struct(s,c=30)
- >>> sorted(s2.keys())
- ['a', 'b', 'c']
- """
- object.__setattr__(self, '_allownew', True)
- dict.__init__(self, *args, **kw)
-
- def __setitem__(self, key, value):
- """Set an item with check for allownew.
-
- Examples
- --------
-
- >>> s = Struct()
- >>> s['a'] = 10
- >>> s.allow_new_attr(False)
- >>> s['a'] = 10
- >>> s['a']
- 10
- >>> try:
- ... s['b'] = 20
- ... except KeyError:
- ... print('this is not allowed')
- ...
- this is not allowed
- """
- if not self._allownew and key not in self:
- raise KeyError(
- "can't create new attribute %s when allow_new_attr(False)" % key)
- dict.__setitem__(self, key, value)
-
- def __setattr__(self, key, value):
- """Set an attr with protection of class members.
-
- This calls :meth:`self.__setitem__` but convert :exc:`KeyError` to
- :exc:`AttributeError`.
-
- Examples
- --------
-
- >>> s = Struct()
- >>> s.a = 10
- >>> s.a
- 10
- >>> try:
- ... s.get = 10
- ... except AttributeError:
- ... print("you can't set a class member")
- ...
- you can't set a class member
- """
- # If key is an str it might be a class member or instance var
- if isinstance(key, str):
- # I can't simply call hasattr here because it calls getattr, which
- # calls self.__getattr__, which returns True for keys in
- # self._data. But I only want keys in the class and in
- # self.__dict__
- if key in self.__dict__ or hasattr(Struct, key):
- raise AttributeError(
- 'attr %s is a protected member of class Struct.' % key
- )
- try:
- self.__setitem__(key, value)
- except KeyError as e:
- raise AttributeError(e)
-
- def __getattr__(self, key):
- """Get an attr by calling :meth:`dict.__getitem__`.
-
- Like :meth:`__setattr__`, this method converts :exc:`KeyError` to
- :exc:`AttributeError`.
-
- Examples
- --------
-
- >>> s = Struct(a=10)
- >>> s.a
- 10
- >>> type(s.get)
- <... 'builtin_function_or_method'>
- >>> try:
- ... s.b
- ... except AttributeError:
- ... print("I don't have that key")
- ...
- I don't have that key
- """
- try:
- result = self[key]
- except KeyError:
- raise AttributeError(key)
- else:
- return result
-
- def __iadd__(self, other):
- """s += s2 is a shorthand for s.merge(s2).
-
- Examples
- --------
-
- >>> s = Struct(a=10,b=30)
- >>> s2 = Struct(a=20,c=40)
- >>> s += s2
- >>> sorted(s.keys())
- ['a', 'b', 'c']
- """
- self.merge(other)
- return self
-
- def __add__(self,other):
- """s + s2 -> New Struct made from s.merge(s2).
-
- Examples
- --------
-
- >>> s1 = Struct(a=10,b=30)
- >>> s2 = Struct(a=20,c=40)
- >>> s = s1 + s2
- >>> sorted(s.keys())
- ['a', 'b', 'c']
- """
- sout = self.copy()
- sout.merge(other)
- return sout
-
- def __sub__(self,other):
- """s1 - s2 -> remove keys in s2 from s1.
-
- Examples
- --------
-
- >>> s1 = Struct(a=10,b=30)
- >>> s2 = Struct(a=40)
- >>> s = s1 - s2
- >>> s
- {'b': 30}
- """
- sout = self.copy()
- sout -= other
- return sout
-
- def __isub__(self,other):
- """Inplace remove keys from self that are in other.
-
- Examples
- --------
-
- >>> s1 = Struct(a=10,b=30)
- >>> s2 = Struct(a=40)
- >>> s1 -= s2
- >>> s1
- {'b': 30}
- """
- for k in other.keys():
- if k in self:
- del self[k]
- return self
-
- def __dict_invert(self, data):
- """Helper function for merge.
-
- Takes a dictionary whose values are lists and returns a dict with
- the elements of each list as keys and the original keys as values.
- """
- outdict = {}
- for k,lst in data.items():
- if isinstance(lst, str):
- lst = lst.split()
- for entry in lst:
- outdict[entry] = k
- return outdict
-
- def dict(self):
- return self
-
- def copy(self):
- """Return a copy as a Struct.
-
- Examples
- --------
-
- >>> s = Struct(a=10,b=30)
- >>> s2 = s.copy()
- >>> type(s2) is Struct
- True
- """
- return Struct(dict.copy(self))
-
- def hasattr(self, key):
- """hasattr function available as a method.
-
- Implemented like has_key.
-
- Examples
- --------
-
- >>> s = Struct(a=10)
- >>> s.hasattr('a')
- True
- >>> s.hasattr('b')
- False
- >>> s.hasattr('get')
- False
- """
- return key in self
-
- def allow_new_attr(self, allow = True):
- """Set whether new attributes can be created in this Struct.
-
- This can be used to catch typos by verifying that the attribute user
- tries to change already exists in this Struct.
- """
- object.__setattr__(self, '_allownew', allow)
-
- def merge(self, __loc_data__=None, __conflict_solve=None, **kw):
- """Merge two Structs with customizable conflict resolution.
-
- This is similar to :meth:`update`, but much more flexible. First, a
- dict is made from data+key=value pairs. When merging this dict with
- the Struct S, the optional dictionary 'conflict' is used to decide
- what to do.
-
- If conflict is not given, the default behavior is to preserve any keys
- with their current value (the opposite of the :meth:`update` method's
- behavior).
-
- Parameters
- ----------
- __loc_data : dict, Struct
- The data to merge into self
- __conflict_solve : dict
- The conflict policy dict. The keys are binary functions used to
- resolve the conflict and the values are lists of strings naming
- the keys the conflict resolution function applies to. Instead of
- a list of strings a space separated string can be used, like
- 'a b c'.
- kw : dict
- Additional key, value pairs to merge in
-
- Notes
- -----
-
- The `__conflict_solve` dict is a dictionary of binary functions which will be used to
- solve key conflicts. Here is an example::
-
- __conflict_solve = dict(
- func1=['a','b','c'],
- func2=['d','e']
- )
-
- In this case, the function :func:`func1` will be used to resolve
- keys 'a', 'b' and 'c' and the function :func:`func2` will be used for
- keys 'd' and 'e'. This could also be written as::
-
- __conflict_solve = dict(func1='a b c',func2='d e')
-
- These functions will be called for each key they apply to with the
- form::
-
- func1(self['a'], other['a'])
-
- The return value is used as the final merged value.
-
- As a convenience, merge() provides five (the most commonly needed)
- pre-defined policies: preserve, update, add, add_flip and add_s. The
- easiest explanation is their implementation::
-
- preserve = lambda old,new: old
- update = lambda old,new: new
- add = lambda old,new: old + new
- add_flip = lambda old,new: new + old # note change of order!
- add_s = lambda old,new: old + ' ' + new # only for str!
-
- You can use those four words (as strings) as keys instead
- of defining them as functions, and the merge method will substitute
- the appropriate functions for you.
-
- For more complicated conflict resolution policies, you still need to
- construct your own functions.
-
- Examples
- --------
-
- This show the default policy:
-
- >>> s = Struct(a=10,b=30)
- >>> s2 = Struct(a=20,c=40)
- >>> s.merge(s2)
- >>> sorted(s.items())
- [('a', 10), ('b', 30), ('c', 40)]
-
- Now, show how to specify a conflict dict:
-
- >>> s = Struct(a=10,b=30)
- >>> s2 = Struct(a=20,b=40)
- >>> conflict = {'update':'a','add':'b'}
- >>> s.merge(s2,conflict)
- >>> sorted(s.items())
- [('a', 20), ('b', 70)]
- """
-
- data_dict = dict(__loc_data__,**kw)
-
- # policies for conflict resolution: two argument functions which return
- # the value that will go in the new struct
- preserve = lambda old,new: old
- update = lambda old,new: new
- add = lambda old,new: old + new
- add_flip = lambda old,new: new + old # note change of order!
- add_s = lambda old,new: old + ' ' + new
-
- # default policy is to keep current keys when there's a conflict
- conflict_solve = dict.fromkeys(self, preserve)
-
- # the conflict_solve dictionary is given by the user 'inverted': we
- # need a name-function mapping, it comes as a function -> names
- # dict. Make a local copy (b/c we'll make changes), replace user
- # strings for the three builtin policies and invert it.
- if __conflict_solve:
- inv_conflict_solve_user = __conflict_solve.copy()
- for name, func in [('preserve',preserve), ('update',update),
- ('add',add), ('add_flip',add_flip),
- ('add_s',add_s)]:
- if name in inv_conflict_solve_user.keys():
- inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
- del inv_conflict_solve_user[name]
- conflict_solve.update(self.__dict_invert(inv_conflict_solve_user))
- for key in data_dict:
- if key not in self:
- self[key] = data_dict[key]
- else:
- self[key] = conflict_solve[key](self[key],data_dict[key])
-
+# encoding: utf-8
+"""A dict subclass that supports attribute style access.
+
+Authors:
+
+* Fernando Perez (original)
+* Brian Granger (refactoring to a dict subclass)
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+__all__ = ['Struct']
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+
+class Struct(dict):
+ """A dict subclass with attribute style access.
+
+ This dict subclass has a a few extra features:
+
+ * Attribute style access.
+ * Protection of class members (like keys, items) when using attribute
+ style access.
+ * The ability to restrict assignment to only existing keys.
+ * Intelligent merging.
+ * Overloaded operators.
+ """
+ _allownew = True
+ def __init__(self, *args, **kw):
+ """Initialize with a dictionary, another Struct, or data.
+
+ Parameters
+ ----------
+ args : dict, Struct
+ Initialize with one dict or Struct
+ kw : dict
+ Initialize with key, value pairs.
+
+ Examples
+ --------
+
+ >>> s = Struct(a=10,b=30)
+ >>> s.a
+ 10
+ >>> s.b
+ 30
+ >>> s2 = Struct(s,c=30)
+ >>> sorted(s2.keys())
+ ['a', 'b', 'c']
+ """
+ object.__setattr__(self, '_allownew', True)
+ dict.__init__(self, *args, **kw)
+
+ def __setitem__(self, key, value):
+ """Set an item with check for allownew.
+
+ Examples
+ --------
+
+ >>> s = Struct()
+ >>> s['a'] = 10
+ >>> s.allow_new_attr(False)
+ >>> s['a'] = 10
+ >>> s['a']
+ 10
+ >>> try:
+ ... s['b'] = 20
+ ... except KeyError:
+ ... print('this is not allowed')
+ ...
+ this is not allowed
+ """
+ if not self._allownew and key not in self:
+ raise KeyError(
+ "can't create new attribute %s when allow_new_attr(False)" % key)
+ dict.__setitem__(self, key, value)
+
+ def __setattr__(self, key, value):
+ """Set an attr with protection of class members.
+
+ This calls :meth:`self.__setitem__` but convert :exc:`KeyError` to
+ :exc:`AttributeError`.
+
+ Examples
+ --------
+
+ >>> s = Struct()
+ >>> s.a = 10
+ >>> s.a
+ 10
+ >>> try:
+ ... s.get = 10
+ ... except AttributeError:
+ ... print("you can't set a class member")
+ ...
+ you can't set a class member
+ """
+ # If key is an str it might be a class member or instance var
+ if isinstance(key, str):
+ # I can't simply call hasattr here because it calls getattr, which
+ # calls self.__getattr__, which returns True for keys in
+ # self._data. But I only want keys in the class and in
+ # self.__dict__
+ if key in self.__dict__ or hasattr(Struct, key):
+ raise AttributeError(
+ 'attr %s is a protected member of class Struct.' % key
+ )
+ try:
+ self.__setitem__(key, value)
+ except KeyError as e:
+ raise AttributeError(e)
+
+ def __getattr__(self, key):
+ """Get an attr by calling :meth:`dict.__getitem__`.
+
+ Like :meth:`__setattr__`, this method converts :exc:`KeyError` to
+ :exc:`AttributeError`.
+
+ Examples
+ --------
+
+ >>> s = Struct(a=10)
+ >>> s.a
+ 10
+ >>> type(s.get)
+ <... 'builtin_function_or_method'>
+ >>> try:
+ ... s.b
+ ... except AttributeError:
+ ... print("I don't have that key")
+ ...
+ I don't have that key
+ """
+ try:
+ result = self[key]
+ except KeyError:
+ raise AttributeError(key)
+ else:
+ return result
+
+ def __iadd__(self, other):
+ """s += s2 is a shorthand for s.merge(s2).
+
+ Examples
+ --------
+
+ >>> s = Struct(a=10,b=30)
+ >>> s2 = Struct(a=20,c=40)
+ >>> s += s2
+ >>> sorted(s.keys())
+ ['a', 'b', 'c']
+ """
+ self.merge(other)
+ return self
+
+ def __add__(self,other):
+ """s + s2 -> New Struct made from s.merge(s2).
+
+ Examples
+ --------
+
+ >>> s1 = Struct(a=10,b=30)
+ >>> s2 = Struct(a=20,c=40)
+ >>> s = s1 + s2
+ >>> sorted(s.keys())
+ ['a', 'b', 'c']
+ """
+ sout = self.copy()
+ sout.merge(other)
+ return sout
+
+ def __sub__(self,other):
+ """s1 - s2 -> remove keys in s2 from s1.
+
+ Examples
+ --------
+
+ >>> s1 = Struct(a=10,b=30)
+ >>> s2 = Struct(a=40)
+ >>> s = s1 - s2
+ >>> s
+ {'b': 30}
+ """
+ sout = self.copy()
+ sout -= other
+ return sout
+
+ def __isub__(self,other):
+ """Inplace remove keys from self that are in other.
+
+ Examples
+ --------
+
+ >>> s1 = Struct(a=10,b=30)
+ >>> s2 = Struct(a=40)
+ >>> s1 -= s2
+ >>> s1
+ {'b': 30}
+ """
+ for k in other.keys():
+ if k in self:
+ del self[k]
+ return self
+
+ def __dict_invert(self, data):
+ """Helper function for merge.
+
+ Takes a dictionary whose values are lists and returns a dict with
+ the elements of each list as keys and the original keys as values.
+ """
+ outdict = {}
+ for k,lst in data.items():
+ if isinstance(lst, str):
+ lst = lst.split()
+ for entry in lst:
+ outdict[entry] = k
+ return outdict
+
+ def dict(self):
+ return self
+
+ def copy(self):
+ """Return a copy as a Struct.
+
+ Examples
+ --------
+
+ >>> s = Struct(a=10,b=30)
+ >>> s2 = s.copy()
+ >>> type(s2) is Struct
+ True
+ """
+ return Struct(dict.copy(self))
+
+ def hasattr(self, key):
+ """hasattr function available as a method.
+
+ Implemented like has_key.
+
+ Examples
+ --------
+
+ >>> s = Struct(a=10)
+ >>> s.hasattr('a')
+ True
+ >>> s.hasattr('b')
+ False
+ >>> s.hasattr('get')
+ False
+ """
+ return key in self
+
+ def allow_new_attr(self, allow = True):
+ """Set whether new attributes can be created in this Struct.
+
+ This can be used to catch typos by verifying that the attribute user
+ tries to change already exists in this Struct.
+ """
+ object.__setattr__(self, '_allownew', allow)
+
+ def merge(self, __loc_data__=None, __conflict_solve=None, **kw):
+ """Merge two Structs with customizable conflict resolution.
+
+ This is similar to :meth:`update`, but much more flexible. First, a
+ dict is made from data+key=value pairs. When merging this dict with
+ the Struct S, the optional dictionary 'conflict' is used to decide
+ what to do.
+
+ If conflict is not given, the default behavior is to preserve any keys
+ with their current value (the opposite of the :meth:`update` method's
+ behavior).
+
+ Parameters
+ ----------
+ __loc_data : dict, Struct
+ The data to merge into self
+ __conflict_solve : dict
+ The conflict policy dict. The keys are binary functions used to
+ resolve the conflict and the values are lists of strings naming
+ the keys the conflict resolution function applies to. Instead of
+ a list of strings a space separated string can be used, like
+ 'a b c'.
+ kw : dict
+ Additional key, value pairs to merge in
+
+ Notes
+ -----
+
+ The `__conflict_solve` dict is a dictionary of binary functions which will be used to
+ solve key conflicts. Here is an example::
+
+ __conflict_solve = dict(
+ func1=['a','b','c'],
+ func2=['d','e']
+ )
+
+ In this case, the function :func:`func1` will be used to resolve
+ keys 'a', 'b' and 'c' and the function :func:`func2` will be used for
+ keys 'd' and 'e'. This could also be written as::
+
+ __conflict_solve = dict(func1='a b c',func2='d e')
+
+ These functions will be called for each key they apply to with the
+ form::
+
+ func1(self['a'], other['a'])
+
+ The return value is used as the final merged value.
+
+ As a convenience, merge() provides five (the most commonly needed)
+ pre-defined policies: preserve, update, add, add_flip and add_s. The
+ easiest explanation is their implementation::
+
+ preserve = lambda old,new: old
+ update = lambda old,new: new
+ add = lambda old,new: old + new
+ add_flip = lambda old,new: new + old # note change of order!
+ add_s = lambda old,new: old + ' ' + new # only for str!
+
+ You can use those four words (as strings) as keys instead
+ of defining them as functions, and the merge method will substitute
+ the appropriate functions for you.
+
+ For more complicated conflict resolution policies, you still need to
+ construct your own functions.
+
+ Examples
+ --------
+
+ This show the default policy:
+
+ >>> s = Struct(a=10,b=30)
+ >>> s2 = Struct(a=20,c=40)
+ >>> s.merge(s2)
+ >>> sorted(s.items())
+ [('a', 10), ('b', 30), ('c', 40)]
+
+ Now, show how to specify a conflict dict:
+
+ >>> s = Struct(a=10,b=30)
+ >>> s2 = Struct(a=20,b=40)
+ >>> conflict = {'update':'a','add':'b'}
+ >>> s.merge(s2,conflict)
+ >>> sorted(s.items())
+ [('a', 20), ('b', 70)]
+ """
+
+ data_dict = dict(__loc_data__,**kw)
+
+ # policies for conflict resolution: two argument functions which return
+ # the value that will go in the new struct
+ preserve = lambda old,new: old
+ update = lambda old,new: new
+ add = lambda old,new: old + new
+ add_flip = lambda old,new: new + old # note change of order!
+ add_s = lambda old,new: old + ' ' + new
+
+ # default policy is to keep current keys when there's a conflict
+ conflict_solve = dict.fromkeys(self, preserve)
+
+ # the conflict_solve dictionary is given by the user 'inverted': we
+ # need a name-function mapping, it comes as a function -> names
+ # dict. Make a local copy (b/c we'll make changes), replace user
+ # strings for the three builtin policies and invert it.
+ if __conflict_solve:
+ inv_conflict_solve_user = __conflict_solve.copy()
+ for name, func in [('preserve',preserve), ('update',update),
+ ('add',add), ('add_flip',add_flip),
+ ('add_s',add_s)]:
+ if name in inv_conflict_solve_user.keys():
+ inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
+ del inv_conflict_solve_user[name]
+ conflict_solve.update(self.__dict_invert(inv_conflict_solve_user))
+ for key in data_dict:
+ if key not in self:
+ self[key] = data_dict[key]
+ else:
+ self[key] = conflict_solve[key](self[key],data_dict[key])
+
diff --git a/contrib/python/ipython/py3/IPython/utils/jsonutil.py b/contrib/python/ipython/py3/IPython/utils/jsonutil.py
index 359633ed6d..2672e09e16 100644
--- a/contrib/python/ipython/py3/IPython/utils/jsonutil.py
+++ b/contrib/python/ipython/py3/IPython/utils/jsonutil.py
@@ -1,5 +1,5 @@
-from warnings import warn
-
-warn("IPython.utils.jsonutil has moved to jupyter_client.jsonutil", stacklevel=2)
-
-from jupyter_client.jsonutil import *
+from warnings import warn
+
+warn("IPython.utils.jsonutil has moved to jupyter_client.jsonutil", stacklevel=2)
+
+from jupyter_client.jsonutil import *
diff --git a/contrib/python/ipython/py3/IPython/utils/localinterfaces.py b/contrib/python/ipython/py3/IPython/utils/localinterfaces.py
index 716d0918ed..2f911222d8 100644
--- a/contrib/python/ipython/py3/IPython/utils/localinterfaces.py
+++ b/contrib/python/ipython/py3/IPython/utils/localinterfaces.py
@@ -1,5 +1,5 @@
-from warnings import warn
-
-warn("IPython.utils.localinterfaces has moved to jupyter_client.localinterfaces", stacklevel=2)
-
-from jupyter_client.localinterfaces import *
+from warnings import warn
+
+warn("IPython.utils.localinterfaces has moved to jupyter_client.localinterfaces", stacklevel=2)
+
+from jupyter_client.localinterfaces import *
diff --git a/contrib/python/ipython/py3/IPython/utils/log.py b/contrib/python/ipython/py3/IPython/utils/log.py
index f9e12281b0..bb262eda93 100644
--- a/contrib/python/ipython/py3/IPython/utils/log.py
+++ b/contrib/python/ipython/py3/IPython/utils/log.py
@@ -1,6 +1,6 @@
-
-from warnings import warn
-
-warn("IPython.utils.log has moved to traitlets.log", stacklevel=2)
-
-from traitlets.log import *
+
+from warnings import warn
+
+warn("IPython.utils.log has moved to traitlets.log", stacklevel=2)
+
+from traitlets.log import *
diff --git a/contrib/python/ipython/py3/IPython/utils/module_paths.py b/contrib/python/ipython/py3/IPython/utils/module_paths.py
index 2184884335..0570c322e6 100644
--- a/contrib/python/ipython/py3/IPython/utils/module_paths.py
+++ b/contrib/python/ipython/py3/IPython/utils/module_paths.py
@@ -1,70 +1,70 @@
-"""Utility functions for finding modules
-
-Utility functions for finding modules on sys.path.
-
-`find_module` returns a path to module or None, given certain conditions.
-
-"""
-#-----------------------------------------------------------------------------
-# Copyright (c) 2011, the IPython Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-# Stdlib imports
-import importlib
-import os
-
-# Third-party imports
-
-# Our own imports
-
-
-#-----------------------------------------------------------------------------
-# Globals and constants
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Local utilities
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Classes and functions
-#-----------------------------------------------------------------------------
-
-def find_mod(module_name):
- """
- Find module `module_name` on sys.path, and return the path to module `module_name`.
-
- - If `module_name` refers to a module directory, then return path to __init__ file.
- - If `module_name` is a directory without an __init__file, return None.
- - If module is missing or does not have a `.py` or `.pyw` extension, return None.
- - Note that we are not interested in running bytecode.
- - Otherwise, return the fill path of the module.
-
- Parameters
- ----------
- module_name : str
-
- Returns
- -------
- module_path : str
- Path to module `module_name`, its __init__.py, or None,
- depending on above conditions.
- """
- loader = importlib.util.find_spec(module_name)
- module_path = loader.origin
- if module_path is None:
- return None
- else:
- split_path = module_path.split(".")
- if split_path[-1] in ["py", "pyw"]:
- return module_path
- else:
- return None
+"""Utility functions for finding modules
+
+Utility functions for finding modules on sys.path.
+
+`find_module` returns a path to module or None, given certain conditions.
+
+"""
+#-----------------------------------------------------------------------------
+# Copyright (c) 2011, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+# Stdlib imports
+import importlib
+import os
+
+# Third-party imports
+
+# Our own imports
+
+
+#-----------------------------------------------------------------------------
+# Globals and constants
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Local utilities
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Classes and functions
+#-----------------------------------------------------------------------------
+
+def find_mod(module_name):
+ """
+ Find module `module_name` on sys.path, and return the path to module `module_name`.
+
+ - If `module_name` refers to a module directory, then return path to __init__ file.
+ - If `module_name` is a directory without an __init__file, return None.
+ - If module is missing or does not have a `.py` or `.pyw` extension, return None.
+ - Note that we are not interested in running bytecode.
+ - Otherwise, return the fill path of the module.
+
+ Parameters
+ ----------
+ module_name : str
+
+ Returns
+ -------
+ module_path : str
+ Path to module `module_name`, its __init__.py, or None,
+ depending on above conditions.
+ """
+ loader = importlib.util.find_spec(module_name)
+ module_path = loader.origin
+ if module_path is None:
+ return None
+ else:
+ split_path = module_path.split(".")
+ if split_path[-1] in ["py", "pyw"]:
+ return module_path
+ else:
+ return None
diff --git a/contrib/python/ipython/py3/IPython/utils/openpy.py b/contrib/python/ipython/py3/IPython/utils/openpy.py
index 75f4601a1f..c90d2b53a3 100644
--- a/contrib/python/ipython/py3/IPython/utils/openpy.py
+++ b/contrib/python/ipython/py3/IPython/utils/openpy.py
@@ -1,103 +1,103 @@
-"""
-Tools to open .py files as Unicode, using the encoding specified within the file,
-as per PEP 263.
-
-Much of the code is taken from the tokenize module in Python 3.2.
-"""
-
-import io
-from io import TextIOWrapper, BytesIO
-import re
-from tokenize import open, detect_encoding
-
-cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)", re.UNICODE)
-cookie_comment_re = re.compile(r"^\s*#.*coding[:=]\s*([-\w.]+)", re.UNICODE)
-
-def source_to_unicode(txt, errors='replace', skip_encoding_cookie=True):
- """Converts a bytes string with python source code to unicode.
-
- Unicode strings are passed through unchanged. Byte strings are checked
- for the python source file encoding cookie to determine encoding.
- txt can be either a bytes buffer or a string containing the source
- code.
- """
- if isinstance(txt, str):
- return txt
- if isinstance(txt, bytes):
- buffer = BytesIO(txt)
- else:
- buffer = txt
- try:
- encoding, _ = detect_encoding(buffer.readline)
- except SyntaxError:
- encoding = "ascii"
- buffer.seek(0)
- with TextIOWrapper(buffer, encoding, errors=errors, line_buffering=True) as text:
- text.mode = 'r'
- if skip_encoding_cookie:
- return u"".join(strip_encoding_cookie(text))
- else:
- return text.read()
-
-def strip_encoding_cookie(filelike):
- """Generator to pull lines from a text-mode file, skipping the encoding
- cookie if it is found in the first two lines.
- """
- it = iter(filelike)
- try:
- first = next(it)
- if not cookie_comment_re.match(first):
- yield first
- second = next(it)
- if not cookie_comment_re.match(second):
- yield second
- except StopIteration:
- return
-
- for line in it:
- yield line
-
-def read_py_file(filename, skip_encoding_cookie=True):
- """Read a Python file, using the encoding declared inside the file.
-
- Parameters
- ----------
- filename : str
- The path to the file to read.
- skip_encoding_cookie : bool
- If True (the default), and the encoding declaration is found in the first
- two lines, that line will be excluded from the output.
-
- Returns
- -------
- A unicode string containing the contents of the file.
- """
- with open(filename) as f: # the open function defined in this module.
- if skip_encoding_cookie:
- return "".join(strip_encoding_cookie(f))
- else:
- return f.read()
-
-def read_py_url(url, errors='replace', skip_encoding_cookie=True):
- """Read a Python file from a URL, using the encoding declared inside the file.
-
- Parameters
- ----------
- url : str
- The URL from which to fetch the file.
- errors : str
- How to handle decoding errors in the file. Options are the same as for
- bytes.decode(), but here 'replace' is the default.
- skip_encoding_cookie : bool
- If True (the default), and the encoding declaration is found in the first
- two lines, that line will be excluded from the output.
-
- Returns
- -------
- A unicode string containing the contents of the file.
- """
- # Deferred import for faster start
- from urllib.request import urlopen
- response = urlopen(url)
- buffer = io.BytesIO(response.read())
- return source_to_unicode(buffer, errors, skip_encoding_cookie)
+"""
+Tools to open .py files as Unicode, using the encoding specified within the file,
+as per PEP 263.
+
+Much of the code is taken from the tokenize module in Python 3.2.
+"""
+
+import io
+from io import TextIOWrapper, BytesIO
+import re
+from tokenize import open, detect_encoding
+
+cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)", re.UNICODE)
+cookie_comment_re = re.compile(r"^\s*#.*coding[:=]\s*([-\w.]+)", re.UNICODE)
+
+def source_to_unicode(txt, errors='replace', skip_encoding_cookie=True):
+ """Converts a bytes string with python source code to unicode.
+
+ Unicode strings are passed through unchanged. Byte strings are checked
+ for the python source file encoding cookie to determine encoding.
+ txt can be either a bytes buffer or a string containing the source
+ code.
+ """
+ if isinstance(txt, str):
+ return txt
+ if isinstance(txt, bytes):
+ buffer = BytesIO(txt)
+ else:
+ buffer = txt
+ try:
+ encoding, _ = detect_encoding(buffer.readline)
+ except SyntaxError:
+ encoding = "ascii"
+ buffer.seek(0)
+ with TextIOWrapper(buffer, encoding, errors=errors, line_buffering=True) as text:
+ text.mode = 'r'
+ if skip_encoding_cookie:
+ return u"".join(strip_encoding_cookie(text))
+ else:
+ return text.read()
+
+def strip_encoding_cookie(filelike):
+ """Generator to pull lines from a text-mode file, skipping the encoding
+ cookie if it is found in the first two lines.
+ """
+ it = iter(filelike)
+ try:
+ first = next(it)
+ if not cookie_comment_re.match(first):
+ yield first
+ second = next(it)
+ if not cookie_comment_re.match(second):
+ yield second
+ except StopIteration:
+ return
+
+ for line in it:
+ yield line
+
+def read_py_file(filename, skip_encoding_cookie=True):
+ """Read a Python file, using the encoding declared inside the file.
+
+ Parameters
+ ----------
+ filename : str
+ The path to the file to read.
+ skip_encoding_cookie : bool
+ If True (the default), and the encoding declaration is found in the first
+ two lines, that line will be excluded from the output.
+
+ Returns
+ -------
+ A unicode string containing the contents of the file.
+ """
+ with open(filename) as f: # the open function defined in this module.
+ if skip_encoding_cookie:
+ return "".join(strip_encoding_cookie(f))
+ else:
+ return f.read()
+
+def read_py_url(url, errors='replace', skip_encoding_cookie=True):
+ """Read a Python file from a URL, using the encoding declared inside the file.
+
+ Parameters
+ ----------
+ url : str
+ The URL from which to fetch the file.
+ errors : str
+ How to handle decoding errors in the file. Options are the same as for
+ bytes.decode(), but here 'replace' is the default.
+ skip_encoding_cookie : bool
+ If True (the default), and the encoding declaration is found in the first
+ two lines, that line will be excluded from the output.
+
+ Returns
+ -------
+ A unicode string containing the contents of the file.
+ """
+ # Deferred import for faster start
+ from urllib.request import urlopen
+ response = urlopen(url)
+ buffer = io.BytesIO(response.read())
+ return source_to_unicode(buffer, errors, skip_encoding_cookie)
diff --git a/contrib/python/ipython/py3/IPython/utils/path.py b/contrib/python/ipython/py3/IPython/utils/path.py
index de88872f85..0fb6144e19 100644
--- a/contrib/python/ipython/py3/IPython/utils/path.py
+++ b/contrib/python/ipython/py3/IPython/utils/path.py
@@ -1,436 +1,436 @@
-# encoding: utf-8
-"""
-Utilities for path handling.
-"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-import os
-import sys
-import errno
-import shutil
-import random
-import glob
-from warnings import warn
-
-from IPython.utils.process import system
-from IPython.utils.decorators import undoc
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-fs_encoding = sys.getfilesystemencoding()
-
-def _writable_dir(path):
- """Whether `path` is a directory, to which the user has write access."""
- return os.path.isdir(path) and os.access(path, os.W_OK)
-
-if sys.platform == 'win32':
- def _get_long_path_name(path):
- """Get a long path name (expand ~) on Windows using ctypes.
-
- Examples
- --------
-
- >>> get_long_path_name('c:\\docume~1')
- 'c:\\\\Documents and Settings'
-
- """
- try:
- import ctypes
- except ImportError:
- raise ImportError('you need to have ctypes installed for this to work')
- _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
- _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
- ctypes.c_uint ]
-
- buf = ctypes.create_unicode_buffer(260)
- rv = _GetLongPathName(path, buf, 260)
- if rv == 0 or rv > 260:
- return path
- else:
- return buf.value
-else:
- def _get_long_path_name(path):
- """Dummy no-op."""
- return path
-
-
-
-def get_long_path_name(path):
- """Expand a path into its long form.
-
- On Windows this expands any ~ in the paths. On other platforms, it is
- a null operation.
- """
- return _get_long_path_name(path)
-
-
-def unquote_filename(name, win32=(sys.platform=='win32')):
- """ On Windows, remove leading and trailing quotes from filenames.
-
- This function has been deprecated and should not be used any more:
- unquoting is now taken care of by :func:`IPython.utils.process.arg_split`.
- """
- warn("'unquote_filename' is deprecated since IPython 5.0 and should not "
- "be used anymore", DeprecationWarning, stacklevel=2)
- if win32:
- if name.startswith(("'", '"')) and name.endswith(("'", '"')):
- name = name[1:-1]
- return name
-
-
-def compress_user(path):
- """Reverse of :func:`os.path.expanduser`
- """
- home = os.path.expanduser('~')
- if path.startswith(home):
- path = "~" + path[len(home):]
- return path
-
-def get_py_filename(name, force_win32=None):
- """Return a valid python filename in the current directory.
-
- If the given name is not a file, it adds '.py' and searches again.
- Raises IOError with an informative message if the file isn't found.
- """
-
- name = os.path.expanduser(name)
- if force_win32 is not None:
- warn("The 'force_win32' argument to 'get_py_filename' is deprecated "
- "since IPython 5.0 and should not be used anymore",
- DeprecationWarning, stacklevel=2)
- if not os.path.isfile(name) and not name.endswith('.py'):
- name += '.py'
- if os.path.isfile(name):
- return name
- else:
- raise IOError('File `%r` not found.' % name)
-
-
-def filefind(filename, path_dirs=None):
- """Find a file by looking through a sequence of paths.
-
- This iterates through a sequence of paths looking for a file and returns
- the full, absolute path of the first occurrence of the file. If no set of
- path dirs is given, the filename is tested as is, after running through
- :func:`expandvars` and :func:`expanduser`. Thus a simple call::
-
- filefind('myfile.txt')
-
- will find the file in the current working dir, but::
-
- filefind('~/myfile.txt')
-
- Will find the file in the users home directory. This function does not
- automatically try any paths, such as the cwd or the user's home directory.
-
- Parameters
- ----------
- filename : str
- The filename to look for.
- path_dirs : str, None or sequence of str
- The sequence of paths to look for the file in. If None, the filename
- need to be absolute or be in the cwd. If a string, the string is
- put into a sequence and the searched. If a sequence, walk through
- each element and join with ``filename``, calling :func:`expandvars`
- and :func:`expanduser` before testing for existence.
-
- Returns
- -------
- Raises :exc:`IOError` or returns absolute path to file.
- """
-
- # If paths are quoted, abspath gets confused, strip them...
- filename = filename.strip('"').strip("'")
- # If the input is an absolute path, just check it exists
- if os.path.isabs(filename) and os.path.isfile(filename):
- return filename
-
- if path_dirs is None:
- path_dirs = ("",)
- elif isinstance(path_dirs, str):
- path_dirs = (path_dirs,)
-
- for path in path_dirs:
- if path == '.': path = os.getcwd()
- testname = expand_path(os.path.join(path, filename))
- if os.path.isfile(testname):
- return os.path.abspath(testname)
-
- raise IOError("File %r does not exist in any of the search paths: %r" %
- (filename, path_dirs) )
-
-
-class HomeDirError(Exception):
- pass
-
-
-def get_home_dir(require_writable=False) -> str:
- """Return the 'home' directory, as a unicode string.
-
- Uses os.path.expanduser('~'), and checks for writability.
-
- See stdlib docs for how this is determined.
- For Python <3.8, $HOME is first priority on *ALL* platforms.
- For Python >=3.8 on Windows, %HOME% is no longer considered.
-
- Parameters
- ----------
-
- require_writable : bool [default: False]
- if True:
- guarantees the return value is a writable directory, otherwise
- raises HomeDirError
- if False:
- The path is resolved, but it is not guaranteed to exist or be writable.
- """
-
- homedir = os.path.expanduser('~')
- # Next line will make things work even when /home/ is a symlink to
- # /usr/home as it is on FreeBSD, for example
- homedir = os.path.realpath(homedir)
-
- if not _writable_dir(homedir) and os.name == 'nt':
- # expanduser failed, use the registry to get the 'My Documents' folder.
- try:
- import winreg as wreg
- with wreg.OpenKey(
- wreg.HKEY_CURRENT_USER,
- r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
- ) as key:
- homedir = wreg.QueryValueEx(key,'Personal')[0]
- except:
- pass
-
- if (not require_writable) or _writable_dir(homedir):
- assert isinstance(homedir, str), "Homedir shoudl be unicode not bytes"
- return homedir
- else:
- raise HomeDirError('%s is not a writable dir, '
- 'set $HOME environment variable to override' % homedir)
-
-def get_xdg_dir():
- """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
-
- This is only for non-OS X posix (Linux,Unix,etc.) systems.
- """
-
- env = os.environ
-
- if os.name == 'posix' and sys.platform != 'darwin':
- # Linux, Unix, AIX, etc.
- # use ~/.config if empty OR not set
- xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
- if xdg and _writable_dir(xdg):
- assert isinstance(xdg, str)
- return xdg
-
- return None
-
-
-def get_xdg_cache_dir():
- """Return the XDG_CACHE_HOME, if it is defined and exists, else None.
-
- This is only for non-OS X posix (Linux,Unix,etc.) systems.
- """
-
- env = os.environ
-
- if os.name == 'posix' and sys.platform != 'darwin':
- # Linux, Unix, AIX, etc.
- # use ~/.cache if empty OR not set
- xdg = env.get("XDG_CACHE_HOME", None) or os.path.join(get_home_dir(), '.cache')
- if xdg and _writable_dir(xdg):
- assert isinstance(xdg, str)
- return xdg
-
- return None
-
-
-@undoc
-def get_ipython_dir():
- warn("get_ipython_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
- from IPython.paths import get_ipython_dir
- return get_ipython_dir()
-
-@undoc
-def get_ipython_cache_dir():
- warn("get_ipython_cache_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
- from IPython.paths import get_ipython_cache_dir
- return get_ipython_cache_dir()
-
-@undoc
-def get_ipython_package_dir():
- warn("get_ipython_package_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
- from IPython.paths import get_ipython_package_dir
- return get_ipython_package_dir()
-
-@undoc
-def get_ipython_module_path(module_str):
- warn("get_ipython_module_path has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
- from IPython.paths import get_ipython_module_path
- return get_ipython_module_path(module_str)
-
-@undoc
-def locate_profile(profile='default'):
- warn("locate_profile has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
- from IPython.paths import locate_profile
- return locate_profile(profile=profile)
-
-def expand_path(s):
- """Expand $VARS and ~names in a string, like a shell
-
- :Examples:
-
- In [2]: os.environ['FOO']='test'
-
- In [3]: expand_path('variable FOO is $FOO')
- Out[3]: 'variable FOO is test'
- """
- # This is a pretty subtle hack. When expand user is given a UNC path
- # on Windows (\\server\share$\%username%), os.path.expandvars, removes
- # the $ to get (\\server\share\%username%). I think it considered $
- # alone an empty var. But, we need the $ to remains there (it indicates
- # a hidden share).
- if os.name=='nt':
- s = s.replace('$\\', 'IPYTHON_TEMP')
- s = os.path.expandvars(os.path.expanduser(s))
- if os.name=='nt':
- s = s.replace('IPYTHON_TEMP', '$\\')
- return s
-
-
-def unescape_glob(string):
- """Unescape glob pattern in `string`."""
- def unescape(s):
- for pattern in '*[]!?':
- s = s.replace(r'\{0}'.format(pattern), pattern)
- return s
- return '\\'.join(map(unescape, string.split('\\\\')))
-
-
-def shellglob(args):
- """
- Do glob expansion for each element in `args` and return a flattened list.
-
- Unmatched glob pattern will remain as-is in the returned list.
-
- """
- expanded = []
- # Do not unescape backslash in Windows as it is interpreted as
- # path separator:
- unescape = unescape_glob if sys.platform != 'win32' else lambda x: x
- for a in args:
- expanded.extend(glob.glob(a) or [unescape(a)])
- return expanded
-
-
-def target_outdated(target,deps):
- """Determine whether a target is out of date.
-
- target_outdated(target,deps) -> 1/0
-
- deps: list of filenames which MUST exist.
- target: single filename which may or may not exist.
-
- If target doesn't exist or is older than any file listed in deps, return
- true, otherwise return false.
- """
- try:
- target_time = os.path.getmtime(target)
- except os.error:
- return 1
- for dep in deps:
- dep_time = os.path.getmtime(dep)
- if dep_time > target_time:
- #print "For target",target,"Dep failed:",dep # dbg
- #print "times (dep,tar):",dep_time,target_time # dbg
- return 1
- return 0
-
-
-def target_update(target,deps,cmd):
- """Update a target with a given command given a list of dependencies.
-
- target_update(target,deps,cmd) -> runs cmd if target is outdated.
-
- This is just a wrapper around target_outdated() which calls the given
- command if target is outdated."""
-
- if target_outdated(target,deps):
- system(cmd)
-
-
-ENOLINK = 1998
-
-def link(src, dst):
- """Hard links ``src`` to ``dst``, returning 0 or errno.
-
- Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't
- supported by the operating system.
- """
-
- if not hasattr(os, "link"):
- return ENOLINK
- link_errno = 0
- try:
- os.link(src, dst)
- except OSError as e:
- link_errno = e.errno
- return link_errno
-
-
-def link_or_copy(src, dst):
- """Attempts to hardlink ``src`` to ``dst``, copying if the link fails.
-
- Attempts to maintain the semantics of ``shutil.copy``.
-
- Because ``os.link`` does not overwrite files, a unique temporary file
- will be used if the target already exists, then that file will be moved
- into place.
- """
-
- if os.path.isdir(dst):
- dst = os.path.join(dst, os.path.basename(src))
-
- link_errno = link(src, dst)
- if link_errno == errno.EEXIST:
- if os.stat(src).st_ino == os.stat(dst).st_ino:
- # dst is already a hard link to the correct file, so we don't need
- # to do anything else. If we try to link and rename the file
- # anyway, we get duplicate files - see http://bugs.python.org/issue21876
- return
-
- new_dst = dst + "-temp-%04X" %(random.randint(1, 16**4), )
- try:
- link_or_copy(src, new_dst)
- except:
- try:
- os.remove(new_dst)
- except OSError:
- pass
- raise
- os.rename(new_dst, dst)
- elif link_errno != 0:
- # Either link isn't supported, or the filesystem doesn't support
- # linking, or 'src' and 'dst' are on different filesystems.
- shutil.copy(src, dst)
-
-def ensure_dir_exists(path, mode=0o755):
- """ensure that a directory exists
-
- If it doesn't exist, try to create it and protect against a race condition
- if another process is doing the same.
-
- The default permissions are 755, which differ from os.makedirs default of 777.
- """
- if not os.path.exists(path):
- try:
- os.makedirs(path, mode=mode)
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
- elif not os.path.isdir(path):
- raise IOError("%r exists but is not a directory" % path)
+# encoding: utf-8
+"""
+Utilities for path handling.
+"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+import os
+import sys
+import errno
+import shutil
+import random
+import glob
+from warnings import warn
+
+from IPython.utils.process import system
+from IPython.utils.decorators import undoc
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+fs_encoding = sys.getfilesystemencoding()
+
+def _writable_dir(path):
+ """Whether `path` is a directory, to which the user has write access."""
+ return os.path.isdir(path) and os.access(path, os.W_OK)
+
+if sys.platform == 'win32':
+ def _get_long_path_name(path):
+ """Get a long path name (expand ~) on Windows using ctypes.
+
+ Examples
+ --------
+
+ >>> get_long_path_name('c:\\docume~1')
+ 'c:\\\\Documents and Settings'
+
+ """
+ try:
+ import ctypes
+ except ImportError:
+ raise ImportError('you need to have ctypes installed for this to work')
+ _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
+ _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
+ ctypes.c_uint ]
+
+ buf = ctypes.create_unicode_buffer(260)
+ rv = _GetLongPathName(path, buf, 260)
+ if rv == 0 or rv > 260:
+ return path
+ else:
+ return buf.value
+else:
+ def _get_long_path_name(path):
+ """Dummy no-op."""
+ return path
+
+
+
+def get_long_path_name(path):
+ """Expand a path into its long form.
+
+ On Windows this expands any ~ in the paths. On other platforms, it is
+ a null operation.
+ """
+ return _get_long_path_name(path)
+
+
+def unquote_filename(name, win32=(sys.platform=='win32')):
+ """ On Windows, remove leading and trailing quotes from filenames.
+
+ This function has been deprecated and should not be used any more:
+ unquoting is now taken care of by :func:`IPython.utils.process.arg_split`.
+ """
+ warn("'unquote_filename' is deprecated since IPython 5.0 and should not "
+ "be used anymore", DeprecationWarning, stacklevel=2)
+ if win32:
+ if name.startswith(("'", '"')) and name.endswith(("'", '"')):
+ name = name[1:-1]
+ return name
+
+
+def compress_user(path):
+ """Reverse of :func:`os.path.expanduser`
+ """
+ home = os.path.expanduser('~')
+ if path.startswith(home):
+ path = "~" + path[len(home):]
+ return path
+
+def get_py_filename(name, force_win32=None):
+ """Return a valid python filename in the current directory.
+
+ If the given name is not a file, it adds '.py' and searches again.
+ Raises IOError with an informative message if the file isn't found.
+ """
+
+ name = os.path.expanduser(name)
+ if force_win32 is not None:
+ warn("The 'force_win32' argument to 'get_py_filename' is deprecated "
+ "since IPython 5.0 and should not be used anymore",
+ DeprecationWarning, stacklevel=2)
+ if not os.path.isfile(name) and not name.endswith('.py'):
+ name += '.py'
+ if os.path.isfile(name):
+ return name
+ else:
+ raise IOError('File `%r` not found.' % name)
+
+
+def filefind(filename, path_dirs=None):
+ """Find a file by looking through a sequence of paths.
+
+ This iterates through a sequence of paths looking for a file and returns
+ the full, absolute path of the first occurrence of the file. If no set of
+ path dirs is given, the filename is tested as is, after running through
+ :func:`expandvars` and :func:`expanduser`. Thus a simple call::
+
+ filefind('myfile.txt')
+
+ will find the file in the current working dir, but::
+
+ filefind('~/myfile.txt')
+
+ Will find the file in the users home directory. This function does not
+ automatically try any paths, such as the cwd or the user's home directory.
+
+ Parameters
+ ----------
+ filename : str
+ The filename to look for.
+ path_dirs : str, None or sequence of str
+ The sequence of paths to look for the file in. If None, the filename
+ need to be absolute or be in the cwd. If a string, the string is
+ put into a sequence and the searched. If a sequence, walk through
+ each element and join with ``filename``, calling :func:`expandvars`
+ and :func:`expanduser` before testing for existence.
+
+ Returns
+ -------
+ Raises :exc:`IOError` or returns absolute path to file.
+ """
+
+ # If paths are quoted, abspath gets confused, strip them...
+ filename = filename.strip('"').strip("'")
+ # If the input is an absolute path, just check it exists
+ if os.path.isabs(filename) and os.path.isfile(filename):
+ return filename
+
+ if path_dirs is None:
+ path_dirs = ("",)
+ elif isinstance(path_dirs, str):
+ path_dirs = (path_dirs,)
+
+ for path in path_dirs:
+ if path == '.': path = os.getcwd()
+ testname = expand_path(os.path.join(path, filename))
+ if os.path.isfile(testname):
+ return os.path.abspath(testname)
+
+ raise IOError("File %r does not exist in any of the search paths: %r" %
+ (filename, path_dirs) )
+
+
+class HomeDirError(Exception):
+ pass
+
+
+def get_home_dir(require_writable=False) -> str:
+ """Return the 'home' directory, as a unicode string.
+
+ Uses os.path.expanduser('~'), and checks for writability.
+
+ See stdlib docs for how this is determined.
+ For Python <3.8, $HOME is first priority on *ALL* platforms.
+ For Python >=3.8 on Windows, %HOME% is no longer considered.
+
+ Parameters
+ ----------
+
+ require_writable : bool [default: False]
+ if True:
+ guarantees the return value is a writable directory, otherwise
+ raises HomeDirError
+ if False:
+ The path is resolved, but it is not guaranteed to exist or be writable.
+ """
+
+ homedir = os.path.expanduser('~')
+ # Next line will make things work even when /home/ is a symlink to
+ # /usr/home as it is on FreeBSD, for example
+ homedir = os.path.realpath(homedir)
+
+ if not _writable_dir(homedir) and os.name == 'nt':
+ # expanduser failed, use the registry to get the 'My Documents' folder.
+ try:
+ import winreg as wreg
+ with wreg.OpenKey(
+ wreg.HKEY_CURRENT_USER,
+ r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
+ ) as key:
+ homedir = wreg.QueryValueEx(key,'Personal')[0]
+ except:
+ pass
+
+ if (not require_writable) or _writable_dir(homedir):
+ assert isinstance(homedir, str), "Homedir shoudl be unicode not bytes"
+ return homedir
+ else:
+ raise HomeDirError('%s is not a writable dir, '
+ 'set $HOME environment variable to override' % homedir)
+
+def get_xdg_dir():
+ """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
+
+ This is only for non-OS X posix (Linux,Unix,etc.) systems.
+ """
+
+ env = os.environ
+
+ if os.name == 'posix' and sys.platform != 'darwin':
+ # Linux, Unix, AIX, etc.
+ # use ~/.config if empty OR not set
+ xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
+ if xdg and _writable_dir(xdg):
+ assert isinstance(xdg, str)
+ return xdg
+
+ return None
+
+
+def get_xdg_cache_dir():
+ """Return the XDG_CACHE_HOME, if it is defined and exists, else None.
+
+ This is only for non-OS X posix (Linux,Unix,etc.) systems.
+ """
+
+ env = os.environ
+
+ if os.name == 'posix' and sys.platform != 'darwin':
+ # Linux, Unix, AIX, etc.
+ # use ~/.cache if empty OR not set
+ xdg = env.get("XDG_CACHE_HOME", None) or os.path.join(get_home_dir(), '.cache')
+ if xdg and _writable_dir(xdg):
+ assert isinstance(xdg, str)
+ return xdg
+
+ return None
+
+
+@undoc
+def get_ipython_dir():
+ warn("get_ipython_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
+ from IPython.paths import get_ipython_dir
+ return get_ipython_dir()
+
+@undoc
+def get_ipython_cache_dir():
+ warn("get_ipython_cache_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
+ from IPython.paths import get_ipython_cache_dir
+ return get_ipython_cache_dir()
+
+@undoc
+def get_ipython_package_dir():
+ warn("get_ipython_package_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
+ from IPython.paths import get_ipython_package_dir
+ return get_ipython_package_dir()
+
+@undoc
+def get_ipython_module_path(module_str):
+ warn("get_ipython_module_path has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
+ from IPython.paths import get_ipython_module_path
+ return get_ipython_module_path(module_str)
+
+@undoc
+def locate_profile(profile='default'):
+ warn("locate_profile has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
+ from IPython.paths import locate_profile
+ return locate_profile(profile=profile)
+
+def expand_path(s):
+ """Expand $VARS and ~names in a string, like a shell
+
+ :Examples:
+
+ In [2]: os.environ['FOO']='test'
+
+ In [3]: expand_path('variable FOO is $FOO')
+ Out[3]: 'variable FOO is test'
+ """
+ # This is a pretty subtle hack. When expand user is given a UNC path
+ # on Windows (\\server\share$\%username%), os.path.expandvars, removes
+ # the $ to get (\\server\share\%username%). I think it considered $
+ # alone an empty var. But, we need the $ to remains there (it indicates
+ # a hidden share).
+ if os.name=='nt':
+ s = s.replace('$\\', 'IPYTHON_TEMP')
+ s = os.path.expandvars(os.path.expanduser(s))
+ if os.name=='nt':
+ s = s.replace('IPYTHON_TEMP', '$\\')
+ return s
+
+
+def unescape_glob(string):
+ """Unescape glob pattern in `string`."""
+ def unescape(s):
+ for pattern in '*[]!?':
+ s = s.replace(r'\{0}'.format(pattern), pattern)
+ return s
+ return '\\'.join(map(unescape, string.split('\\\\')))
+
+
+def shellglob(args):
+ """
+ Do glob expansion for each element in `args` and return a flattened list.
+
+ Unmatched glob pattern will remain as-is in the returned list.
+
+ """
+ expanded = []
+ # Do not unescape backslash in Windows as it is interpreted as
+ # path separator:
+ unescape = unescape_glob if sys.platform != 'win32' else lambda x: x
+ for a in args:
+ expanded.extend(glob.glob(a) or [unescape(a)])
+ return expanded
+
+
+def target_outdated(target,deps):
+ """Determine whether a target is out of date.
+
+ target_outdated(target,deps) -> 1/0
+
+ deps: list of filenames which MUST exist.
+ target: single filename which may or may not exist.
+
+ If target doesn't exist or is older than any file listed in deps, return
+ true, otherwise return false.
+ """
+ try:
+ target_time = os.path.getmtime(target)
+ except os.error:
+ return 1
+ for dep in deps:
+ dep_time = os.path.getmtime(dep)
+ if dep_time > target_time:
+ #print "For target",target,"Dep failed:",dep # dbg
+ #print "times (dep,tar):",dep_time,target_time # dbg
+ return 1
+ return 0
+
+
+def target_update(target,deps,cmd):
+ """Update a target with a given command given a list of dependencies.
+
+ target_update(target,deps,cmd) -> runs cmd if target is outdated.
+
+ This is just a wrapper around target_outdated() which calls the given
+ command if target is outdated."""
+
+ if target_outdated(target,deps):
+ system(cmd)
+
+
+ENOLINK = 1998
+
+def link(src, dst):
+ """Hard links ``src`` to ``dst``, returning 0 or errno.
+
+ Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't
+ supported by the operating system.
+ """
+
+ if not hasattr(os, "link"):
+ return ENOLINK
+ link_errno = 0
+ try:
+ os.link(src, dst)
+ except OSError as e:
+ link_errno = e.errno
+ return link_errno
+
+
+def link_or_copy(src, dst):
+ """Attempts to hardlink ``src`` to ``dst``, copying if the link fails.
+
+ Attempts to maintain the semantics of ``shutil.copy``.
+
+ Because ``os.link`` does not overwrite files, a unique temporary file
+ will be used if the target already exists, then that file will be moved
+ into place.
+ """
+
+ if os.path.isdir(dst):
+ dst = os.path.join(dst, os.path.basename(src))
+
+ link_errno = link(src, dst)
+ if link_errno == errno.EEXIST:
+ if os.stat(src).st_ino == os.stat(dst).st_ino:
+ # dst is already a hard link to the correct file, so we don't need
+ # to do anything else. If we try to link and rename the file
+ # anyway, we get duplicate files - see http://bugs.python.org/issue21876
+ return
+
+ new_dst = dst + "-temp-%04X" %(random.randint(1, 16**4), )
+ try:
+ link_or_copy(src, new_dst)
+ except:
+ try:
+ os.remove(new_dst)
+ except OSError:
+ pass
+ raise
+ os.rename(new_dst, dst)
+ elif link_errno != 0:
+ # Either link isn't supported, or the filesystem doesn't support
+ # linking, or 'src' and 'dst' are on different filesystems.
+ shutil.copy(src, dst)
+
+def ensure_dir_exists(path, mode=0o755):
+ """ensure that a directory exists
+
+ If it doesn't exist, try to create it and protect against a race condition
+ if another process is doing the same.
+
+ The default permissions are 755, which differ from os.makedirs default of 777.
+ """
+ if not os.path.exists(path):
+ try:
+ os.makedirs(path, mode=mode)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+ elif not os.path.isdir(path):
+ raise IOError("%r exists but is not a directory" % path)
diff --git a/contrib/python/ipython/py3/IPython/utils/pickleutil.py b/contrib/python/ipython/py3/IPython/utils/pickleutil.py
index 0a4802d595..785e6f6c80 100644
--- a/contrib/python/ipython/py3/IPython/utils/pickleutil.py
+++ b/contrib/python/ipython/py3/IPython/utils/pickleutil.py
@@ -1,5 +1,5 @@
-from warnings import warn
-
-warn("IPython.utils.pickleutil has moved to ipykernel.pickleutil", stacklevel=2)
-
-from ipykernel.pickleutil import *
+from warnings import warn
+
+warn("IPython.utils.pickleutil has moved to ipykernel.pickleutil", stacklevel=2)
+
+from ipykernel.pickleutil import *
diff --git a/contrib/python/ipython/py3/IPython/utils/process.py b/contrib/python/ipython/py3/IPython/utils/process.py
index 67a16a7863..489b7c13d0 100644
--- a/contrib/python/ipython/py3/IPython/utils/process.py
+++ b/contrib/python/ipython/py3/IPython/utils/process.py
@@ -1,69 +1,69 @@
-# encoding: utf-8
-"""
-Utilities for working with external processes.
-"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-
-import os
-import shutil
-import sys
-
-if sys.platform == 'win32':
- from ._process_win32 import system, getoutput, arg_split, check_pid
-elif sys.platform == 'cli':
- from ._process_cli import system, getoutput, arg_split, check_pid
-else:
- from ._process_posix import system, getoutput, arg_split, check_pid
-
-from ._process_common import getoutputerror, get_output_error_code, process_handler
-
-
-class FindCmdError(Exception):
- pass
-
-
-def find_cmd(cmd):
- """Find absolute path to executable cmd in a cross platform manner.
-
- This function tries to determine the full path to a command line program
- using `which` on Unix/Linux/OS X and `win32api` on Windows. Most of the
- time it will use the version that is first on the users `PATH`.
-
- Warning, don't use this to find IPython command line programs as there
- is a risk you will find the wrong one. Instead find those using the
- following code and looking for the application itself::
-
- import sys
- argv = [sys.executable, '-m', 'IPython']
-
- Parameters
- ----------
- cmd : str
- The command line program to look for.
- """
- path = shutil.which(cmd)
- if path is None:
- raise FindCmdError('command could not be found: %s' % cmd)
- return path
-
-
-def abbrev_cwd():
- """ Return abbreviated version of cwd, e.g. d:mydir """
- cwd = os.getcwd().replace('\\','/')
- drivepart = ''
- tail = cwd
- if sys.platform == 'win32':
- if len(cwd) < 4:
- return cwd
- drivepart,tail = os.path.splitdrive(cwd)
-
-
- parts = tail.split('/')
- if len(parts) > 2:
- tail = '/'.join(parts[-2:])
-
- return (drivepart + (
- cwd == '/' and '/' or tail))
+# encoding: utf-8
+"""
+Utilities for working with external processes.
+"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+
+import os
+import shutil
+import sys
+
+if sys.platform == 'win32':
+ from ._process_win32 import system, getoutput, arg_split, check_pid
+elif sys.platform == 'cli':
+ from ._process_cli import system, getoutput, arg_split, check_pid
+else:
+ from ._process_posix import system, getoutput, arg_split, check_pid
+
+from ._process_common import getoutputerror, get_output_error_code, process_handler
+
+
+class FindCmdError(Exception):
+ pass
+
+
+def find_cmd(cmd):
+ """Find absolute path to executable cmd in a cross platform manner.
+
+ This function tries to determine the full path to a command line program
+ using `which` on Unix/Linux/OS X and `win32api` on Windows. Most of the
+ time it will use the version that is first on the users `PATH`.
+
+ Warning, don't use this to find IPython command line programs as there
+ is a risk you will find the wrong one. Instead find those using the
+ following code and looking for the application itself::
+
+ import sys
+ argv = [sys.executable, '-m', 'IPython']
+
+ Parameters
+ ----------
+ cmd : str
+ The command line program to look for.
+ """
+ path = shutil.which(cmd)
+ if path is None:
+ raise FindCmdError('command could not be found: %s' % cmd)
+ return path
+
+
+def abbrev_cwd():
+ """ Return abbreviated version of cwd, e.g. d:mydir """
+ cwd = os.getcwd().replace('\\','/')
+ drivepart = ''
+ tail = cwd
+ if sys.platform == 'win32':
+ if len(cwd) < 4:
+ return cwd
+ drivepart,tail = os.path.splitdrive(cwd)
+
+
+ parts = tail.split('/')
+ if len(parts) > 2:
+ tail = '/'.join(parts[-2:])
+
+ return (drivepart + (
+ cwd == '/' and '/' or tail))
diff --git a/contrib/python/ipython/py3/IPython/utils/py3compat.py b/contrib/python/ipython/py3/IPython/utils/py3compat.py
index 7aee6afd47..c758787300 100644
--- a/contrib/python/ipython/py3/IPython/utils/py3compat.py
+++ b/contrib/python/ipython/py3/IPython/utils/py3compat.py
@@ -1,191 +1,191 @@
-# coding: utf-8
-"""Compatibility tricks for Python 3. Mainly to do with unicode.
-
-This file is deprecated and will be removed in a future version.
-"""
-import functools
-import os
-import sys
-import re
-import shutil
-import types
-import platform
-
-from .encoding import DEFAULT_ENCODING
-
-
-def decode(s, encoding=None):
- encoding = encoding or DEFAULT_ENCODING
- return s.decode(encoding, "replace")
-
-def encode(u, encoding=None):
- encoding = encoding or DEFAULT_ENCODING
- return u.encode(encoding, "replace")
-
-
-def cast_unicode(s, encoding=None):
- if isinstance(s, bytes):
- return decode(s, encoding)
- return s
-
-def cast_bytes(s, encoding=None):
- if not isinstance(s, bytes):
- return encode(s, encoding)
- return s
-
-def buffer_to_bytes(buf):
- """Cast a buffer object to bytes"""
- if not isinstance(buf, bytes):
- buf = bytes(buf)
- return buf
-
-def _modify_str_or_docstring(str_change_func):
- @functools.wraps(str_change_func)
- def wrapper(func_or_str):
- if isinstance(func_or_str, (str,)):
- func = None
- doc = func_or_str
- else:
- func = func_or_str
- doc = func.__doc__
-
- # PYTHONOPTIMIZE=2 strips docstrings, so they can disappear unexpectedly
- if doc is not None:
- doc = str_change_func(doc)
-
- if func:
- func.__doc__ = doc
- return func
- return doc
- return wrapper
-
-def safe_unicode(e):
- """unicode(e) with various fallbacks. Used for exceptions, which may not be
- safe to call unicode() on.
- """
- try:
- return str(e)
- except UnicodeError:
- pass
-
- try:
- return repr(e)
- except UnicodeError:
- pass
-
- return u'Unrecoverably corrupt evalue'
-
-# shutil.which from Python 3.4
-def _shutil_which(cmd, mode=os.F_OK | os.X_OK, path=None):
- """Given a command, mode, and a PATH string, return the path which
- conforms to the given mode on the PATH, or None if there is no such
- file.
-
- `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
- of os.environ.get("PATH"), or can be overridden with a custom search
- path.
-
- This is a backport of shutil.which from Python 3.4
- """
- # Check that a given file can be accessed with the correct mode.
- # Additionally check that `file` is not a directory, as on Windows
- # directories pass the os.access check.
- def _access_check(fn, mode):
- return (os.path.exists(fn) and os.access(fn, mode)
- and not os.path.isdir(fn))
-
- # If we're given a path with a directory part, look it up directly rather
- # than referring to PATH directories. This includes checking relative to the
- # current directory, e.g. ./script
- if os.path.dirname(cmd):
- if _access_check(cmd, mode):
- return cmd
- return None
-
- if path is None:
- path = os.environ.get("PATH", os.defpath)
- if not path:
- return None
- path = path.split(os.pathsep)
-
- if sys.platform == "win32":
- # The current directory takes precedence on Windows.
- if not os.curdir in path:
- path.insert(0, os.curdir)
-
- # PATHEXT is necessary to check on Windows.
- pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
- # See if the given file matches any of the expected path extensions.
- # This will allow us to short circuit when given "python.exe".
- # If it does match, only test that one, otherwise we have to try
- # others.
- if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
- files = [cmd]
- else:
- files = [cmd + ext for ext in pathext]
- else:
- # On other platforms you don't have things like PATHEXT to tell you
- # what file suffixes are executable, so just pass on cmd as-is.
- files = [cmd]
-
- seen = set()
- for dir in path:
- normdir = os.path.normcase(dir)
- if not normdir in seen:
- seen.add(normdir)
- for thefile in files:
- name = os.path.join(dir, thefile)
- if _access_check(name, mode):
- return name
- return None
-
-PY3 = True
-
-# keep reference to builtin_mod because the kernel overrides that value
-# to forward requests to a frontend.
-def input(prompt=''):
- return builtin_mod.input(prompt)
-
-builtin_mod_name = "builtins"
-import builtins as builtin_mod
-
-
-which = shutil.which
-
-def isidentifier(s, dotted=False):
- if dotted:
- return all(isidentifier(a) for a in s.split("."))
- return s.isidentifier()
-
-getcwd = os.getcwd
-
-MethodType = types.MethodType
-
-def execfile(fname, glob, loc=None, compiler=None):
- loc = loc if (loc is not None) else glob
- with open(fname, 'rb') as f:
- compiler = compiler or compile
- exec(compiler(f.read(), fname, 'exec'), glob, loc)
-
-# Refactor print statements in doctests.
-_print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
-
-# Abstract u'abc' syntax:
-@_modify_str_or_docstring
-def u_format(s):
- """"{u}'abc'" --> "'abc'" (Python 3)
-
- Accepts a string or a function, so it can be used as a decorator."""
- return s.format(u='')
-
-
-PY2 = not PY3
-PYPY = platform.python_implementation() == "PyPy"
-
-# Cython still rely on that as a Dec 28 2019
-# See https://github.com/cython/cython/pull/3291 and
-# https://github.com/ipython/ipython/issues/12068
-def no_code(x, encoding=None):
- return x
-unicode_to_str = cast_bytes_py2 = no_code
-
+# coding: utf-8
+"""Compatibility tricks for Python 3. Mainly to do with unicode.
+
+This file is deprecated and will be removed in a future version.
+"""
+import functools
+import os
+import sys
+import re
+import shutil
+import types
+import platform
+
+from .encoding import DEFAULT_ENCODING
+
+
+def decode(s, encoding=None):
+ encoding = encoding or DEFAULT_ENCODING
+ return s.decode(encoding, "replace")
+
+def encode(u, encoding=None):
+ encoding = encoding or DEFAULT_ENCODING
+ return u.encode(encoding, "replace")
+
+
+def cast_unicode(s, encoding=None):
+ if isinstance(s, bytes):
+ return decode(s, encoding)
+ return s
+
+def cast_bytes(s, encoding=None):
+ if not isinstance(s, bytes):
+ return encode(s, encoding)
+ return s
+
+def buffer_to_bytes(buf):
+ """Cast a buffer object to bytes"""
+ if not isinstance(buf, bytes):
+ buf = bytes(buf)
+ return buf
+
+def _modify_str_or_docstring(str_change_func):
+ @functools.wraps(str_change_func)
+ def wrapper(func_or_str):
+ if isinstance(func_or_str, (str,)):
+ func = None
+ doc = func_or_str
+ else:
+ func = func_or_str
+ doc = func.__doc__
+
+ # PYTHONOPTIMIZE=2 strips docstrings, so they can disappear unexpectedly
+ if doc is not None:
+ doc = str_change_func(doc)
+
+ if func:
+ func.__doc__ = doc
+ return func
+ return doc
+ return wrapper
+
+def safe_unicode(e):
+ """unicode(e) with various fallbacks. Used for exceptions, which may not be
+ safe to call unicode() on.
+ """
+ try:
+ return str(e)
+ except UnicodeError:
+ pass
+
+ try:
+ return repr(e)
+ except UnicodeError:
+ pass
+
+ return u'Unrecoverably corrupt evalue'
+
+# shutil.which from Python 3.4
+def _shutil_which(cmd, mode=os.F_OK | os.X_OK, path=None):
+ """Given a command, mode, and a PATH string, return the path which
+ conforms to the given mode on the PATH, or None if there is no such
+ file.
+
+ `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
+ of os.environ.get("PATH"), or can be overridden with a custom search
+ path.
+
+ This is a backport of shutil.which from Python 3.4
+ """
+ # Check that a given file can be accessed with the correct mode.
+ # Additionally check that `file` is not a directory, as on Windows
+ # directories pass the os.access check.
+ def _access_check(fn, mode):
+ return (os.path.exists(fn) and os.access(fn, mode)
+ and not os.path.isdir(fn))
+
+ # If we're given a path with a directory part, look it up directly rather
+ # than referring to PATH directories. This includes checking relative to the
+ # current directory, e.g. ./script
+ if os.path.dirname(cmd):
+ if _access_check(cmd, mode):
+ return cmd
+ return None
+
+ if path is None:
+ path = os.environ.get("PATH", os.defpath)
+ if not path:
+ return None
+ path = path.split(os.pathsep)
+
+ if sys.platform == "win32":
+ # The current directory takes precedence on Windows.
+ if not os.curdir in path:
+ path.insert(0, os.curdir)
+
+ # PATHEXT is necessary to check on Windows.
+ pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
+ # See if the given file matches any of the expected path extensions.
+ # This will allow us to short circuit when given "python.exe".
+ # If it does match, only test that one, otherwise we have to try
+ # others.
+ if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
+ files = [cmd]
+ else:
+ files = [cmd + ext for ext in pathext]
+ else:
+ # On other platforms you don't have things like PATHEXT to tell you
+ # what file suffixes are executable, so just pass on cmd as-is.
+ files = [cmd]
+
+ seen = set()
+ for dir in path:
+ normdir = os.path.normcase(dir)
+ if not normdir in seen:
+ seen.add(normdir)
+ for thefile in files:
+ name = os.path.join(dir, thefile)
+ if _access_check(name, mode):
+ return name
+ return None
+
+PY3 = True
+
+# keep reference to builtin_mod because the kernel overrides that value
+# to forward requests to a frontend.
+def input(prompt=''):
+ return builtin_mod.input(prompt)
+
+builtin_mod_name = "builtins"
+import builtins as builtin_mod
+
+
+which = shutil.which
+
+def isidentifier(s, dotted=False):
+ if dotted:
+ return all(isidentifier(a) for a in s.split("."))
+ return s.isidentifier()
+
+getcwd = os.getcwd
+
+MethodType = types.MethodType
+
+def execfile(fname, glob, loc=None, compiler=None):
+ loc = loc if (loc is not None) else glob
+ with open(fname, 'rb') as f:
+ compiler = compiler or compile
+ exec(compiler(f.read(), fname, 'exec'), glob, loc)
+
+# Refactor print statements in doctests.
+_print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
+
+# Abstract u'abc' syntax:
+@_modify_str_or_docstring
+def u_format(s):
+ """"{u}'abc'" --> "'abc'" (Python 3)
+
+ Accepts a string or a function, so it can be used as a decorator."""
+ return s.format(u='')
+
+
+PY2 = not PY3
+PYPY = platform.python_implementation() == "PyPy"
+
+# Cython still rely on that as a Dec 28 2019
+# See https://github.com/cython/cython/pull/3291 and
+# https://github.com/ipython/ipython/issues/12068
+def no_code(x, encoding=None):
+ return x
+unicode_to_str = cast_bytes_py2 = no_code
+
diff --git a/contrib/python/ipython/py3/IPython/utils/sentinel.py b/contrib/python/ipython/py3/IPython/utils/sentinel.py
index 7af2558c1a..dc57a2591c 100644
--- a/contrib/python/ipython/py3/IPython/utils/sentinel.py
+++ b/contrib/python/ipython/py3/IPython/utils/sentinel.py
@@ -1,17 +1,17 @@
-"""Sentinel class for constants with useful reprs"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-class Sentinel(object):
-
- def __init__(self, name, module, docstring=None):
- self.name = name
- self.module = module
- if docstring:
- self.__doc__ = docstring
-
-
- def __repr__(self):
- return str(self.module)+'.'+self.name
-
+"""Sentinel class for constants with useful reprs"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+class Sentinel(object):
+
+ def __init__(self, name, module, docstring=None):
+ self.name = name
+ self.module = module
+ if docstring:
+ self.__doc__ = docstring
+
+
+ def __repr__(self):
+ return str(self.module)+'.'+self.name
+
diff --git a/contrib/python/ipython/py3/IPython/utils/shimmodule.py b/contrib/python/ipython/py3/IPython/utils/shimmodule.py
index 097e82149b..b70ac135bf 100644
--- a/contrib/python/ipython/py3/IPython/utils/shimmodule.py
+++ b/contrib/python/ipython/py3/IPython/utils/shimmodule.py
@@ -1,94 +1,94 @@
-"""A shim module for deprecated imports
-"""
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-import sys
-import types
-from importlib import import_module
-
-from .importstring import import_item
-
-
-class ShimWarning(Warning):
- """A warning to show when a module has moved, and a shim is in its place."""
-
-class ShimImporter(object):
- """Import hook for a shim.
-
- This ensures that submodule imports return the real target module,
- not a clone that will confuse `is` and `isinstance` checks.
- """
- def __init__(self, src, mirror):
- self.src = src
- self.mirror = mirror
-
- def _mirror_name(self, fullname):
- """get the name of the mirrored module"""
-
- return self.mirror + fullname[len(self.src):]
-
- def find_module(self, fullname, path=None):
- """Return self if we should be used to import the module."""
- if fullname.startswith(self.src + '.'):
- mirror_name = self._mirror_name(fullname)
- try:
- mod = import_item(mirror_name)
- except ImportError:
- return
- else:
- if not isinstance(mod, types.ModuleType):
- # not a module
- return None
- return self
-
- def load_module(self, fullname):
- """Import the mirrored module, and insert it into sys.modules"""
- mirror_name = self._mirror_name(fullname)
- mod = import_item(mirror_name)
- sys.modules[fullname] = mod
- return mod
-
-
-class ShimModule(types.ModuleType):
-
- def __init__(self, *args, **kwargs):
- self._mirror = kwargs.pop("mirror")
- src = kwargs.pop("src", None)
- if src:
- kwargs['name'] = src.rsplit('.', 1)[-1]
- super(ShimModule, self).__init__(*args, **kwargs)
- # add import hook for descendent modules
- if src:
- sys.meta_path.append(
- ShimImporter(src=src, mirror=self._mirror)
- )
-
- @property
- def __path__(self):
- return []
-
- @property
- def __spec__(self):
- """Don't produce __spec__ until requested"""
- return import_module(self._mirror).__spec__
-
- def __dir__(self):
- return dir(import_module(self._mirror))
-
- @property
- def __all__(self):
- """Ensure __all__ is always defined"""
- mod = import_module(self._mirror)
- try:
- return mod.__all__
- except AttributeError:
- return [name for name in dir(mod) if not name.startswith('_')]
-
- def __getattr__(self, key):
- # Use the equivalent of import_item(name), see below
- name = "%s.%s" % (self._mirror, key)
- try:
- return import_item(name)
- except ImportError:
- raise AttributeError(key)
+"""A shim module for deprecated imports
+"""
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+import sys
+import types
+from importlib import import_module
+
+from .importstring import import_item
+
+
+class ShimWarning(Warning):
+ """A warning to show when a module has moved, and a shim is in its place."""
+
+class ShimImporter(object):
+ """Import hook for a shim.
+
+ This ensures that submodule imports return the real target module,
+ not a clone that will confuse `is` and `isinstance` checks.
+ """
+ def __init__(self, src, mirror):
+ self.src = src
+ self.mirror = mirror
+
+ def _mirror_name(self, fullname):
+ """get the name of the mirrored module"""
+
+ return self.mirror + fullname[len(self.src):]
+
+ def find_module(self, fullname, path=None):
+ """Return self if we should be used to import the module."""
+ if fullname.startswith(self.src + '.'):
+ mirror_name = self._mirror_name(fullname)
+ try:
+ mod = import_item(mirror_name)
+ except ImportError:
+ return
+ else:
+ if not isinstance(mod, types.ModuleType):
+ # not a module
+ return None
+ return self
+
+ def load_module(self, fullname):
+ """Import the mirrored module, and insert it into sys.modules"""
+ mirror_name = self._mirror_name(fullname)
+ mod = import_item(mirror_name)
+ sys.modules[fullname] = mod
+ return mod
+
+
+class ShimModule(types.ModuleType):
+
+ def __init__(self, *args, **kwargs):
+ self._mirror = kwargs.pop("mirror")
+ src = kwargs.pop("src", None)
+ if src:
+ kwargs['name'] = src.rsplit('.', 1)[-1]
+ super(ShimModule, self).__init__(*args, **kwargs)
+ # add import hook for descendent modules
+ if src:
+ sys.meta_path.append(
+ ShimImporter(src=src, mirror=self._mirror)
+ )
+
+ @property
+ def __path__(self):
+ return []
+
+ @property
+ def __spec__(self):
+ """Don't produce __spec__ until requested"""
+ return import_module(self._mirror).__spec__
+
+ def __dir__(self):
+ return dir(import_module(self._mirror))
+
+ @property
+ def __all__(self):
+ """Ensure __all__ is always defined"""
+ mod = import_module(self._mirror)
+ try:
+ return mod.__all__
+ except AttributeError:
+ return [name for name in dir(mod) if not name.startswith('_')]
+
+ def __getattr__(self, key):
+ # Use the equivalent of import_item(name), see below
+ name = "%s.%s" % (self._mirror, key)
+ try:
+ return import_item(name)
+ except ImportError:
+ raise AttributeError(key)
diff --git a/contrib/python/ipython/py3/IPython/utils/signatures.py b/contrib/python/ipython/py3/IPython/utils/signatures.py
index ba35b9858d..88d72b185e 100644
--- a/contrib/python/ipython/py3/IPython/utils/signatures.py
+++ b/contrib/python/ipython/py3/IPython/utils/signatures.py
@@ -1,12 +1,12 @@
-"""DEPRECATED: Function signature objects for callables.
-
-Use the standard library version if available, as it is more up to date.
-Fallback on backport otherwise.
-"""
-
-import warnings
-warnings.warn("{} backport for Python 2 is deprecated in IPython 6, which only supports "
- "Python 3. Import directly from standard library `inspect`".format(__name__),
- DeprecationWarning, stacklevel=2)
-
-from inspect import BoundArguments, Parameter, Signature, signature
+"""DEPRECATED: Function signature objects for callables.
+
+Use the standard library version if available, as it is more up to date.
+Fallback on backport otherwise.
+"""
+
+import warnings
+warnings.warn("{} backport for Python 2 is deprecated in IPython 6, which only supports "
+ "Python 3. Import directly from standard library `inspect`".format(__name__),
+ DeprecationWarning, stacklevel=2)
+
+from inspect import BoundArguments, Parameter, Signature, signature
diff --git a/contrib/python/ipython/py3/IPython/utils/strdispatch.py b/contrib/python/ipython/py3/IPython/utils/strdispatch.py
index a6183404e7..d6bf510535 100644
--- a/contrib/python/ipython/py3/IPython/utils/strdispatch.py
+++ b/contrib/python/ipython/py3/IPython/utils/strdispatch.py
@@ -1,68 +1,68 @@
-"""String dispatch class to match regexps and dispatch commands.
-"""
-
-# Stdlib imports
-import re
-
-# Our own modules
-from IPython.core.hooks import CommandChainDispatcher
-
-# Code begins
-class StrDispatch(object):
- """Dispatch (lookup) a set of strings / regexps for match.
-
- Example:
-
- >>> dis = StrDispatch()
- >>> dis.add_s('hei',34, priority = 4)
- >>> dis.add_s('hei',123, priority = 2)
- >>> dis.add_re('h.i', 686)
- >>> print(list(dis.flat_matches('hei')))
- [123, 34, 686]
- """
-
- def __init__(self):
- self.strs = {}
- self.regexs = {}
-
- def add_s(self, s, obj, priority= 0 ):
- """ Adds a target 'string' for dispatching """
-
- chain = self.strs.get(s, CommandChainDispatcher())
- chain.add(obj,priority)
- self.strs[s] = chain
-
- def add_re(self, regex, obj, priority= 0 ):
- """ Adds a target regexp for dispatching """
-
- chain = self.regexs.get(regex, CommandChainDispatcher())
- chain.add(obj,priority)
- self.regexs[regex] = chain
-
- def dispatch(self, key):
- """ Get a seq of Commandchain objects that match key """
- if key in self.strs:
- yield self.strs[key]
-
- for r, obj in self.regexs.items():
- if re.match(r, key):
- yield obj
- else:
- #print "nomatch",key # dbg
- pass
-
- def __repr__(self):
- return "<Strdispatch %s, %s>" % (self.strs, self.regexs)
-
- def s_matches(self, key):
- if key not in self.strs:
- return
- for el in self.strs[key]:
- yield el[1]
-
- def flat_matches(self, key):
- """ Yield all 'value' targets, without priority """
- for val in self.dispatch(key):
- for el in val:
- yield el[1] # only value, no priority
- return
+"""String dispatch class to match regexps and dispatch commands.
+"""
+
+# Stdlib imports
+import re
+
+# Our own modules
+from IPython.core.hooks import CommandChainDispatcher
+
+# Code begins
+class StrDispatch(object):
+ """Dispatch (lookup) a set of strings / regexps for match.
+
+ Example:
+
+ >>> dis = StrDispatch()
+ >>> dis.add_s('hei',34, priority = 4)
+ >>> dis.add_s('hei',123, priority = 2)
+ >>> dis.add_re('h.i', 686)
+ >>> print(list(dis.flat_matches('hei')))
+ [123, 34, 686]
+ """
+
+ def __init__(self):
+ self.strs = {}
+ self.regexs = {}
+
+ def add_s(self, s, obj, priority= 0 ):
+ """ Adds a target 'string' for dispatching """
+
+ chain = self.strs.get(s, CommandChainDispatcher())
+ chain.add(obj,priority)
+ self.strs[s] = chain
+
+ def add_re(self, regex, obj, priority= 0 ):
+ """ Adds a target regexp for dispatching """
+
+ chain = self.regexs.get(regex, CommandChainDispatcher())
+ chain.add(obj,priority)
+ self.regexs[regex] = chain
+
+ def dispatch(self, key):
+ """ Get a seq of Commandchain objects that match key """
+ if key in self.strs:
+ yield self.strs[key]
+
+ for r, obj in self.regexs.items():
+ if re.match(r, key):
+ yield obj
+ else:
+ #print "nomatch",key # dbg
+ pass
+
+ def __repr__(self):
+ return "<Strdispatch %s, %s>" % (self.strs, self.regexs)
+
+ def s_matches(self, key):
+ if key not in self.strs:
+ return
+ for el in self.strs[key]:
+ yield el[1]
+
+ def flat_matches(self, key):
+ """ Yield all 'value' targets, without priority """
+ for val in self.dispatch(key):
+ for el in val:
+ yield el[1] # only value, no priority
+ return
diff --git a/contrib/python/ipython/py3/IPython/utils/sysinfo.py b/contrib/python/ipython/py3/IPython/utils/sysinfo.py
index f082921c54..07d14fd8a4 100644
--- a/contrib/python/ipython/py3/IPython/utils/sysinfo.py
+++ b/contrib/python/ipython/py3/IPython/utils/sysinfo.py
@@ -1,166 +1,166 @@
-# encoding: utf-8
-"""
-Utilities for getting information about IPython and the system it's running in.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-import os
-import platform
-import pprint
-import sys
-import subprocess
-
-from IPython.core import release
-from IPython.utils import _sysinfo, encoding
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-
-def pkg_commit_hash(pkg_path):
- """Get short form of commit hash given directory `pkg_path`
-
- We get the commit hash from (in order of preference):
-
- * IPython.utils._sysinfo.commit
- * git output, if we are in a git repository
-
- If these fail, we return a not-found placeholder tuple
-
- Parameters
- ----------
- pkg_path : str
- directory containing package
- only used for getting commit from active repo
-
- Returns
- -------
- hash_from : str
- Where we got the hash from - description
- hash_str : str
- short form of hash
- """
- # Try and get commit from written commit text file
- if _sysinfo.commit:
- return "installation", _sysinfo.commit
-
- # maybe we are in a repository
- proc = subprocess.Popen('git rev-parse --short HEAD'.split(' '),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=pkg_path)
- repo_commit, _ = proc.communicate()
- if repo_commit:
- return 'repository', repo_commit.strip().decode('ascii')
- return '(none found)', '<not found>'
-
-
-def pkg_info(pkg_path):
- """Return dict describing the context of this package
-
- Parameters
- ----------
- pkg_path : str
- path containing __init__.py for package
-
- Returns
- -------
- context : dict
- with named parameters of interest
- """
- src, hsh = pkg_commit_hash(pkg_path)
- return dict(
- ipython_version=release.version,
- ipython_path=pkg_path,
- commit_source=src,
- commit_hash=hsh,
- sys_version=sys.version,
- sys_executable=sys.executable,
- sys_platform=sys.platform,
- platform=platform.platform(),
- os_name=os.name,
- default_encoding=encoding.DEFAULT_ENCODING,
- )
-
-def get_sys_info():
- """Return useful information about IPython and the system, as a dict."""
- p = os.path
- path = p.realpath(p.dirname(p.abspath(p.join(__file__, '..'))))
- return pkg_info(path)
-
-def sys_info():
- """Return useful information about IPython and the system, as a string.
-
- Examples
- --------
- ::
-
- In [2]: print(sys_info())
- {'commit_hash': '144fdae', # random
- 'commit_source': 'repository',
- 'ipython_path': '/home/fperez/usr/lib/python2.6/site-packages/IPython',
- 'ipython_version': '0.11.dev',
- 'os_name': 'posix',
- 'platform': 'Linux-2.6.35-22-generic-i686-with-Ubuntu-10.10-maverick',
- 'sys_executable': '/usr/bin/python',
- 'sys_platform': 'linux2',
- 'sys_version': '2.6.6 (r266:84292, Sep 15 2010, 15:52:39) \\n[GCC 4.4.5]'}
- """
- return pprint.pformat(get_sys_info())
-
-def _num_cpus_unix():
- """Return the number of active CPUs on a Unix system."""
- return os.sysconf("SC_NPROCESSORS_ONLN")
-
-
-def _num_cpus_darwin():
- """Return the number of active CPUs on a Darwin system."""
- p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
- return p.stdout.read()
-
-
-def _num_cpus_windows():
- """Return the number of active CPUs on a Windows system."""
- return os.environ.get("NUMBER_OF_PROCESSORS")
-
-
-def num_cpus():
- """Return the effective number of CPUs in the system as an integer.
-
- This cross-platform function makes an attempt at finding the total number of
- available CPUs in the system, as returned by various underlying system and
- python calls.
-
- If it can't find a sensible answer, it returns 1 (though an error *may* make
- it return a large positive number that's actually incorrect).
- """
-
- # Many thanks to the Parallel Python project (http://www.parallelpython.com)
- # for the names of the keys we needed to look up for this function. This
- # code was inspired by their equivalent function.
-
- ncpufuncs = {'Linux':_num_cpus_unix,
- 'Darwin':_num_cpus_darwin,
- 'Windows':_num_cpus_windows
- }
-
- ncpufunc = ncpufuncs.get(platform.system(),
- # default to unix version (Solaris, AIX, etc)
- _num_cpus_unix)
-
- try:
- ncpus = max(1,int(ncpufunc()))
- except:
- ncpus = 1
- return ncpus
-
+# encoding: utf-8
+"""
+Utilities for getting information about IPython and the system it's running in.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+import os
+import platform
+import pprint
+import sys
+import subprocess
+
+from IPython.core import release
+from IPython.utils import _sysinfo, encoding
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+def pkg_commit_hash(pkg_path):
+ """Get short form of commit hash given directory `pkg_path`
+
+ We get the commit hash from (in order of preference):
+
+ * IPython.utils._sysinfo.commit
+ * git output, if we are in a git repository
+
+ If these fail, we return a not-found placeholder tuple
+
+ Parameters
+ ----------
+ pkg_path : str
+ directory containing package
+ only used for getting commit from active repo
+
+ Returns
+ -------
+ hash_from : str
+ Where we got the hash from - description
+ hash_str : str
+ short form of hash
+ """
+ # Try and get commit from written commit text file
+ if _sysinfo.commit:
+ return "installation", _sysinfo.commit
+
+ # maybe we are in a repository
+ proc = subprocess.Popen('git rev-parse --short HEAD'.split(' '),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ cwd=pkg_path)
+ repo_commit, _ = proc.communicate()
+ if repo_commit:
+ return 'repository', repo_commit.strip().decode('ascii')
+ return '(none found)', '<not found>'
+
+
+def pkg_info(pkg_path):
+ """Return dict describing the context of this package
+
+ Parameters
+ ----------
+ pkg_path : str
+ path containing __init__.py for package
+
+ Returns
+ -------
+ context : dict
+ with named parameters of interest
+ """
+ src, hsh = pkg_commit_hash(pkg_path)
+ return dict(
+ ipython_version=release.version,
+ ipython_path=pkg_path,
+ commit_source=src,
+ commit_hash=hsh,
+ sys_version=sys.version,
+ sys_executable=sys.executable,
+ sys_platform=sys.platform,
+ platform=platform.platform(),
+ os_name=os.name,
+ default_encoding=encoding.DEFAULT_ENCODING,
+ )
+
+def get_sys_info():
+ """Return useful information about IPython and the system, as a dict."""
+ p = os.path
+ path = p.realpath(p.dirname(p.abspath(p.join(__file__, '..'))))
+ return pkg_info(path)
+
+def sys_info():
+ """Return useful information about IPython and the system, as a string.
+
+ Examples
+ --------
+ ::
+
+ In [2]: print(sys_info())
+ {'commit_hash': '144fdae', # random
+ 'commit_source': 'repository',
+ 'ipython_path': '/home/fperez/usr/lib/python2.6/site-packages/IPython',
+ 'ipython_version': '0.11.dev',
+ 'os_name': 'posix',
+ 'platform': 'Linux-2.6.35-22-generic-i686-with-Ubuntu-10.10-maverick',
+ 'sys_executable': '/usr/bin/python',
+ 'sys_platform': 'linux2',
+ 'sys_version': '2.6.6 (r266:84292, Sep 15 2010, 15:52:39) \\n[GCC 4.4.5]'}
+ """
+ return pprint.pformat(get_sys_info())
+
+def _num_cpus_unix():
+ """Return the number of active CPUs on a Unix system."""
+ return os.sysconf("SC_NPROCESSORS_ONLN")
+
+
+def _num_cpus_darwin():
+ """Return the number of active CPUs on a Darwin system."""
+ p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
+ return p.stdout.read()
+
+
+def _num_cpus_windows():
+ """Return the number of active CPUs on a Windows system."""
+ return os.environ.get("NUMBER_OF_PROCESSORS")
+
+
+def num_cpus():
+ """Return the effective number of CPUs in the system as an integer.
+
+ This cross-platform function makes an attempt at finding the total number of
+ available CPUs in the system, as returned by various underlying system and
+ python calls.
+
+ If it can't find a sensible answer, it returns 1 (though an error *may* make
+ it return a large positive number that's actually incorrect).
+ """
+
+ # Many thanks to the Parallel Python project (http://www.parallelpython.com)
+ # for the names of the keys we needed to look up for this function. This
+ # code was inspired by their equivalent function.
+
+ ncpufuncs = {'Linux':_num_cpus_unix,
+ 'Darwin':_num_cpus_darwin,
+ 'Windows':_num_cpus_windows
+ }
+
+ ncpufunc = ncpufuncs.get(platform.system(),
+ # default to unix version (Solaris, AIX, etc)
+ _num_cpus_unix)
+
+ try:
+ ncpus = max(1,int(ncpufunc()))
+ except:
+ ncpus = 1
+ return ncpus
+
diff --git a/contrib/python/ipython/py3/IPython/utils/syspathcontext.py b/contrib/python/ipython/py3/IPython/utils/syspathcontext.py
index 1da30064b2..bd1c51500d 100644
--- a/contrib/python/ipython/py3/IPython/utils/syspathcontext.py
+++ b/contrib/python/ipython/py3/IPython/utils/syspathcontext.py
@@ -1,62 +1,62 @@
-# encoding: utf-8
-"""
-Context managers for adding things to sys.path temporarily.
-
-Authors:
-
-* Brian Granger
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-import sys
-
-
-class appended_to_syspath(object):
- """A context for appending a directory to sys.path for a second."""
-
- def __init__(self, dir):
- self.dir = dir
-
- def __enter__(self):
- if self.dir not in sys.path:
- sys.path.append(self.dir)
- self.added = True
- else:
- self.added = False
-
- def __exit__(self, type, value, traceback):
- if self.added:
- try:
- sys.path.remove(self.dir)
- except ValueError:
- pass
- # Returning False causes any exceptions to be re-raised.
- return False
-
-class prepended_to_syspath(object):
- """A context for prepending a directory to sys.path for a second."""
-
- def __init__(self, dir):
- self.dir = dir
-
- def __enter__(self):
- if self.dir not in sys.path:
- sys.path.insert(0,self.dir)
- self.added = True
- else:
- self.added = False
-
- def __exit__(self, type, value, traceback):
- if self.added:
- try:
- sys.path.remove(self.dir)
- except ValueError:
- pass
- # Returning False causes any exceptions to be re-raised.
- return False
+# encoding: utf-8
+"""
+Context managers for adding things to sys.path temporarily.
+
+Authors:
+
+* Brian Granger
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+import sys
+
+
+class appended_to_syspath(object):
+ """A context for appending a directory to sys.path for a second."""
+
+ def __init__(self, dir):
+ self.dir = dir
+
+ def __enter__(self):
+ if self.dir not in sys.path:
+ sys.path.append(self.dir)
+ self.added = True
+ else:
+ self.added = False
+
+ def __exit__(self, type, value, traceback):
+ if self.added:
+ try:
+ sys.path.remove(self.dir)
+ except ValueError:
+ pass
+ # Returning False causes any exceptions to be re-raised.
+ return False
+
+class prepended_to_syspath(object):
+ """A context for prepending a directory to sys.path for a second."""
+
+ def __init__(self, dir):
+ self.dir = dir
+
+ def __enter__(self):
+ if self.dir not in sys.path:
+ sys.path.insert(0,self.dir)
+ self.added = True
+ else:
+ self.added = False
+
+ def __exit__(self, type, value, traceback):
+ if self.added:
+ try:
+ sys.path.remove(self.dir)
+ except ValueError:
+ pass
+ # Returning False causes any exceptions to be re-raised.
+ return False
diff --git a/contrib/python/ipython/py3/IPython/utils/tempdir.py b/contrib/python/ipython/py3/IPython/utils/tempdir.py
index 2446ee2ccc..98f6aeb3c6 100644
--- a/contrib/python/ipython/py3/IPython/utils/tempdir.py
+++ b/contrib/python/ipython/py3/IPython/utils/tempdir.py
@@ -1,57 +1,57 @@
-""" This module contains classes - NamedFileInTemporaryDirectory, TemporaryWorkingDirectory.
-
-These classes add extra features such as creating a named file in temporary directory and
-creating a context manager for the working directory which is also temporary.
-"""
-
-import os as _os
-from tempfile import TemporaryDirectory
-
-
-class NamedFileInTemporaryDirectory(object):
-
- def __init__(self, filename, mode='w+b', bufsize=-1, **kwds):
- """
- Open a file named `filename` in a temporary directory.
-
- This context manager is preferred over `NamedTemporaryFile` in
- stdlib `tempfile` when one needs to reopen the file.
-
- Arguments `mode` and `bufsize` are passed to `open`.
- Rest of the arguments are passed to `TemporaryDirectory`.
-
- """
- self._tmpdir = TemporaryDirectory(**kwds)
- path = _os.path.join(self._tmpdir.name, filename)
- self.file = open(path, mode, bufsize)
-
- def cleanup(self):
- self.file.close()
- self._tmpdir.cleanup()
-
- __del__ = cleanup
-
- def __enter__(self):
- return self.file
-
- def __exit__(self, type, value, traceback):
- self.cleanup()
-
-
-class TemporaryWorkingDirectory(TemporaryDirectory):
- """
- Creates a temporary directory and sets the cwd to that directory.
- Automatically reverts to previous cwd upon cleanup.
- Usage example:
-
- with TemporaryWorkingDirectory() as tmpdir:
- ...
- """
- def __enter__(self):
- self.old_wd = _os.getcwd()
- _os.chdir(self.name)
- return super(TemporaryWorkingDirectory, self).__enter__()
-
- def __exit__(self, exc, value, tb):
- _os.chdir(self.old_wd)
- return super(TemporaryWorkingDirectory, self).__exit__(exc, value, tb)
+""" This module contains classes - NamedFileInTemporaryDirectory, TemporaryWorkingDirectory.
+
+These classes add extra features such as creating a named file in temporary directory and
+creating a context manager for the working directory which is also temporary.
+"""
+
+import os as _os
+from tempfile import TemporaryDirectory
+
+
+class NamedFileInTemporaryDirectory(object):
+
+ def __init__(self, filename, mode='w+b', bufsize=-1, **kwds):
+ """
+ Open a file named `filename` in a temporary directory.
+
+ This context manager is preferred over `NamedTemporaryFile` in
+ stdlib `tempfile` when one needs to reopen the file.
+
+ Arguments `mode` and `bufsize` are passed to `open`.
+ Rest of the arguments are passed to `TemporaryDirectory`.
+
+ """
+ self._tmpdir = TemporaryDirectory(**kwds)
+ path = _os.path.join(self._tmpdir.name, filename)
+ self.file = open(path, mode, bufsize)
+
+ def cleanup(self):
+ self.file.close()
+ self._tmpdir.cleanup()
+
+ __del__ = cleanup
+
+ def __enter__(self):
+ return self.file
+
+ def __exit__(self, type, value, traceback):
+ self.cleanup()
+
+
+class TemporaryWorkingDirectory(TemporaryDirectory):
+ """
+ Creates a temporary directory and sets the cwd to that directory.
+ Automatically reverts to previous cwd upon cleanup.
+ Usage example:
+
+ with TemporaryWorkingDirectory() as tmpdir:
+ ...
+ """
+ def __enter__(self):
+ self.old_wd = _os.getcwd()
+ _os.chdir(self.name)
+ return super(TemporaryWorkingDirectory, self).__enter__()
+
+ def __exit__(self, exc, value, tb):
+ _os.chdir(self.old_wd)
+ return super(TemporaryWorkingDirectory, self).__exit__(exc, value, tb)
diff --git a/contrib/python/ipython/py3/IPython/utils/terminal.py b/contrib/python/ipython/py3/IPython/utils/terminal.py
index b2f8e16513..4e1800208c 100644
--- a/contrib/python/ipython/py3/IPython/utils/terminal.py
+++ b/contrib/python/ipython/py3/IPython/utils/terminal.py
@@ -1,129 +1,129 @@
-# encoding: utf-8
-"""
-Utilities for working with terminals.
-
-Authors:
-
-* Brian E. Granger
-* Fernando Perez
-* Alexander Belchenko (e-mail: bialix AT ukr.net)
-"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-import os
-import sys
-import warnings
-from shutil import get_terminal_size as _get_terminal_size
-
-# This variable is part of the expected API of the module:
-ignore_termtitle = True
-
-
-
-if os.name == 'posix':
- def _term_clear():
- os.system('clear')
-elif sys.platform == 'win32':
- def _term_clear():
- os.system('cls')
-else:
- def _term_clear():
- pass
-
-
-
-def toggle_set_term_title(val):
- """Control whether set_term_title is active or not.
-
- set_term_title() allows writing to the console titlebar. In embedded
- widgets this can cause problems, so this call can be used to toggle it on
- or off as needed.
-
- The default state of the module is for the function to be disabled.
-
- Parameters
- ----------
- val : bool
- If True, set_term_title() actually writes to the terminal (using the
- appropriate platform-specific module). If False, it is a no-op.
- """
- global ignore_termtitle
- ignore_termtitle = not(val)
-
-
-def _set_term_title(*args,**kw):
- """Dummy no-op."""
- pass
-
-
-def _restore_term_title():
- pass
-
-
-def _set_term_title_xterm(title):
- """ Change virtual terminal title in xterm-workalikes """
- # save the current title to the xterm "stack"
- sys.stdout.write('\033[22;0t')
- sys.stdout.write('\033]0;%s\007' % title)
-
-
-def _restore_term_title_xterm():
- sys.stdout.write('\033[23;0t')
-
-
-if os.name == 'posix':
- TERM = os.environ.get('TERM','')
- if TERM.startswith('xterm'):
- _set_term_title = _set_term_title_xterm
- _restore_term_title = _restore_term_title_xterm
-elif sys.platform == 'win32':
- try:
- import ctypes
-
- SetConsoleTitleW = ctypes.windll.kernel32.SetConsoleTitleW
- SetConsoleTitleW.argtypes = [ctypes.c_wchar_p]
-
- def _set_term_title(title):
- """Set terminal title using ctypes to access the Win32 APIs."""
- SetConsoleTitleW(title)
- except ImportError:
- def _set_term_title(title):
- """Set terminal title using the 'title' command."""
- global ignore_termtitle
-
- try:
- # Cannot be on network share when issuing system commands
- curr = os.getcwd()
- os.chdir("C:")
- ret = os.system("title " + title)
- finally:
- os.chdir(curr)
- if ret:
- # non-zero return code signals error, don't try again
- ignore_termtitle = True
-
-
-def set_term_title(title):
- """Set terminal title using the necessary platform-dependent calls."""
- if ignore_termtitle:
- return
- _set_term_title(title)
-
-
-def restore_term_title():
- """Restore, if possible, terminal title to the original state"""
- if ignore_termtitle:
- return
- _restore_term_title()
-
-
-def freeze_term_title():
- warnings.warn("This function is deprecated, use toggle_set_term_title()")
- global ignore_termtitle
- ignore_termtitle = True
-
-
-def get_terminal_size(defaultx=80, defaulty=25):
- return _get_terminal_size((defaultx, defaulty))
+# encoding: utf-8
+"""
+Utilities for working with terminals.
+
+Authors:
+
+* Brian E. Granger
+* Fernando Perez
+* Alexander Belchenko (e-mail: bialix AT ukr.net)
+"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+import os
+import sys
+import warnings
+from shutil import get_terminal_size as _get_terminal_size
+
+# This variable is part of the expected API of the module:
+ignore_termtitle = True
+
+
+
+if os.name == 'posix':
+ def _term_clear():
+ os.system('clear')
+elif sys.platform == 'win32':
+ def _term_clear():
+ os.system('cls')
+else:
+ def _term_clear():
+ pass
+
+
+
+def toggle_set_term_title(val):
+ """Control whether set_term_title is active or not.
+
+ set_term_title() allows writing to the console titlebar. In embedded
+ widgets this can cause problems, so this call can be used to toggle it on
+ or off as needed.
+
+ The default state of the module is for the function to be disabled.
+
+ Parameters
+ ----------
+ val : bool
+ If True, set_term_title() actually writes to the terminal (using the
+ appropriate platform-specific module). If False, it is a no-op.
+ """
+ global ignore_termtitle
+ ignore_termtitle = not(val)
+
+
+def _set_term_title(*args,**kw):
+ """Dummy no-op."""
+ pass
+
+
+def _restore_term_title():
+ pass
+
+
+def _set_term_title_xterm(title):
+ """ Change virtual terminal title in xterm-workalikes """
+ # save the current title to the xterm "stack"
+ sys.stdout.write('\033[22;0t')
+ sys.stdout.write('\033]0;%s\007' % title)
+
+
+def _restore_term_title_xterm():
+ sys.stdout.write('\033[23;0t')
+
+
+if os.name == 'posix':
+ TERM = os.environ.get('TERM','')
+ if TERM.startswith('xterm'):
+ _set_term_title = _set_term_title_xterm
+ _restore_term_title = _restore_term_title_xterm
+elif sys.platform == 'win32':
+ try:
+ import ctypes
+
+ SetConsoleTitleW = ctypes.windll.kernel32.SetConsoleTitleW
+ SetConsoleTitleW.argtypes = [ctypes.c_wchar_p]
+
+ def _set_term_title(title):
+ """Set terminal title using ctypes to access the Win32 APIs."""
+ SetConsoleTitleW(title)
+ except ImportError:
+ def _set_term_title(title):
+ """Set terminal title using the 'title' command."""
+ global ignore_termtitle
+
+ try:
+ # Cannot be on network share when issuing system commands
+ curr = os.getcwd()
+ os.chdir("C:")
+ ret = os.system("title " + title)
+ finally:
+ os.chdir(curr)
+ if ret:
+ # non-zero return code signals error, don't try again
+ ignore_termtitle = True
+
+
+def set_term_title(title):
+ """Set terminal title using the necessary platform-dependent calls."""
+ if ignore_termtitle:
+ return
+ _set_term_title(title)
+
+
+def restore_term_title():
+ """Restore, if possible, terminal title to the original state"""
+ if ignore_termtitle:
+ return
+ _restore_term_title()
+
+
+def freeze_term_title():
+ warnings.warn("This function is deprecated, use toggle_set_term_title()")
+ global ignore_termtitle
+ ignore_termtitle = True
+
+
+def get_terminal_size(defaultx=80, defaulty=25):
+ return _get_terminal_size((defaultx, defaulty))
diff --git a/contrib/python/ipython/py3/IPython/utils/text.py b/contrib/python/ipython/py3/IPython/utils/text.py
index f590cbc18a..256fdab584 100644
--- a/contrib/python/ipython/py3/IPython/utils/text.py
+++ b/contrib/python/ipython/py3/IPython/utils/text.py
@@ -1,763 +1,763 @@
-# encoding: utf-8
-"""
-Utilities for working with strings and text.
-
-Inheritance diagram:
-
-.. inheritance-diagram:: IPython.utils.text
- :parts: 3
-"""
-
-import os
-import re
-import string
-import sys
-import textwrap
-from string import Formatter
-from pathlib import Path
-
-from IPython.utils import py3compat
-
-# datetime.strftime date format for ipython
-if sys.platform == 'win32':
- date_format = "%B %d, %Y"
-else:
- date_format = "%B %-d, %Y"
-
-class LSString(str):
- """String derivative with a special access attributes.
-
- These are normal strings, but with the special attributes:
-
- .l (or .list) : value as list (split on newlines).
- .n (or .nlstr): original value (the string itself).
- .s (or .spstr): value as whitespace-separated string.
- .p (or .paths): list of path objects (requires path.py package)
-
- Any values which require transformations are computed only once and
- cached.
-
- Such strings are very useful to efficiently interact with the shell, which
- typically only understands whitespace-separated options for commands."""
-
- def get_list(self):
- try:
- return self.__list
- except AttributeError:
- self.__list = self.split('\n')
- return self.__list
-
- l = list = property(get_list)
-
- def get_spstr(self):
- try:
- return self.__spstr
- except AttributeError:
- self.__spstr = self.replace('\n',' ')
- return self.__spstr
-
- s = spstr = property(get_spstr)
-
- def get_nlstr(self):
- return self
-
- n = nlstr = property(get_nlstr)
-
- def get_paths(self):
- try:
- return self.__paths
- except AttributeError:
- self.__paths = [Path(p) for p in self.split('\n') if os.path.exists(p)]
- return self.__paths
-
- p = paths = property(get_paths)
-
-# FIXME: We need to reimplement type specific displayhook and then add this
-# back as a custom printer. This should also be moved outside utils into the
-# core.
-
-# def print_lsstring(arg):
-# """ Prettier (non-repr-like) and more informative printer for LSString """
-# print "LSString (.p, .n, .l, .s available). Value:"
-# print arg
-#
-#
-# print_lsstring = result_display.register(LSString)(print_lsstring)
-
-
-class SList(list):
- """List derivative with a special access attributes.
-
- These are normal lists, but with the special attributes:
-
- * .l (or .list) : value as list (the list itself).
- * .n (or .nlstr): value as a string, joined on newlines.
- * .s (or .spstr): value as a string, joined on spaces.
- * .p (or .paths): list of path objects (requires path.py package)
-
- Any values which require transformations are computed only once and
- cached."""
-
- def get_list(self):
- return self
-
- l = list = property(get_list)
-
- def get_spstr(self):
- try:
- return self.__spstr
- except AttributeError:
- self.__spstr = ' '.join(self)
- return self.__spstr
-
- s = spstr = property(get_spstr)
-
- def get_nlstr(self):
- try:
- return self.__nlstr
- except AttributeError:
- self.__nlstr = '\n'.join(self)
- return self.__nlstr
-
- n = nlstr = property(get_nlstr)
-
- def get_paths(self):
- try:
- return self.__paths
- except AttributeError:
- self.__paths = [Path(p) for p in self if os.path.exists(p)]
- return self.__paths
-
- p = paths = property(get_paths)
-
- def grep(self, pattern, prune = False, field = None):
- """ Return all strings matching 'pattern' (a regex or callable)
-
- This is case-insensitive. If prune is true, return all items
- NOT matching the pattern.
-
- If field is specified, the match must occur in the specified
- whitespace-separated field.
-
- Examples::
-
- a.grep( lambda x: x.startswith('C') )
- a.grep('Cha.*log', prune=1)
- a.grep('chm', field=-1)
- """
-
- def match_target(s):
- if field is None:
- return s
- parts = s.split()
- try:
- tgt = parts[field]
- return tgt
- except IndexError:
- return ""
-
- if isinstance(pattern, str):
- pred = lambda x : re.search(pattern, x, re.IGNORECASE)
- else:
- pred = pattern
- if not prune:
- return SList([el for el in self if pred(match_target(el))])
- else:
- return SList([el for el in self if not pred(match_target(el))])
-
- def fields(self, *fields):
- """ Collect whitespace-separated fields from string list
-
- Allows quick awk-like usage of string lists.
-
- Example data (in var a, created by 'a = !ls -l')::
-
- -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
- drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
-
- * ``a.fields(0)`` is ``['-rwxrwxrwx', 'drwxrwxrwx+']``
- * ``a.fields(1,0)`` is ``['1 -rwxrwxrwx', '6 drwxrwxrwx+']``
- (note the joining by space).
- * ``a.fields(-1)`` is ``['ChangeLog', 'IPython']``
-
- IndexErrors are ignored.
-
- Without args, fields() just split()'s the strings.
- """
- if len(fields) == 0:
- return [el.split() for el in self]
-
- res = SList()
- for el in [f.split() for f in self]:
- lineparts = []
-
- for fd in fields:
- try:
- lineparts.append(el[fd])
- except IndexError:
- pass
- if lineparts:
- res.append(" ".join(lineparts))
-
- return res
-
- def sort(self,field= None, nums = False):
- """ sort by specified fields (see fields())
-
- Example::
-
- a.sort(1, nums = True)
-
- Sorts a by second field, in numerical order (so that 21 > 3)
-
- """
-
- #decorate, sort, undecorate
- if field is not None:
- dsu = [[SList([line]).fields(field), line] for line in self]
- else:
- dsu = [[line, line] for line in self]
- if nums:
- for i in range(len(dsu)):
- numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
- try:
- n = int(numstr)
- except ValueError:
- n = 0
- dsu[i][0] = n
-
-
- dsu.sort()
- return SList([t[1] for t in dsu])
-
-
-# FIXME: We need to reimplement type specific displayhook and then add this
-# back as a custom printer. This should also be moved outside utils into the
-# core.
-
-# def print_slist(arg):
-# """ Prettier (non-repr-like) and more informative printer for SList """
-# print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
-# if hasattr(arg, 'hideonce') and arg.hideonce:
-# arg.hideonce = False
-# return
-#
-# nlprint(arg) # This was a nested list printer, now removed.
-#
-# print_slist = result_display.register(SList)(print_slist)
-
-
-def indent(instr,nspaces=4, ntabs=0, flatten=False):
- """Indent a string a given number of spaces or tabstops.
-
- indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
-
- Parameters
- ----------
-
- instr : basestring
- The string to be indented.
- nspaces : int (default: 4)
- The number of spaces to be indented.
- ntabs : int (default: 0)
- The number of tabs to be indented.
- flatten : bool (default: False)
- Whether to scrub existing indentation. If True, all lines will be
- aligned to the same indentation. If False, existing indentation will
- be strictly increased.
-
- Returns
- -------
-
- str|unicode : string indented by ntabs and nspaces.
-
- """
- if instr is None:
- return
- ind = '\t'*ntabs+' '*nspaces
- if flatten:
- pat = re.compile(r'^\s*', re.MULTILINE)
- else:
- pat = re.compile(r'^', re.MULTILINE)
- outstr = re.sub(pat, ind, instr)
- if outstr.endswith(os.linesep+ind):
- return outstr[:-len(ind)]
- else:
- return outstr
-
-
-def list_strings(arg):
- """Always return a list of strings, given a string or list of strings
- as input.
-
- Examples
- --------
- ::
-
- In [7]: list_strings('A single string')
- Out[7]: ['A single string']
-
- In [8]: list_strings(['A single string in a list'])
- Out[8]: ['A single string in a list']
-
- In [9]: list_strings(['A','list','of','strings'])
- Out[9]: ['A', 'list', 'of', 'strings']
- """
-
- if isinstance(arg, str):
- return [arg]
- else:
- return arg
-
-
-def marquee(txt='',width=78,mark='*'):
- """Return the input string centered in a 'marquee'.
-
- Examples
- --------
- ::
-
- In [16]: marquee('A test',40)
- Out[16]: '**************** A test ****************'
-
- In [17]: marquee('A test',40,'-')
- Out[17]: '---------------- A test ----------------'
-
- In [18]: marquee('A test',40,' ')
- Out[18]: ' A test '
-
- """
- if not txt:
- return (mark*width)[:width]
- nmark = (width-len(txt)-2)//len(mark)//2
- if nmark < 0: nmark =0
- marks = mark*nmark
- return '%s %s %s' % (marks,txt,marks)
-
-
-ini_spaces_re = re.compile(r'^(\s+)')
-
-def num_ini_spaces(strng):
- """Return the number of initial spaces in a string"""
-
- ini_spaces = ini_spaces_re.match(strng)
- if ini_spaces:
- return ini_spaces.end()
- else:
- return 0
-
-
-def format_screen(strng):
- """Format a string for screen printing.
-
- This removes some latex-type format codes."""
- # Paragraph continue
- par_re = re.compile(r'\\$',re.MULTILINE)
- strng = par_re.sub('',strng)
- return strng
-
-
-def dedent(text):
- """Equivalent of textwrap.dedent that ignores unindented first line.
-
- This means it will still dedent strings like:
- '''foo
- is a bar
- '''
-
- For use in wrap_paragraphs.
- """
-
- if text.startswith('\n'):
- # text starts with blank line, don't ignore the first line
- return textwrap.dedent(text)
-
- # split first line
- splits = text.split('\n',1)
- if len(splits) == 1:
- # only one line
- return textwrap.dedent(text)
-
- first, rest = splits
- # dedent everything but the first line
- rest = textwrap.dedent(rest)
- return '\n'.join([first, rest])
-
-
-def wrap_paragraphs(text, ncols=80):
- """Wrap multiple paragraphs to fit a specified width.
-
- This is equivalent to textwrap.wrap, but with support for multiple
- paragraphs, as separated by empty lines.
-
- Returns
- -------
-
- list of complete paragraphs, wrapped to fill `ncols` columns.
- """
- paragraph_re = re.compile(r'\n(\s*\n)+', re.MULTILINE)
- text = dedent(text).strip()
- paragraphs = paragraph_re.split(text)[::2] # every other entry is space
- out_ps = []
- indent_re = re.compile(r'\n\s+', re.MULTILINE)
- for p in paragraphs:
- # presume indentation that survives dedent is meaningful formatting,
- # so don't fill unless text is flush.
- if indent_re.search(p) is None:
- # wrap paragraph
- p = textwrap.fill(p, ncols)
- out_ps.append(p)
- return out_ps
-
-
-def strip_email_quotes(text):
- """Strip leading email quotation characters ('>').
-
- Removes any combination of leading '>' interspersed with whitespace that
- appears *identically* in all lines of the input text.
-
- Parameters
- ----------
- text : str
-
- Examples
- --------
-
- Simple uses::
-
- In [2]: strip_email_quotes('> > text')
- Out[2]: 'text'
-
- In [3]: strip_email_quotes('> > text\\n> > more')
- Out[3]: 'text\\nmore'
-
- Note how only the common prefix that appears in all lines is stripped::
-
- In [4]: strip_email_quotes('> > text\\n> > more\\n> more...')
- Out[4]: '> text\\n> more\\nmore...'
-
- So if any line has no quote marks ('>'), then none are stripped from any
- of them ::
-
- In [5]: strip_email_quotes('> > text\\n> > more\\nlast different')
- Out[5]: '> > text\\n> > more\\nlast different'
- """
- lines = text.splitlines()
- strip_len = 0
-
- for characters in zip(*lines):
- # Check if all characters in this position are the same
- if len(set(characters)) > 1:
- break
- prefix_char = characters[0]
-
- if prefix_char in string.whitespace or prefix_char == ">":
- strip_len += 1
- else:
- break
-
- text = "\n".join([ln[strip_len:] for ln in lines])
- return text
-
-
-def strip_ansi(source):
- """
- Remove ansi escape codes from text.
-
- Parameters
- ----------
- source : str
- Source to remove the ansi from
- """
- return re.sub(r'\033\[(\d|;)+?m', '', source)
-
-
-class EvalFormatter(Formatter):
- """A String Formatter that allows evaluation of simple expressions.
-
- Note that this version interprets a : as specifying a format string (as per
- standard string formatting), so if slicing is required, you must explicitly
- create a slice.
-
- This is to be used in templating cases, such as the parallel batch
- script templates, where simple arithmetic on arguments is useful.
-
- Examples
- --------
- ::
-
- In [1]: f = EvalFormatter()
- In [2]: f.format('{n//4}', n=8)
- Out[2]: '2'
-
- In [3]: f.format("{greeting[slice(2,4)]}", greeting="Hello")
- Out[3]: 'll'
- """
- def get_field(self, name, args, kwargs):
- v = eval(name, kwargs)
- return v, name
-
-#XXX: As of Python 3.4, the format string parsing no longer splits on a colon
-# inside [], so EvalFormatter can handle slicing. Once we only support 3.4 and
-# above, it should be possible to remove FullEvalFormatter.
-
-class FullEvalFormatter(Formatter):
- """A String Formatter that allows evaluation of simple expressions.
-
- Any time a format key is not found in the kwargs,
- it will be tried as an expression in the kwargs namespace.
-
- Note that this version allows slicing using [1:2], so you cannot specify
- a format string. Use :class:`EvalFormatter` to permit format strings.
-
- Examples
- --------
- ::
-
- In [1]: f = FullEvalFormatter()
- In [2]: f.format('{n//4}', n=8)
- Out[2]: '2'
-
- In [3]: f.format('{list(range(5))[2:4]}')
- Out[3]: '[2, 3]'
-
- In [4]: f.format('{3*2}')
- Out[4]: '6'
- """
- # copied from Formatter._vformat with minor changes to allow eval
- # and replace the format_spec code with slicing
- def vformat(self, format_string:str, args, kwargs)->str:
- result = []
- for literal_text, field_name, format_spec, conversion in \
- self.parse(format_string):
-
- # output the literal text
- if literal_text:
- result.append(literal_text)
-
- # if there's a field, output it
- if field_name is not None:
- # this is some markup, find the object and do
- # the formatting
-
- if format_spec:
- # override format spec, to allow slicing:
- field_name = ':'.join([field_name, format_spec])
-
- # eval the contents of the field for the object
- # to be formatted
- obj = eval(field_name, kwargs)
-
- # do any conversion on the resulting object
- obj = self.convert_field(obj, conversion)
-
- # format the object and append to the result
- result.append(self.format_field(obj, ''))
-
- return ''.join(result)
-
-
-class DollarFormatter(FullEvalFormatter):
- """Formatter allowing Itpl style $foo replacement, for names and attribute
- access only. Standard {foo} replacement also works, and allows full
- evaluation of its arguments.
-
- Examples
- --------
- ::
-
- In [1]: f = DollarFormatter()
- In [2]: f.format('{n//4}', n=8)
- Out[2]: '2'
-
- In [3]: f.format('23 * 76 is $result', result=23*76)
- Out[3]: '23 * 76 is 1748'
-
- In [4]: f.format('$a or {b}', a=1, b=2)
- Out[4]: '1 or 2'
- """
- _dollar_pattern_ignore_single_quote = re.compile(r"(.*?)\$(\$?[\w\.]+)(?=([^']*'[^']*')*[^']*$)")
- def parse(self, fmt_string):
- for literal_txt, field_name, format_spec, conversion \
- in Formatter.parse(self, fmt_string):
-
- # Find $foo patterns in the literal text.
- continue_from = 0
- txt = ""
- for m in self._dollar_pattern_ignore_single_quote.finditer(literal_txt):
- new_txt, new_field = m.group(1,2)
- # $$foo --> $foo
- if new_field.startswith("$"):
- txt += new_txt + new_field
- else:
- yield (txt + new_txt, new_field, "", None)
- txt = ""
- continue_from = m.end()
-
- # Re-yield the {foo} style pattern
- yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
-
- def __repr__(self):
- return "<DollarFormatter>"
-
-#-----------------------------------------------------------------------------
-# Utils to columnize a list of string
-#-----------------------------------------------------------------------------
-
-def _col_chunks(l, max_rows, row_first=False):
- """Yield successive max_rows-sized column chunks from l."""
- if row_first:
- ncols = (len(l) // max_rows) + (len(l) % max_rows > 0)
- for i in range(ncols):
- yield [l[j] for j in range(i, len(l), ncols)]
- else:
- for i in range(0, len(l), max_rows):
- yield l[i:(i + max_rows)]
-
-
-def _find_optimal(rlist, row_first=False, separator_size=2, displaywidth=80):
- """Calculate optimal info to columnize a list of string"""
- for max_rows in range(1, len(rlist) + 1):
- col_widths = list(map(max, _col_chunks(rlist, max_rows, row_first)))
- sumlength = sum(col_widths)
- ncols = len(col_widths)
- if sumlength + separator_size * (ncols - 1) <= displaywidth:
- break
- return {'num_columns': ncols,
- 'optimal_separator_width': (displaywidth - sumlength) // (ncols - 1) if (ncols - 1) else 0,
- 'max_rows': max_rows,
- 'column_widths': col_widths
- }
-
-
-def _get_or_default(mylist, i, default=None):
- """return list item number, or default if don't exist"""
- if i >= len(mylist):
- return default
- else :
- return mylist[i]
-
-
-def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) :
- """Returns a nested list, and info to columnize items
-
- Parameters
- ----------
-
- items
- list of strings to columize
- row_first : (default False)
- Whether to compute columns for a row-first matrix instead of
- column-first (default).
- empty : (default None)
- default value to fill list if needed
- separator_size : int (default=2)
- How much characters will be used as a separation between each columns.
- displaywidth : int (default=80)
- The width of the area onto which the columns should enter
-
- Returns
- -------
-
- strings_matrix
-
- nested list of string, the outer most list contains as many list as
- rows, the innermost lists have each as many element as columns. If the
- total number of elements in `items` does not equal the product of
- rows*columns, the last element of some lists are filled with `None`.
-
- dict_info
- some info to make columnize easier:
-
- num_columns
- number of columns
- max_rows
- maximum number of rows (final number may be less)
- column_widths
- list of with of each columns
- optimal_separator_width
- best separator width between columns
-
- Examples
- --------
- ::
-
- In [1]: l = ['aaa','b','cc','d','eeeee','f','g','h','i','j','k','l']
- In [2]: list, info = compute_item_matrix(l, displaywidth=12)
- In [3]: list
- Out[3]: [['aaa', 'f', 'k'], ['b', 'g', 'l'], ['cc', 'h', None], ['d', 'i', None], ['eeeee', 'j', None]]
- In [4]: ideal = {'num_columns': 3, 'column_widths': [5, 1, 1], 'optimal_separator_width': 2, 'max_rows': 5}
- In [5]: all((info[k] == ideal[k] for k in ideal.keys()))
- Out[5]: True
- """
- info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs)
- nrow, ncol = info['max_rows'], info['num_columns']
- if row_first:
- return ([[_get_or_default(items, r * ncol + c, default=empty) for c in range(ncol)] for r in range(nrow)], info)
- else:
- return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info)
-
-
-def columnize(items, row_first=False, separator=' ', displaywidth=80, spread=False):
- """ Transform a list of strings into a single string with columns.
-
- Parameters
- ----------
- items : sequence of strings
- The strings to process.
-
- row_first : (default False)
- Whether to compute columns for a row-first matrix instead of
- column-first (default).
-
- separator : str, optional [default is two spaces]
- The string that separates columns.
-
- displaywidth : int, optional [default is 80]
- Width of the display in number of characters.
-
- Returns
- -------
- The formatted string.
- """
- if not items:
- return '\n'
- matrix, info = compute_item_matrix(items, row_first=row_first, separator_size=len(separator), displaywidth=displaywidth)
- if spread:
- separator = separator.ljust(int(info['optimal_separator_width']))
- fmatrix = [filter(None, x) for x in matrix]
- sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['column_widths'])])
- return '\n'.join(map(sjoin, fmatrix))+'\n'
-
-
-def get_text_list(list_, last_sep=' and ', sep=", ", wrap_item_with=""):
- """
- Return a string with a natural enumeration of items
-
- >>> get_text_list(['a', 'b', 'c', 'd'])
- 'a, b, c and d'
- >>> get_text_list(['a', 'b', 'c'], ' or ')
- 'a, b or c'
- >>> get_text_list(['a', 'b', 'c'], ', ')
- 'a, b, c'
- >>> get_text_list(['a', 'b'], ' or ')
- 'a or b'
- >>> get_text_list(['a'])
- 'a'
- >>> get_text_list([])
- ''
- >>> get_text_list(['a', 'b'], wrap_item_with="`")
- '`a` and `b`'
- >>> get_text_list(['a', 'b', 'c', 'd'], " = ", sep=" + ")
- 'a + b + c = d'
- """
- if len(list_) == 0:
- return ''
- if wrap_item_with:
- list_ = ['%s%s%s' % (wrap_item_with, item, wrap_item_with) for
- item in list_]
- if len(list_) == 1:
- return list_[0]
- return '%s%s%s' % (
- sep.join(i for i in list_[:-1]),
- last_sep, list_[-1])
+# encoding: utf-8
+"""
+Utilities for working with strings and text.
+
+Inheritance diagram:
+
+.. inheritance-diagram:: IPython.utils.text
+ :parts: 3
+"""
+
+import os
+import re
+import string
+import sys
+import textwrap
+from string import Formatter
+from pathlib import Path
+
+from IPython.utils import py3compat
+
+# datetime.strftime date format for ipython
+if sys.platform == 'win32':
+ date_format = "%B %d, %Y"
+else:
+ date_format = "%B %-d, %Y"
+
+class LSString(str):
+ """String derivative with a special access attributes.
+
+ These are normal strings, but with the special attributes:
+
+ .l (or .list) : value as list (split on newlines).
+ .n (or .nlstr): original value (the string itself).
+ .s (or .spstr): value as whitespace-separated string.
+ .p (or .paths): list of path objects (requires path.py package)
+
+ Any values which require transformations are computed only once and
+ cached.
+
+ Such strings are very useful to efficiently interact with the shell, which
+ typically only understands whitespace-separated options for commands."""
+
+ def get_list(self):
+ try:
+ return self.__list
+ except AttributeError:
+ self.__list = self.split('\n')
+ return self.__list
+
+ l = list = property(get_list)
+
+ def get_spstr(self):
+ try:
+ return self.__spstr
+ except AttributeError:
+ self.__spstr = self.replace('\n',' ')
+ return self.__spstr
+
+ s = spstr = property(get_spstr)
+
+ def get_nlstr(self):
+ return self
+
+ n = nlstr = property(get_nlstr)
+
+ def get_paths(self):
+ try:
+ return self.__paths
+ except AttributeError:
+ self.__paths = [Path(p) for p in self.split('\n') if os.path.exists(p)]
+ return self.__paths
+
+ p = paths = property(get_paths)
+
+# FIXME: We need to reimplement type specific displayhook and then add this
+# back as a custom printer. This should also be moved outside utils into the
+# core.
+
+# def print_lsstring(arg):
+# """ Prettier (non-repr-like) and more informative printer for LSString """
+# print "LSString (.p, .n, .l, .s available). Value:"
+# print arg
+#
+#
+# print_lsstring = result_display.register(LSString)(print_lsstring)
+
+
+class SList(list):
+ """List derivative with a special access attributes.
+
+ These are normal lists, but with the special attributes:
+
+ * .l (or .list) : value as list (the list itself).
+ * .n (or .nlstr): value as a string, joined on newlines.
+ * .s (or .spstr): value as a string, joined on spaces.
+ * .p (or .paths): list of path objects (requires path.py package)
+
+ Any values which require transformations are computed only once and
+ cached."""
+
+ def get_list(self):
+ return self
+
+ l = list = property(get_list)
+
+ def get_spstr(self):
+ try:
+ return self.__spstr
+ except AttributeError:
+ self.__spstr = ' '.join(self)
+ return self.__spstr
+
+ s = spstr = property(get_spstr)
+
+ def get_nlstr(self):
+ try:
+ return self.__nlstr
+ except AttributeError:
+ self.__nlstr = '\n'.join(self)
+ return self.__nlstr
+
+ n = nlstr = property(get_nlstr)
+
+ def get_paths(self):
+ try:
+ return self.__paths
+ except AttributeError:
+ self.__paths = [Path(p) for p in self if os.path.exists(p)]
+ return self.__paths
+
+ p = paths = property(get_paths)
+
+ def grep(self, pattern, prune = False, field = None):
+ """ Return all strings matching 'pattern' (a regex or callable)
+
+ This is case-insensitive. If prune is true, return all items
+ NOT matching the pattern.
+
+ If field is specified, the match must occur in the specified
+ whitespace-separated field.
+
+ Examples::
+
+ a.grep( lambda x: x.startswith('C') )
+ a.grep('Cha.*log', prune=1)
+ a.grep('chm', field=-1)
+ """
+
+ def match_target(s):
+ if field is None:
+ return s
+ parts = s.split()
+ try:
+ tgt = parts[field]
+ return tgt
+ except IndexError:
+ return ""
+
+ if isinstance(pattern, str):
+ pred = lambda x : re.search(pattern, x, re.IGNORECASE)
+ else:
+ pred = pattern
+ if not prune:
+ return SList([el for el in self if pred(match_target(el))])
+ else:
+ return SList([el for el in self if not pred(match_target(el))])
+
+ def fields(self, *fields):
+ """ Collect whitespace-separated fields from string list
+
+ Allows quick awk-like usage of string lists.
+
+ Example data (in var a, created by 'a = !ls -l')::
+
+ -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
+ drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
+
+ * ``a.fields(0)`` is ``['-rwxrwxrwx', 'drwxrwxrwx+']``
+ * ``a.fields(1,0)`` is ``['1 -rwxrwxrwx', '6 drwxrwxrwx+']``
+ (note the joining by space).
+ * ``a.fields(-1)`` is ``['ChangeLog', 'IPython']``
+
+ IndexErrors are ignored.
+
+ Without args, fields() just split()'s the strings.
+ """
+ if len(fields) == 0:
+ return [el.split() for el in self]
+
+ res = SList()
+ for el in [f.split() for f in self]:
+ lineparts = []
+
+ for fd in fields:
+ try:
+ lineparts.append(el[fd])
+ except IndexError:
+ pass
+ if lineparts:
+ res.append(" ".join(lineparts))
+
+ return res
+
+ def sort(self,field= None, nums = False):
+ """ sort by specified fields (see fields())
+
+ Example::
+
+ a.sort(1, nums = True)
+
+ Sorts a by second field, in numerical order (so that 21 > 3)
+
+ """
+
+ #decorate, sort, undecorate
+ if field is not None:
+ dsu = [[SList([line]).fields(field), line] for line in self]
+ else:
+ dsu = [[line, line] for line in self]
+ if nums:
+ for i in range(len(dsu)):
+ numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
+ try:
+ n = int(numstr)
+ except ValueError:
+ n = 0
+ dsu[i][0] = n
+
+
+ dsu.sort()
+ return SList([t[1] for t in dsu])
+
+
+# FIXME: We need to reimplement type specific displayhook and then add this
+# back as a custom printer. This should also be moved outside utils into the
+# core.
+
+# def print_slist(arg):
+# """ Prettier (non-repr-like) and more informative printer for SList """
+# print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
+# if hasattr(arg, 'hideonce') and arg.hideonce:
+# arg.hideonce = False
+# return
+#
+# nlprint(arg) # This was a nested list printer, now removed.
+#
+# print_slist = result_display.register(SList)(print_slist)
+
+
+def indent(instr,nspaces=4, ntabs=0, flatten=False):
+ """Indent a string a given number of spaces or tabstops.
+
+ indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
+
+ Parameters
+ ----------
+
+ instr : basestring
+ The string to be indented.
+ nspaces : int (default: 4)
+ The number of spaces to be indented.
+ ntabs : int (default: 0)
+ The number of tabs to be indented.
+ flatten : bool (default: False)
+ Whether to scrub existing indentation. If True, all lines will be
+ aligned to the same indentation. If False, existing indentation will
+ be strictly increased.
+
+ Returns
+ -------
+
+ str|unicode : string indented by ntabs and nspaces.
+
+ """
+ if instr is None:
+ return
+ ind = '\t'*ntabs+' '*nspaces
+ if flatten:
+ pat = re.compile(r'^\s*', re.MULTILINE)
+ else:
+ pat = re.compile(r'^', re.MULTILINE)
+ outstr = re.sub(pat, ind, instr)
+ if outstr.endswith(os.linesep+ind):
+ return outstr[:-len(ind)]
+ else:
+ return outstr
+
+
+def list_strings(arg):
+ """Always return a list of strings, given a string or list of strings
+ as input.
+
+ Examples
+ --------
+ ::
+
+ In [7]: list_strings('A single string')
+ Out[7]: ['A single string']
+
+ In [8]: list_strings(['A single string in a list'])
+ Out[8]: ['A single string in a list']
+
+ In [9]: list_strings(['A','list','of','strings'])
+ Out[9]: ['A', 'list', 'of', 'strings']
+ """
+
+ if isinstance(arg, str):
+ return [arg]
+ else:
+ return arg
+
+
+def marquee(txt='',width=78,mark='*'):
+ """Return the input string centered in a 'marquee'.
+
+ Examples
+ --------
+ ::
+
+ In [16]: marquee('A test',40)
+ Out[16]: '**************** A test ****************'
+
+ In [17]: marquee('A test',40,'-')
+ Out[17]: '---------------- A test ----------------'
+
+ In [18]: marquee('A test',40,' ')
+ Out[18]: ' A test '
+
+ """
+ if not txt:
+ return (mark*width)[:width]
+ nmark = (width-len(txt)-2)//len(mark)//2
+ if nmark < 0: nmark =0
+ marks = mark*nmark
+ return '%s %s %s' % (marks,txt,marks)
+
+
+ini_spaces_re = re.compile(r'^(\s+)')
+
+def num_ini_spaces(strng):
+ """Return the number of initial spaces in a string"""
+
+ ini_spaces = ini_spaces_re.match(strng)
+ if ini_spaces:
+ return ini_spaces.end()
+ else:
+ return 0
+
+
+def format_screen(strng):
+ """Format a string for screen printing.
+
+ This removes some latex-type format codes."""
+ # Paragraph continue
+ par_re = re.compile(r'\\$',re.MULTILINE)
+ strng = par_re.sub('',strng)
+ return strng
+
+
+def dedent(text):
+ """Equivalent of textwrap.dedent that ignores unindented first line.
+
+ This means it will still dedent strings like:
+ '''foo
+ is a bar
+ '''
+
+ For use in wrap_paragraphs.
+ """
+
+ if text.startswith('\n'):
+ # text starts with blank line, don't ignore the first line
+ return textwrap.dedent(text)
+
+ # split first line
+ splits = text.split('\n',1)
+ if len(splits) == 1:
+ # only one line
+ return textwrap.dedent(text)
+
+ first, rest = splits
+ # dedent everything but the first line
+ rest = textwrap.dedent(rest)
+ return '\n'.join([first, rest])
+
+
+def wrap_paragraphs(text, ncols=80):
+ """Wrap multiple paragraphs to fit a specified width.
+
+ This is equivalent to textwrap.wrap, but with support for multiple
+ paragraphs, as separated by empty lines.
+
+ Returns
+ -------
+
+ list of complete paragraphs, wrapped to fill `ncols` columns.
+ """
+ paragraph_re = re.compile(r'\n(\s*\n)+', re.MULTILINE)
+ text = dedent(text).strip()
+ paragraphs = paragraph_re.split(text)[::2] # every other entry is space
+ out_ps = []
+ indent_re = re.compile(r'\n\s+', re.MULTILINE)
+ for p in paragraphs:
+ # presume indentation that survives dedent is meaningful formatting,
+ # so don't fill unless text is flush.
+ if indent_re.search(p) is None:
+ # wrap paragraph
+ p = textwrap.fill(p, ncols)
+ out_ps.append(p)
+ return out_ps
+
+
+def strip_email_quotes(text):
+ """Strip leading email quotation characters ('>').
+
+ Removes any combination of leading '>' interspersed with whitespace that
+ appears *identically* in all lines of the input text.
+
+ Parameters
+ ----------
+ text : str
+
+ Examples
+ --------
+
+ Simple uses::
+
+ In [2]: strip_email_quotes('> > text')
+ Out[2]: 'text'
+
+ In [3]: strip_email_quotes('> > text\\n> > more')
+ Out[3]: 'text\\nmore'
+
+ Note how only the common prefix that appears in all lines is stripped::
+
+ In [4]: strip_email_quotes('> > text\\n> > more\\n> more...')
+ Out[4]: '> text\\n> more\\nmore...'
+
+ So if any line has no quote marks ('>'), then none are stripped from any
+ of them ::
+
+ In [5]: strip_email_quotes('> > text\\n> > more\\nlast different')
+ Out[5]: '> > text\\n> > more\\nlast different'
+ """
+ lines = text.splitlines()
+ strip_len = 0
+
+ for characters in zip(*lines):
+ # Check if all characters in this position are the same
+ if len(set(characters)) > 1:
+ break
+ prefix_char = characters[0]
+
+ if prefix_char in string.whitespace or prefix_char == ">":
+ strip_len += 1
+ else:
+ break
+
+ text = "\n".join([ln[strip_len:] for ln in lines])
+ return text
+
+
+def strip_ansi(source):
+ """
+ Remove ansi escape codes from text.
+
+ Parameters
+ ----------
+ source : str
+ Source to remove the ansi from
+ """
+ return re.sub(r'\033\[(\d|;)+?m', '', source)
+
+
+class EvalFormatter(Formatter):
+ """A String Formatter that allows evaluation of simple expressions.
+
+ Note that this version interprets a : as specifying a format string (as per
+ standard string formatting), so if slicing is required, you must explicitly
+ create a slice.
+
+ This is to be used in templating cases, such as the parallel batch
+ script templates, where simple arithmetic on arguments is useful.
+
+ Examples
+ --------
+ ::
+
+ In [1]: f = EvalFormatter()
+ In [2]: f.format('{n//4}', n=8)
+ Out[2]: '2'
+
+ In [3]: f.format("{greeting[slice(2,4)]}", greeting="Hello")
+ Out[3]: 'll'
+ """
+ def get_field(self, name, args, kwargs):
+ v = eval(name, kwargs)
+ return v, name
+
+#XXX: As of Python 3.4, the format string parsing no longer splits on a colon
+# inside [], so EvalFormatter can handle slicing. Once we only support 3.4 and
+# above, it should be possible to remove FullEvalFormatter.
+
+class FullEvalFormatter(Formatter):
+ """A String Formatter that allows evaluation of simple expressions.
+
+ Any time a format key is not found in the kwargs,
+ it will be tried as an expression in the kwargs namespace.
+
+ Note that this version allows slicing using [1:2], so you cannot specify
+ a format string. Use :class:`EvalFormatter` to permit format strings.
+
+ Examples
+ --------
+ ::
+
+ In [1]: f = FullEvalFormatter()
+ In [2]: f.format('{n//4}', n=8)
+ Out[2]: '2'
+
+ In [3]: f.format('{list(range(5))[2:4]}')
+ Out[3]: '[2, 3]'
+
+ In [4]: f.format('{3*2}')
+ Out[4]: '6'
+ """
+ # copied from Formatter._vformat with minor changes to allow eval
+ # and replace the format_spec code with slicing
+ def vformat(self, format_string:str, args, kwargs)->str:
+ result = []
+ for literal_text, field_name, format_spec, conversion in \
+ self.parse(format_string):
+
+ # output the literal text
+ if literal_text:
+ result.append(literal_text)
+
+ # if there's a field, output it
+ if field_name is not None:
+ # this is some markup, find the object and do
+ # the formatting
+
+ if format_spec:
+ # override format spec, to allow slicing:
+ field_name = ':'.join([field_name, format_spec])
+
+ # eval the contents of the field for the object
+ # to be formatted
+ obj = eval(field_name, kwargs)
+
+ # do any conversion on the resulting object
+ obj = self.convert_field(obj, conversion)
+
+ # format the object and append to the result
+ result.append(self.format_field(obj, ''))
+
+ return ''.join(result)
+
+
+class DollarFormatter(FullEvalFormatter):
+ """Formatter allowing Itpl style $foo replacement, for names and attribute
+ access only. Standard {foo} replacement also works, and allows full
+ evaluation of its arguments.
+
+ Examples
+ --------
+ ::
+
+ In [1]: f = DollarFormatter()
+ In [2]: f.format('{n//4}', n=8)
+ Out[2]: '2'
+
+ In [3]: f.format('23 * 76 is $result', result=23*76)
+ Out[3]: '23 * 76 is 1748'
+
+ In [4]: f.format('$a or {b}', a=1, b=2)
+ Out[4]: '1 or 2'
+ """
+ _dollar_pattern_ignore_single_quote = re.compile(r"(.*?)\$(\$?[\w\.]+)(?=([^']*'[^']*')*[^']*$)")
+ def parse(self, fmt_string):
+ for literal_txt, field_name, format_spec, conversion \
+ in Formatter.parse(self, fmt_string):
+
+ # Find $foo patterns in the literal text.
+ continue_from = 0
+ txt = ""
+ for m in self._dollar_pattern_ignore_single_quote.finditer(literal_txt):
+ new_txt, new_field = m.group(1,2)
+ # $$foo --> $foo
+ if new_field.startswith("$"):
+ txt += new_txt + new_field
+ else:
+ yield (txt + new_txt, new_field, "", None)
+ txt = ""
+ continue_from = m.end()
+
+ # Re-yield the {foo} style pattern
+ yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
+
+ def __repr__(self):
+ return "<DollarFormatter>"
+
+#-----------------------------------------------------------------------------
+# Utils to columnize a list of string
+#-----------------------------------------------------------------------------
+
+def _col_chunks(l, max_rows, row_first=False):
+ """Yield successive max_rows-sized column chunks from l."""
+ if row_first:
+ ncols = (len(l) // max_rows) + (len(l) % max_rows > 0)
+ for i in range(ncols):
+ yield [l[j] for j in range(i, len(l), ncols)]
+ else:
+ for i in range(0, len(l), max_rows):
+ yield l[i:(i + max_rows)]
+
+
+def _find_optimal(rlist, row_first=False, separator_size=2, displaywidth=80):
+ """Calculate optimal info to columnize a list of string"""
+ for max_rows in range(1, len(rlist) + 1):
+ col_widths = list(map(max, _col_chunks(rlist, max_rows, row_first)))
+ sumlength = sum(col_widths)
+ ncols = len(col_widths)
+ if sumlength + separator_size * (ncols - 1) <= displaywidth:
+ break
+ return {'num_columns': ncols,
+ 'optimal_separator_width': (displaywidth - sumlength) // (ncols - 1) if (ncols - 1) else 0,
+ 'max_rows': max_rows,
+ 'column_widths': col_widths
+ }
+
+
+def _get_or_default(mylist, i, default=None):
+ """return list item number, or default if don't exist"""
+ if i >= len(mylist):
+ return default
+ else :
+ return mylist[i]
+
+
+def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) :
+ """Returns a nested list, and info to columnize items
+
+ Parameters
+ ----------
+
+ items
+ list of strings to columize
+ row_first : (default False)
+ Whether to compute columns for a row-first matrix instead of
+ column-first (default).
+ empty : (default None)
+ default value to fill list if needed
+ separator_size : int (default=2)
+ How much characters will be used as a separation between each columns.
+ displaywidth : int (default=80)
+ The width of the area onto which the columns should enter
+
+ Returns
+ -------
+
+ strings_matrix
+
+ nested list of string, the outer most list contains as many list as
+ rows, the innermost lists have each as many element as columns. If the
+ total number of elements in `items` does not equal the product of
+ rows*columns, the last element of some lists are filled with `None`.
+
+ dict_info
+ some info to make columnize easier:
+
+ num_columns
+ number of columns
+ max_rows
+ maximum number of rows (final number may be less)
+ column_widths
+ list of with of each columns
+ optimal_separator_width
+ best separator width between columns
+
+ Examples
+ --------
+ ::
+
+ In [1]: l = ['aaa','b','cc','d','eeeee','f','g','h','i','j','k','l']
+ In [2]: list, info = compute_item_matrix(l, displaywidth=12)
+ In [3]: list
+ Out[3]: [['aaa', 'f', 'k'], ['b', 'g', 'l'], ['cc', 'h', None], ['d', 'i', None], ['eeeee', 'j', None]]
+ In [4]: ideal = {'num_columns': 3, 'column_widths': [5, 1, 1], 'optimal_separator_width': 2, 'max_rows': 5}
+ In [5]: all((info[k] == ideal[k] for k in ideal.keys()))
+ Out[5]: True
+ """
+ info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs)
+ nrow, ncol = info['max_rows'], info['num_columns']
+ if row_first:
+ return ([[_get_or_default(items, r * ncol + c, default=empty) for c in range(ncol)] for r in range(nrow)], info)
+ else:
+ return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info)
+
+
+def columnize(items, row_first=False, separator=' ', displaywidth=80, spread=False):
+ """ Transform a list of strings into a single string with columns.
+
+ Parameters
+ ----------
+ items : sequence of strings
+ The strings to process.
+
+ row_first : (default False)
+ Whether to compute columns for a row-first matrix instead of
+ column-first (default).
+
+ separator : str, optional [default is two spaces]
+ The string that separates columns.
+
+ displaywidth : int, optional [default is 80]
+ Width of the display in number of characters.
+
+ Returns
+ -------
+ The formatted string.
+ """
+ if not items:
+ return '\n'
+ matrix, info = compute_item_matrix(items, row_first=row_first, separator_size=len(separator), displaywidth=displaywidth)
+ if spread:
+ separator = separator.ljust(int(info['optimal_separator_width']))
+ fmatrix = [filter(None, x) for x in matrix]
+ sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['column_widths'])])
+ return '\n'.join(map(sjoin, fmatrix))+'\n'
+
+
+def get_text_list(list_, last_sep=' and ', sep=", ", wrap_item_with=""):
+ """
+ Return a string with a natural enumeration of items
+
+ >>> get_text_list(['a', 'b', 'c', 'd'])
+ 'a, b, c and d'
+ >>> get_text_list(['a', 'b', 'c'], ' or ')
+ 'a, b or c'
+ >>> get_text_list(['a', 'b', 'c'], ', ')
+ 'a, b, c'
+ >>> get_text_list(['a', 'b'], ' or ')
+ 'a or b'
+ >>> get_text_list(['a'])
+ 'a'
+ >>> get_text_list([])
+ ''
+ >>> get_text_list(['a', 'b'], wrap_item_with="`")
+ '`a` and `b`'
+ >>> get_text_list(['a', 'b', 'c', 'd'], " = ", sep=" + ")
+ 'a + b + c = d'
+ """
+ if len(list_) == 0:
+ return ''
+ if wrap_item_with:
+ list_ = ['%s%s%s' % (wrap_item_with, item, wrap_item_with) for
+ item in list_]
+ if len(list_) == 1:
+ return list_[0]
+ return '%s%s%s' % (
+ sep.join(i for i in list_[:-1]),
+ last_sep, list_[-1])
diff --git a/contrib/python/ipython/py3/IPython/utils/timing.py b/contrib/python/ipython/py3/IPython/utils/timing.py
index 187cfb3652..92f6883c4a 100644
--- a/contrib/python/ipython/py3/IPython/utils/timing.py
+++ b/contrib/python/ipython/py3/IPython/utils/timing.py
@@ -1,122 +1,122 @@
-# encoding: utf-8
-"""
-Utilities for timing code execution.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2008-2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-import time
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-
-# If possible (Unix), use the resource module instead of time.clock()
-try:
- import resource
-except ImportError:
- resource = None
-
-# Some implementations (like jyputerlite) don't have getrusage
-if resource is not None and hasattr(resource, "getrusage"):
- def clocku():
- """clocku() -> floating point number
-
- Return the *USER* CPU time in seconds since the start of the process.
- This is done via a call to resource.getrusage, so it avoids the
- wraparound problems in time.clock()."""
-
- return resource.getrusage(resource.RUSAGE_SELF)[0]
-
- def clocks():
- """clocks() -> floating point number
-
- Return the *SYSTEM* CPU time in seconds since the start of the process.
- This is done via a call to resource.getrusage, so it avoids the
- wraparound problems in time.clock()."""
-
- return resource.getrusage(resource.RUSAGE_SELF)[1]
-
- def clock():
- """clock() -> floating point number
-
- Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
- the process. This is done via a call to resource.getrusage, so it
- avoids the wraparound problems in time.clock()."""
-
- u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
- return u+s
-
- def clock2():
- """clock2() -> (t_user,t_system)
-
- Similar to clock(), but return a tuple of user/system times."""
- return resource.getrusage(resource.RUSAGE_SELF)[:2]
-
-else:
- # There is no distinction of user/system time under windows, so we just use
- # time.perff_counter() for everything...
- clocku = clocks = clock = time.perf_counter
- def clock2():
- """Under windows, system CPU time can't be measured.
-
- This just returns perf_counter() and zero."""
- return time.perf_counter(),0.0
-
-
-def timings_out(reps,func,*args,**kw):
- """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
-
- Execute a function reps times, return a tuple with the elapsed total
- CPU time in seconds, the time per call and the function's output.
-
- Under Unix, the return value is the sum of user+system time consumed by
- the process, computed via the resource module. This prevents problems
- related to the wraparound effect which the time.clock() function has.
-
- Under Windows the return value is in wall clock seconds. See the
- documentation for the time module for more details."""
-
- reps = int(reps)
- assert reps >=1, 'reps must be >= 1'
- if reps==1:
- start = clock()
- out = func(*args,**kw)
- tot_time = clock()-start
- else:
- rng = range(reps-1) # the last time is executed separately to store output
- start = clock()
- for dummy in rng: func(*args,**kw)
- out = func(*args,**kw) # one last time
- tot_time = clock()-start
- av_time = tot_time / reps
- return tot_time,av_time,out
-
-
-def timings(reps,func,*args,**kw):
- """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
-
- Execute a function reps times, return a tuple with the elapsed total CPU
- time in seconds and the time per call. These are just the first two values
- in timings_out()."""
-
- return timings_out(reps,func,*args,**kw)[0:2]
-
-
-def timing(func,*args,**kw):
- """timing(func,*args,**kw) -> t_total
-
- Execute a function once, return the elapsed total CPU time in
- seconds. This is just the first value in timings_out()."""
-
- return timings_out(1,func,*args,**kw)[0]
-
+# encoding: utf-8
+"""
+Utilities for timing code execution.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2008-2011 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+import time
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+# If possible (Unix), use the resource module instead of time.clock()
+try:
+ import resource
+except ImportError:
+ resource = None
+
+# Some implementations (like jyputerlite) don't have getrusage
+if resource is not None and hasattr(resource, "getrusage"):
+ def clocku():
+ """clocku() -> floating point number
+
+ Return the *USER* CPU time in seconds since the start of the process.
+ This is done via a call to resource.getrusage, so it avoids the
+ wraparound problems in time.clock()."""
+
+ return resource.getrusage(resource.RUSAGE_SELF)[0]
+
+ def clocks():
+ """clocks() -> floating point number
+
+ Return the *SYSTEM* CPU time in seconds since the start of the process.
+ This is done via a call to resource.getrusage, so it avoids the
+ wraparound problems in time.clock()."""
+
+ return resource.getrusage(resource.RUSAGE_SELF)[1]
+
+ def clock():
+ """clock() -> floating point number
+
+ Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
+ the process. This is done via a call to resource.getrusage, so it
+ avoids the wraparound problems in time.clock()."""
+
+ u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
+ return u+s
+
+ def clock2():
+ """clock2() -> (t_user,t_system)
+
+ Similar to clock(), but return a tuple of user/system times."""
+ return resource.getrusage(resource.RUSAGE_SELF)[:2]
+
+else:
+ # There is no distinction of user/system time under windows, so we just use
+ # time.perff_counter() for everything...
+ clocku = clocks = clock = time.perf_counter
+ def clock2():
+ """Under windows, system CPU time can't be measured.
+
+ This just returns perf_counter() and zero."""
+ return time.perf_counter(),0.0
+
+
+def timings_out(reps,func,*args,**kw):
+ """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
+
+ Execute a function reps times, return a tuple with the elapsed total
+ CPU time in seconds, the time per call and the function's output.
+
+ Under Unix, the return value is the sum of user+system time consumed by
+ the process, computed via the resource module. This prevents problems
+ related to the wraparound effect which the time.clock() function has.
+
+ Under Windows the return value is in wall clock seconds. See the
+ documentation for the time module for more details."""
+
+ reps = int(reps)
+ assert reps >=1, 'reps must be >= 1'
+ if reps==1:
+ start = clock()
+ out = func(*args,**kw)
+ tot_time = clock()-start
+ else:
+ rng = range(reps-1) # the last time is executed separately to store output
+ start = clock()
+ for dummy in rng: func(*args,**kw)
+ out = func(*args,**kw) # one last time
+ tot_time = clock()-start
+ av_time = tot_time / reps
+ return tot_time,av_time,out
+
+
+def timings(reps,func,*args,**kw):
+ """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
+
+ Execute a function reps times, return a tuple with the elapsed total CPU
+ time in seconds and the time per call. These are just the first two values
+ in timings_out()."""
+
+ return timings_out(reps,func,*args,**kw)[0:2]
+
+
+def timing(func,*args,**kw):
+ """timing(func,*args,**kw) -> t_total
+
+ Execute a function once, return the elapsed total CPU time in
+ seconds. This is just the first value in timings_out()."""
+
+ return timings_out(1,func,*args,**kw)[0]
+
diff --git a/contrib/python/ipython/py3/IPython/utils/tokenutil.py b/contrib/python/ipython/py3/IPython/utils/tokenutil.py
index bccf969541..28f8b6d526 100644
--- a/contrib/python/ipython/py3/IPython/utils/tokenutil.py
+++ b/contrib/python/ipython/py3/IPython/utils/tokenutil.py
@@ -1,130 +1,130 @@
-"""Token-related utilities"""
-
-# Copyright (c) IPython Development Team.
-# Distributed under the terms of the Modified BSD License.
-
-from collections import namedtuple
-from io import StringIO
-from keyword import iskeyword
-
-import tokenize
-
-
-Token = namedtuple('Token', ['token', 'text', 'start', 'end', 'line'])
-
-def generate_tokens(readline):
- """wrap generate_tokens to catch EOF errors"""
- try:
- for token in tokenize.generate_tokens(readline):
- yield token
- except tokenize.TokenError:
- # catch EOF error
- return
-
-def line_at_cursor(cell, cursor_pos=0):
- """Return the line in a cell at a given cursor position
-
- Used for calling line-based APIs that don't support multi-line input, yet.
-
- Parameters
- ----------
-
- cell: str
- multiline block of text
- cursor_pos: integer
- the cursor position
-
- Returns
- -------
-
- (line, offset): (string, integer)
- The line with the current cursor, and the character offset of the start of the line.
- """
- offset = 0
- lines = cell.splitlines(True)
- for line in lines:
- next_offset = offset + len(line)
- if not line.endswith('\n'):
- # If the last line doesn't have a trailing newline, treat it as if
- # it does so that the cursor at the end of the line still counts
- # as being on that line.
- next_offset += 1
- if next_offset > cursor_pos:
- break
- offset = next_offset
- else:
- line = ""
- return (line, offset)
-
-def token_at_cursor(cell, cursor_pos=0):
- """Get the token at a given cursor
-
- Used for introspection.
-
- Function calls are prioritized, so the token for the callable will be returned
- if the cursor is anywhere inside the call.
-
- Parameters
- ----------
-
- cell : unicode
- A block of Python code
- cursor_pos : int
- The location of the cursor in the block where the token should be found
- """
- names = []
- tokens = []
- call_names = []
-
- offsets = {1: 0} # lines start at 1
- for tup in generate_tokens(StringIO(cell).readline):
-
- tok = Token(*tup)
-
- # token, text, start, end, line = tup
- start_line, start_col = tok.start
- end_line, end_col = tok.end
- if end_line + 1 not in offsets:
- # keep track of offsets for each line
- lines = tok.line.splitlines(True)
- for lineno, line in enumerate(lines, start_line + 1):
- if lineno not in offsets:
- offsets[lineno] = offsets[lineno-1] + len(line)
-
- offset = offsets[start_line]
- # allow '|foo' to find 'foo' at the beginning of a line
- boundary = cursor_pos + 1 if start_col == 0 else cursor_pos
- if offset + start_col >= boundary:
- # current token starts after the cursor,
- # don't consume it
- break
-
- if tok.token == tokenize.NAME and not iskeyword(tok.text):
- if names and tokens and tokens[-1].token == tokenize.OP and tokens[-1].text == '.':
- names[-1] = "%s.%s" % (names[-1], tok.text)
- else:
- names.append(tok.text)
- elif tok.token == tokenize.OP:
- if tok.text == '=' and names:
- # don't inspect the lhs of an assignment
- names.pop(-1)
- if tok.text == '(' and names:
- # if we are inside a function call, inspect the function
- call_names.append(names[-1])
- elif tok.text == ')' and call_names:
- call_names.pop(-1)
-
- tokens.append(tok)
-
- if offsets[end_line] + end_col > cursor_pos:
- # we found the cursor, stop reading
- break
-
- if call_names:
- return call_names[-1]
- elif names:
- return names[-1]
- else:
- return ''
-
-
+"""Token-related utilities"""
+
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+from collections import namedtuple
+from io import StringIO
+from keyword import iskeyword
+
+import tokenize
+
+
+Token = namedtuple('Token', ['token', 'text', 'start', 'end', 'line'])
+
+def generate_tokens(readline):
+ """wrap generate_tokens to catch EOF errors"""
+ try:
+ for token in tokenize.generate_tokens(readline):
+ yield token
+ except tokenize.TokenError:
+ # catch EOF error
+ return
+
+def line_at_cursor(cell, cursor_pos=0):
+ """Return the line in a cell at a given cursor position
+
+ Used for calling line-based APIs that don't support multi-line input, yet.
+
+ Parameters
+ ----------
+
+ cell: str
+ multiline block of text
+ cursor_pos: integer
+ the cursor position
+
+ Returns
+ -------
+
+ (line, offset): (string, integer)
+ The line with the current cursor, and the character offset of the start of the line.
+ """
+ offset = 0
+ lines = cell.splitlines(True)
+ for line in lines:
+ next_offset = offset + len(line)
+ if not line.endswith('\n'):
+ # If the last line doesn't have a trailing newline, treat it as if
+ # it does so that the cursor at the end of the line still counts
+ # as being on that line.
+ next_offset += 1
+ if next_offset > cursor_pos:
+ break
+ offset = next_offset
+ else:
+ line = ""
+ return (line, offset)
+
+def token_at_cursor(cell, cursor_pos=0):
+ """Get the token at a given cursor
+
+ Used for introspection.
+
+ Function calls are prioritized, so the token for the callable will be returned
+ if the cursor is anywhere inside the call.
+
+ Parameters
+ ----------
+
+ cell : unicode
+ A block of Python code
+ cursor_pos : int
+ The location of the cursor in the block where the token should be found
+ """
+ names = []
+ tokens = []
+ call_names = []
+
+ offsets = {1: 0} # lines start at 1
+ for tup in generate_tokens(StringIO(cell).readline):
+
+ tok = Token(*tup)
+
+ # token, text, start, end, line = tup
+ start_line, start_col = tok.start
+ end_line, end_col = tok.end
+ if end_line + 1 not in offsets:
+ # keep track of offsets for each line
+ lines = tok.line.splitlines(True)
+ for lineno, line in enumerate(lines, start_line + 1):
+ if lineno not in offsets:
+ offsets[lineno] = offsets[lineno-1] + len(line)
+
+ offset = offsets[start_line]
+ # allow '|foo' to find 'foo' at the beginning of a line
+ boundary = cursor_pos + 1 if start_col == 0 else cursor_pos
+ if offset + start_col >= boundary:
+ # current token starts after the cursor,
+ # don't consume it
+ break
+
+ if tok.token == tokenize.NAME and not iskeyword(tok.text):
+ if names and tokens and tokens[-1].token == tokenize.OP and tokens[-1].text == '.':
+ names[-1] = "%s.%s" % (names[-1], tok.text)
+ else:
+ names.append(tok.text)
+ elif tok.token == tokenize.OP:
+ if tok.text == '=' and names:
+ # don't inspect the lhs of an assignment
+ names.pop(-1)
+ if tok.text == '(' and names:
+ # if we are inside a function call, inspect the function
+ call_names.append(names[-1])
+ elif tok.text == ')' and call_names:
+ call_names.pop(-1)
+
+ tokens.append(tok)
+
+ if offsets[end_line] + end_col > cursor_pos:
+ # we found the cursor, stop reading
+ break
+
+ if call_names:
+ return call_names[-1]
+ elif names:
+ return names[-1]
+ else:
+ return ''
+
+
diff --git a/contrib/python/ipython/py3/IPython/utils/traitlets.py b/contrib/python/ipython/py3/IPython/utils/traitlets.py
index de35a84b76..2f979fa727 100644
--- a/contrib/python/ipython/py3/IPython/utils/traitlets.py
+++ b/contrib/python/ipython/py3/IPython/utils/traitlets.py
@@ -1,6 +1,6 @@
-
-from warnings import warn
-
-warn("IPython.utils.traitlets has moved to a top-level traitlets package.", stacklevel=2)
-
-from traitlets import *
+
+from warnings import warn
+
+warn("IPython.utils.traitlets has moved to a top-level traitlets package.", stacklevel=2)
+
+from traitlets import *
diff --git a/contrib/python/ipython/py3/IPython/utils/tz.py b/contrib/python/ipython/py3/IPython/utils/tz.py
index 14172b2f4a..b315d532d1 100644
--- a/contrib/python/ipython/py3/IPython/utils/tz.py
+++ b/contrib/python/ipython/py3/IPython/utils/tz.py
@@ -1,46 +1,46 @@
-# encoding: utf-8
-"""
-Timezone utilities
-
-Just UTC-awareness right now
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2013 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-from datetime import tzinfo, timedelta, datetime
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-# constant for zero offset
-ZERO = timedelta(0)
-
-class tzUTC(tzinfo):
- """tzinfo object for UTC (zero offset)"""
-
- def utcoffset(self, d):
- return ZERO
-
- def dst(self, d):
- return ZERO
-
-UTC = tzUTC()
-
-def utc_aware(unaware):
- """decorator for adding UTC tzinfo to datetime's utcfoo methods"""
- def utc_method(*args, **kwargs):
- dt = unaware(*args, **kwargs)
- return dt.replace(tzinfo=UTC)
- return utc_method
-
-utcfromtimestamp = utc_aware(datetime.utcfromtimestamp)
-utcnow = utc_aware(datetime.utcnow)
+# encoding: utf-8
+"""
+Timezone utilities
+
+Just UTC-awareness right now
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2013 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from datetime import tzinfo, timedelta, datetime
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+# constant for zero offset
+ZERO = timedelta(0)
+
+class tzUTC(tzinfo):
+ """tzinfo object for UTC (zero offset)"""
+
+ def utcoffset(self, d):
+ return ZERO
+
+ def dst(self, d):
+ return ZERO
+
+UTC = tzUTC()
+
+def utc_aware(unaware):
+ """decorator for adding UTC tzinfo to datetime's utcfoo methods"""
+ def utc_method(*args, **kwargs):
+ dt = unaware(*args, **kwargs)
+ return dt.replace(tzinfo=UTC)
+ return utc_method
+
+utcfromtimestamp = utc_aware(datetime.utcfromtimestamp)
+utcnow = utc_aware(datetime.utcnow)
diff --git a/contrib/python/ipython/py3/IPython/utils/ulinecache.py b/contrib/python/ipython/py3/IPython/utils/ulinecache.py
index e0e2abdef3..0b4ede08e6 100644
--- a/contrib/python/ipython/py3/IPython/utils/ulinecache.py
+++ b/contrib/python/ipython/py3/IPython/utils/ulinecache.py
@@ -1,21 +1,21 @@
-"""
-This module has been deprecated since IPython 6.0.
-
-Wrapper around linecache which decodes files to unicode according to PEP 263.
-"""
-import functools
-import linecache
-from warnings import warn
-
-getline = linecache.getline
-
-# getlines has to be looked up at runtime, because doctests monkeypatch it.
-@functools.wraps(linecache.getlines)
-def getlines(filename, module_globals=None):
- """
- Deprecated since IPython 6.0
- """
- warn(("`IPython.utils.ulinecache.getlines` is deprecated since"
- " IPython 6.0 and will be removed in future versions."),
- DeprecationWarning, stacklevel=2)
- return linecache.getlines(filename, module_globals=module_globals)
+"""
+This module has been deprecated since IPython 6.0.
+
+Wrapper around linecache which decodes files to unicode according to PEP 263.
+"""
+import functools
+import linecache
+from warnings import warn
+
+getline = linecache.getline
+
+# getlines has to be looked up at runtime, because doctests monkeypatch it.
+@functools.wraps(linecache.getlines)
+def getlines(filename, module_globals=None):
+ """
+ Deprecated since IPython 6.0
+ """
+ warn(("`IPython.utils.ulinecache.getlines` is deprecated since"
+ " IPython 6.0 and will be removed in future versions."),
+ DeprecationWarning, stacklevel=2)
+ return linecache.getlines(filename, module_globals=module_globals)
diff --git a/contrib/python/ipython/py3/IPython/utils/version.py b/contrib/python/ipython/py3/IPython/utils/version.py
index 3d1018f7bd..1de0047e6b 100644
--- a/contrib/python/ipython/py3/IPython/utils/version.py
+++ b/contrib/python/ipython/py3/IPython/utils/version.py
@@ -1,36 +1,36 @@
-# encoding: utf-8
-"""
-Utilities for version comparison
-
-It is a bit ridiculous that we need these.
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2013 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
-
-from distutils.version import LooseVersion
-
-#-----------------------------------------------------------------------------
-# Code
-#-----------------------------------------------------------------------------
-
-def check_version(v, check):
- """check version string v >= check
-
- If dev/prerelease tags result in TypeError for string-number comparison,
- it is assumed that the dependency is satisfied.
- Users on dev branches are responsible for keeping their own packages up to date.
- """
- try:
- return LooseVersion(v) >= LooseVersion(check)
- except TypeError:
- return True
-
+# encoding: utf-8
+"""
+Utilities for version comparison
+
+It is a bit ridiculous that we need these.
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (C) 2013 The IPython Development Team
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from distutils.version import LooseVersion
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+def check_version(v, check):
+ """check version string v >= check
+
+ If dev/prerelease tags result in TypeError for string-number comparison,
+ it is assumed that the dependency is satisfied.
+ Users on dev branches are responsible for keeping their own packages up to date.
+ """
+ try:
+ return LooseVersion(v) >= LooseVersion(check)
+ except TypeError:
+ return True
+
diff --git a/contrib/python/ipython/py3/IPython/utils/wildcard.py b/contrib/python/ipython/py3/IPython/utils/wildcard.py
index 1df2540dd8..cbef8c5175 100644
--- a/contrib/python/ipython/py3/IPython/utils/wildcard.py
+++ b/contrib/python/ipython/py3/IPython/utils/wildcard.py
@@ -1,111 +1,111 @@
-# -*- coding: utf-8 -*-
-"""Support for wildcard pattern matching in object inspection.
-
-Authors
--------
-- Jörgen Stenarson <jorgen.stenarson@bostream.nu>
-- Thomas Kluyver
-"""
-
-#*****************************************************************************
-# Copyright (C) 2005 Jörgen Stenarson <jorgen.stenarson@bostream.nu>
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#*****************************************************************************
-
-import re
-import types
-
-from IPython.utils.dir2 import dir2
-
-def create_typestr2type_dicts(dont_include_in_type2typestr=["lambda"]):
- """Return dictionaries mapping lower case typename (e.g. 'tuple') to type
- objects from the types package, and vice versa."""
- typenamelist = [tname for tname in dir(types) if tname.endswith("Type")]
- typestr2type, type2typestr = {}, {}
-
- for tname in typenamelist:
- name = tname[:-4].lower() # Cut 'Type' off the end of the name
- obj = getattr(types, tname)
- typestr2type[name] = obj
- if name not in dont_include_in_type2typestr:
- type2typestr[obj] = name
- return typestr2type, type2typestr
-
-typestr2type, type2typestr = create_typestr2type_dicts()
-
-def is_type(obj, typestr_or_type):
- """is_type(obj, typestr_or_type) verifies if obj is of a certain type. It
- can take strings or actual python types for the second argument, i.e.
- 'tuple'<->TupleType. 'all' matches all types.
-
- TODO: Should be extended for choosing more than one type."""
- if typestr_or_type == "all":
- return True
- if type(typestr_or_type) == type:
- test_type = typestr_or_type
- else:
- test_type = typestr2type.get(typestr_or_type, False)
- if test_type:
- return isinstance(obj, test_type)
- return False
-
-def show_hidden(str, show_all=False):
- """Return true for strings starting with single _ if show_all is true."""
- return show_all or str.startswith("__") or not str.startswith("_")
-
-def dict_dir(obj):
- """Produce a dictionary of an object's attributes. Builds on dir2 by
- checking that a getattr() call actually succeeds."""
- ns = {}
- for key in dir2(obj):
- # This seemingly unnecessary try/except is actually needed
- # because there is code out there with metaclasses that
- # create 'write only' attributes, where a getattr() call
- # will fail even if the attribute appears listed in the
- # object's dictionary. Properties can actually do the same
- # thing. In particular, Traits use this pattern
- try:
- ns[key] = getattr(obj, key)
- except AttributeError:
- pass
- return ns
-
-def filter_ns(ns, name_pattern="*", type_pattern="all", ignore_case=True,
- show_all=True):
- """Filter a namespace dictionary by name pattern and item type."""
- pattern = name_pattern.replace("*",".*").replace("?",".")
- if ignore_case:
- reg = re.compile(pattern+"$", re.I)
- else:
- reg = re.compile(pattern+"$")
-
- # Check each one matches regex; shouldn't be hidden; of correct type.
- return dict((key,obj) for key, obj in ns.items() if reg.match(key) \
- and show_hidden(key, show_all) \
- and is_type(obj, type_pattern) )
-
-def list_namespace(namespace, type_pattern, filter, ignore_case=False, show_all=False):
- """Return dictionary of all objects in a namespace dictionary that match
- type_pattern and filter."""
- pattern_list=filter.split(".")
- if len(pattern_list) == 1:
- return filter_ns(namespace, name_pattern=pattern_list[0],
- type_pattern=type_pattern,
- ignore_case=ignore_case, show_all=show_all)
- else:
- # This is where we can change if all objects should be searched or
- # only modules. Just change the type_pattern to module to search only
- # modules
- filtered = filter_ns(namespace, name_pattern=pattern_list[0],
- type_pattern="all",
- ignore_case=ignore_case, show_all=show_all)
- results = {}
- for name, obj in filtered.items():
- ns = list_namespace(dict_dir(obj), type_pattern,
- ".".join(pattern_list[1:]),
- ignore_case=ignore_case, show_all=show_all)
- for inner_name, inner_obj in ns.items():
- results["%s.%s"%(name,inner_name)] = inner_obj
- return results
+# -*- coding: utf-8 -*-
+"""Support for wildcard pattern matching in object inspection.
+
+Authors
+-------
+- Jörgen Stenarson <jorgen.stenarson@bostream.nu>
+- Thomas Kluyver
+"""
+
+#*****************************************************************************
+# Copyright (C) 2005 Jörgen Stenarson <jorgen.stenarson@bostream.nu>
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+#*****************************************************************************
+
+import re
+import types
+
+from IPython.utils.dir2 import dir2
+
+def create_typestr2type_dicts(dont_include_in_type2typestr=["lambda"]):
+ """Return dictionaries mapping lower case typename (e.g. 'tuple') to type
+ objects from the types package, and vice versa."""
+ typenamelist = [tname for tname in dir(types) if tname.endswith("Type")]
+ typestr2type, type2typestr = {}, {}
+
+ for tname in typenamelist:
+ name = tname[:-4].lower() # Cut 'Type' off the end of the name
+ obj = getattr(types, tname)
+ typestr2type[name] = obj
+ if name not in dont_include_in_type2typestr:
+ type2typestr[obj] = name
+ return typestr2type, type2typestr
+
+typestr2type, type2typestr = create_typestr2type_dicts()
+
+def is_type(obj, typestr_or_type):
+ """is_type(obj, typestr_or_type) verifies if obj is of a certain type. It
+ can take strings or actual python types for the second argument, i.e.
+ 'tuple'<->TupleType. 'all' matches all types.
+
+ TODO: Should be extended for choosing more than one type."""
+ if typestr_or_type == "all":
+ return True
+ if type(typestr_or_type) == type:
+ test_type = typestr_or_type
+ else:
+ test_type = typestr2type.get(typestr_or_type, False)
+ if test_type:
+ return isinstance(obj, test_type)
+ return False
+
+def show_hidden(str, show_all=False):
+ """Return true for strings starting with single _ if show_all is true."""
+ return show_all or str.startswith("__") or not str.startswith("_")
+
+def dict_dir(obj):
+ """Produce a dictionary of an object's attributes. Builds on dir2 by
+ checking that a getattr() call actually succeeds."""
+ ns = {}
+ for key in dir2(obj):
+ # This seemingly unnecessary try/except is actually needed
+ # because there is code out there with metaclasses that
+ # create 'write only' attributes, where a getattr() call
+ # will fail even if the attribute appears listed in the
+ # object's dictionary. Properties can actually do the same
+ # thing. In particular, Traits use this pattern
+ try:
+ ns[key] = getattr(obj, key)
+ except AttributeError:
+ pass
+ return ns
+
+def filter_ns(ns, name_pattern="*", type_pattern="all", ignore_case=True,
+ show_all=True):
+ """Filter a namespace dictionary by name pattern and item type."""
+ pattern = name_pattern.replace("*",".*").replace("?",".")
+ if ignore_case:
+ reg = re.compile(pattern+"$", re.I)
+ else:
+ reg = re.compile(pattern+"$")
+
+ # Check each one matches regex; shouldn't be hidden; of correct type.
+ return dict((key,obj) for key, obj in ns.items() if reg.match(key) \
+ and show_hidden(key, show_all) \
+ and is_type(obj, type_pattern) )
+
+def list_namespace(namespace, type_pattern, filter, ignore_case=False, show_all=False):
+ """Return dictionary of all objects in a namespace dictionary that match
+ type_pattern and filter."""
+ pattern_list=filter.split(".")
+ if len(pattern_list) == 1:
+ return filter_ns(namespace, name_pattern=pattern_list[0],
+ type_pattern=type_pattern,
+ ignore_case=ignore_case, show_all=show_all)
+ else:
+ # This is where we can change if all objects should be searched or
+ # only modules. Just change the type_pattern to module to search only
+ # modules
+ filtered = filter_ns(namespace, name_pattern=pattern_list[0],
+ type_pattern="all",
+ ignore_case=ignore_case, show_all=show_all)
+ results = {}
+ for name, obj in filtered.items():
+ ns = list_namespace(dict_dir(obj), type_pattern,
+ ".".join(pattern_list[1:]),
+ ignore_case=ignore_case, show_all=show_all)
+ for inner_name, inner_obj in ns.items():
+ results["%s.%s"%(name,inner_name)] = inner_obj
+ return results