Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
331
venv/Lib/site-packages/IPython/utils/PyColorize.py
Normal file
331
venv/Lib/site-packages/IPython/utils/PyColorize.py
Normal file
|
@ -0,0 +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))
|
0
venv/Lib/site-packages/IPython/utils/__init__.py
Normal file
0
venv/Lib/site-packages/IPython/utils/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
78
venv/Lib/site-packages/IPython/utils/_process_cli.py
Normal file
78
venv/Lib/site-packages/IPython/utils/_process_cli.py
Normal file
|
@ -0,0 +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
|
212
venv/Lib/site-packages/IPython/utils/_process_common.py
Normal file
212
venv/Lib/site-packages/IPython/utils/_process_common.py
Normal file
|
@ -0,0 +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
|
225
venv/Lib/site-packages/IPython/utils/_process_posix.py
Normal file
225
venv/Lib/site-packages/IPython/utils/_process_posix.py
Normal file
|
@ -0,0 +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
|
205
venv/Lib/site-packages/IPython/utils/_process_win32.py
Normal file
205
venv/Lib/site-packages/IPython/utils/_process_win32.py
Normal file
|
@ -0,0 +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))
|
|
@ -0,0 +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!")
|
2
venv/Lib/site-packages/IPython/utils/_sysinfo.py
Normal file
2
venv/Lib/site-packages/IPython/utils/_sysinfo.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
# GENERATED BY setup.py
|
||||
commit = u"2486838d9"
|
170
venv/Lib/site-packages/IPython/utils/capture.py
Normal file
170
venv/Lib/site-packages/IPython/utils/capture.py
Normal file
|
@ -0,0 +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
|
25
venv/Lib/site-packages/IPython/utils/colorable.py
Normal file
25
venv/Lib/site-packages/IPython/utils/colorable.py
Normal file
|
@ -0,0 +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)
|
||||
|
187
venv/Lib/site-packages/IPython/utils/coloransi.py
Normal file
187
venv/Lib/site-packages/IPython/utils/coloransi.py
Normal file
|
@ -0,0 +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]
|
74
venv/Lib/site-packages/IPython/utils/contexts.py
Normal file
74
venv/Lib/site-packages/IPython/utils/contexts.py
Normal file
|
@ -0,0 +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
|
4
venv/Lib/site-packages/IPython/utils/daemonize.py
Normal file
4
venv/Lib/site-packages/IPython/utils/daemonize.py
Normal file
|
@ -0,0 +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
|
30
venv/Lib/site-packages/IPython/utils/data.py
Normal file
30
venv/Lib/site-packages/IPython/utils/data.py
Normal file
|
@ -0,0 +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)]
|
||||
|
||||
|
58
venv/Lib/site-packages/IPython/utils/decorators.py
Normal file
58
venv/Lib/site-packages/IPython/utils/decorators.py
Normal file
|
@ -0,0 +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
|
||||
|
84
venv/Lib/site-packages/IPython/utils/dir2.py
Normal file
84
venv/Lib/site-packages/IPython/utils/dir2.py
Normal file
|
@ -0,0 +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
|
71
venv/Lib/site-packages/IPython/utils/encoding.py
Normal file
71
venv/Lib/site-packages/IPython/utils/encoding.py
Normal file
|
@ -0,0 +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()
|
6
venv/Lib/site-packages/IPython/utils/eventful.py
Normal file
6
venv/Lib/site-packages/IPython/utils/eventful.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
from warnings import warn
|
||||
|
||||
warn("IPython.utils.eventful has moved to traitlets.eventful", stacklevel=2)
|
||||
|
||||
from traitlets.eventful import *
|
94
venv/Lib/site-packages/IPython/utils/frame.py
Normal file
94
venv/Lib/site-packages/IPython/utils/frame.py
Normal file
|
@ -0,0 +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)
|
30
venv/Lib/site-packages/IPython/utils/generics.py
Normal file
30
venv/Lib/site-packages/IPython/utils/generics.py
Normal file
|
@ -0,0 +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
|
39
venv/Lib/site-packages/IPython/utils/importstring.py
Normal file
39
venv/Lib/site-packages/IPython/utils/importstring.py
Normal file
|
@ -0,0 +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])
|
248
venv/Lib/site-packages/IPython/utils/io.py
Normal file
248
venv/Lib/site-packages/IPython/utils/io.py
Normal file
|
@ -0,0 +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)
|
391
venv/Lib/site-packages/IPython/utils/ipstruct.py
Normal file
391
venv/Lib/site-packages/IPython/utils/ipstruct.py
Normal file
|
@ -0,0 +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])
|
||||
|
5
venv/Lib/site-packages/IPython/utils/jsonutil.py
Normal file
5
venv/Lib/site-packages/IPython/utils/jsonutil.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from warnings import warn
|
||||
|
||||
warn("IPython.utils.jsonutil has moved to jupyter_client.jsonutil", stacklevel=2)
|
||||
|
||||
from jupyter_client.jsonutil import *
|
5
venv/Lib/site-packages/IPython/utils/localinterfaces.py
Normal file
5
venv/Lib/site-packages/IPython/utils/localinterfaces.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from warnings import warn
|
||||
|
||||
warn("IPython.utils.localinterfaces has moved to jupyter_client.localinterfaces", stacklevel=2)
|
||||
|
||||
from jupyter_client.localinterfaces import *
|
6
venv/Lib/site-packages/IPython/utils/log.py
Normal file
6
venv/Lib/site-packages/IPython/utils/log.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
from warnings import warn
|
||||
|
||||
warn("IPython.utils.log has moved to traitlets.log", stacklevel=2)
|
||||
|
||||
from traitlets.log import *
|
70
venv/Lib/site-packages/IPython/utils/module_paths.py
Normal file
70
venv/Lib/site-packages/IPython/utils/module_paths.py
Normal file
|
@ -0,0 +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
|
103
venv/Lib/site-packages/IPython/utils/openpy.py
Normal file
103
venv/Lib/site-packages/IPython/utils/openpy.py
Normal file
|
@ -0,0 +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)
|
436
venv/Lib/site-packages/IPython/utils/path.py
Normal file
436
venv/Lib/site-packages/IPython/utils/path.py
Normal file
|
@ -0,0 +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)
|
5
venv/Lib/site-packages/IPython/utils/pickleutil.py
Normal file
5
venv/Lib/site-packages/IPython/utils/pickleutil.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from warnings import warn
|
||||
|
||||
warn("IPython.utils.pickleutil has moved to ipykernel.pickleutil", stacklevel=2)
|
||||
|
||||
from ipykernel.pickleutil import *
|
69
venv/Lib/site-packages/IPython/utils/process.py
Normal file
69
venv/Lib/site-packages/IPython/utils/process.py
Normal file
|
@ -0,0 +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))
|
191
venv/Lib/site-packages/IPython/utils/py3compat.py
Normal file
191
venv/Lib/site-packages/IPython/utils/py3compat.py
Normal file
|
@ -0,0 +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
|
||||
|
17
venv/Lib/site-packages/IPython/utils/sentinel.py
Normal file
17
venv/Lib/site-packages/IPython/utils/sentinel.py
Normal file
|
@ -0,0 +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
|
||||
|
94
venv/Lib/site-packages/IPython/utils/shimmodule.py
Normal file
94
venv/Lib/site-packages/IPython/utils/shimmodule.py
Normal file
|
@ -0,0 +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)
|
12
venv/Lib/site-packages/IPython/utils/signatures.py
Normal file
12
venv/Lib/site-packages/IPython/utils/signatures.py
Normal file
|
@ -0,0 +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
|
68
venv/Lib/site-packages/IPython/utils/strdispatch.py
Normal file
68
venv/Lib/site-packages/IPython/utils/strdispatch.py
Normal file
|
@ -0,0 +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
|
166
venv/Lib/site-packages/IPython/utils/sysinfo.py
Normal file
166
venv/Lib/site-packages/IPython/utils/sysinfo.py
Normal file
|
@ -0,0 +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
|
||||
|
62
venv/Lib/site-packages/IPython/utils/syspathcontext.py
Normal file
62
venv/Lib/site-packages/IPython/utils/syspathcontext.py
Normal file
|
@ -0,0 +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
|
57
venv/Lib/site-packages/IPython/utils/tempdir.py
Normal file
57
venv/Lib/site-packages/IPython/utils/tempdir.py
Normal file
|
@ -0,0 +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)
|
129
venv/Lib/site-packages/IPython/utils/terminal.py
Normal file
129
venv/Lib/site-packages/IPython/utils/terminal.py
Normal file
|
@ -0,0 +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))
|
0
venv/Lib/site-packages/IPython/utils/tests/__init__.py
Normal file
0
venv/Lib/site-packages/IPython/utils/tests/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue