##// END OF EJS Templates
ipython_directive: Adjust doc examples for reproducibility....
ipython_directive: Adjust doc examples for reproducibility. Before this change, building the documentation twice in a row in an environment configured for reproducible bulids would result in discrepancies such as: diff -ru /gnu/store/...-python-ipython-documentation-8.2.0/share/doc/python-ipython-documentation-8.2.0/html/sphinxext.html /gnu/store/...-python-ipython-documentation-8.2.0-check/share/doc/python-ipython-documentation-8.2.0/html/sphinxext.html --- /gnu/store/...-python-ipython-documentation-8.2.0/share/doc/python-ipython-documentation-8.2.0/html/sphinxext.html 1969-12-31 19:00:01.000000000 -0500 +++ /gnu/store/...-python-ipython-documentation-8.2.0-check/share/doc/python-ipython-documentation-8.2.0/html/sphinxext.html 1969-12-31 19:00:01.000000000 -0500 @@ -682,7 +682,7 @@ <span class="gp">In [2]: </span><span class="kn">import</span> <span class="nn">datetime</span> <span class="gp"> ...: </span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="gp"> ...: </span> -<span class="gh">Out[2]: </span><span class="go">datetime.datetime(2022, 4, 17, 3, 21, 14, 978155)</span> +<span class="gh">Out[2]: </span><span class="go">datetime.datetime(2022, 4, 17, 3, 37, 37, 115081)</span> </pre></div> </div> <p>It supports IPython construct that plain @@ -690,7 +690,7 @@ <div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [3]: </span><span class="kn">import</span> <span class="nn">time</span> <span class="gp">In [4]: </span><span class="o">%</span><span class="k">timeit</span> time.sleep(0.05) -<span class="go">50.2 ms +- 104 us per loop (mean +- std. dev. of 7 runs, 10 loops each)</span> +<span class="go">50.1 ms +- 8.86 us per loop (mean +- std. dev. of 7 runs, 10 loops each)</span> </pre></div> </div> <p>This will also support top-level async when using IPython 7.0+</p> * IPython/sphinxext/ipython_directive.py: Use a fixed date string in the datetime example, and replace the %timeit example by %pdoc, whole output is static.

File last commit:

r26993:8a04efad
r27687:71d665c4
Show More
_process_win32.py
184 lines | 6.0 KiB | text/x-python | PythonLexer
"""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 _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))