Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e6aab7f

Browse files
authored
Merge pull request #13191 from Carreau/fix-loop
Try to fix some of current failures.
2 parents 16bad32 + f7213ea commit e6aab7f

4 files changed

Lines changed: 101 additions & 27 deletions

File tree

.github/workflows/python-package.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
build:
1414

1515
runs-on: ubuntu-latest
16+
timeout-minutes: 10
1617
strategy:
1718
matrix:
1819
python-version: [3.8]

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ jobs:
4545
cp /tmp/.coverage ./
4646
- name: pytest
4747
run: |
48-
pytest
48+
pytest -v
4949
- name: Upload coverage to Codecov
5050
uses: codecov/codecov-action@v2

IPython/core/magics/script.py

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,23 @@
33
# Copyright (c) IPython Development Team.
44
# Distributed under the terms of the Modified BSD License.
55

6+
import asyncio
7+
import atexit
68
import errno
9+
import functools
710
import os
8-
import sys
911
import signal
12+
import sys
1013
import time
11-
import asyncio
12-
import atexit
13-
14+
from contextlib import contextmanager
1415
from subprocess import CalledProcessError
1516

17+
from traitlets import Dict, List, default
18+
1619
from IPython.core import magic_arguments
17-
from IPython.core.magic import (
18-
Magics, magics_class, line_magic, cell_magic
19-
)
20+
from IPython.core.magic import Magics, cell_magic, line_magic, magics_class
2021
from IPython.lib.backgroundjobs import BackgroundJobManager
2122
from IPython.utils.process import arg_split
22-
from traitlets import List, Dict, default
23-
2423

2524
#-----------------------------------------------------------------------------
2625
# Magic implementation classes
@@ -67,6 +66,41 @@ def script_args(f):
6766
f = arg(f)
6867
return f
6968

69+
70+
@contextmanager
71+
def safe_watcher():
72+
if sys.platform == "win32":
73+
yield
74+
return
75+
76+
from asyncio import SafeChildWatcher
77+
78+
policy = asyncio.get_event_loop_policy()
79+
old_watcher = policy.get_child_watcher()
80+
if isinstance(old_watcher, SafeChildWatcher):
81+
yield
82+
return
83+
84+
loop = asyncio.get_event_loop()
85+
try:
86+
watcher = asyncio.SafeChildWatcher()
87+
watcher.attach_loop(loop)
88+
policy.set_child_watcher(watcher)
89+
yield
90+
finally:
91+
watcher.close()
92+
policy.set_child_watcher(old_watcher)
93+
94+
95+
def dec_safe_watcher(fun):
96+
@functools.wraps(fun)
97+
def _inner(*args, **kwargs):
98+
with safe_watcher():
99+
return fun(*args, **kwargs)
100+
101+
return _inner
102+
103+
70104
@magics_class
71105
class ScriptMagics(Magics):
72106
"""Magics for talking to scripts
@@ -157,6 +191,7 @@ def named_script_magic(line, cell):
157191
@magic_arguments.magic_arguments()
158192
@script_args
159193
@cell_magic("script")
194+
@dec_safe_watcher
160195
def shebang(self, line, cell):
161196
"""Run a cell via a shell command
162197
@@ -204,7 +239,6 @@ async def _stream_communicate(process, cell):
204239
if sys.platform.startswith("win"):
205240
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
206241
loop = asyncio.get_event_loop()
207-
208242
argv = arg_split(line, posix=not sys.platform.startswith("win"))
209243
args, cmd = self.shebang.parser.parse_known_args(argv)
210244
try:

IPython/core/tests/test_magic.py

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,42 @@
44
Needs to be run by nose (to make ipython session available).
55
"""
66

7+
import asyncio
78
import io
89
import os
910
import re
11+
import shlex
1012
import sys
1113
import warnings
12-
from textwrap import dedent
13-
from unittest import TestCase
14-
from unittest import mock
1514
from importlib import invalidate_caches
1615
from io import StringIO
1716
from pathlib import Path
17+
from textwrap import dedent
18+
from unittest import TestCase, mock
1819

1920
import nose.tools as nt
2021

21-
import shlex
22+
import pytest
2223

2324
from IPython import get_ipython
2425
from IPython.core import magic
2526
from IPython.core.error import UsageError
26-
from IPython.core.magic import (Magics, magics_class, line_magic,
27-
cell_magic,
28-
register_line_magic, register_cell_magic)
29-
from IPython.core.magics import execution, script, code, logging, osm
27+
from IPython.core.magic import (
28+
Magics,
29+
cell_magic,
30+
line_magic,
31+
magics_class,
32+
register_cell_magic,
33+
register_line_magic,
34+
)
35+
from IPython.core.magics import code, execution, logging, osm, script
3036
from IPython.testing import decorators as dec
3137
from IPython.testing import tools as tt
3238
from IPython.utils.io import capture_output
33-
from IPython.utils.tempdir import (TemporaryDirectory,
34-
TemporaryWorkingDirectory)
3539
from IPython.utils.process import find_cmd
36-
from .test_debugger import PdbTestInput
40+
from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
3741

38-
import pytest
42+
from .test_debugger import PdbTestInput
3943

4044

4145
@magic.magics_class
@@ -947,41 +951,76 @@ def test_script_config():
947951
sm = script.ScriptMagics(shell=ip)
948952
nt.assert_in('whoda', sm.magics['cell'])
949953

954+
@dec.skip_iptest_but_not_pytest
950955
@dec.skip_win32
956+
@pytest.mark.skipif(
957+
sys.platform == "win32", reason="This test does not run under Windows"
958+
)
951959
def test_script_out():
960+
assert asyncio.get_event_loop().is_running() is False
961+
952962
ip = get_ipython()
953963
ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
964+
assert asyncio.get_event_loop().is_running() is False
954965
nt.assert_equal(ip.user_ns['output'], 'hi\n')
955966

967+
@dec.skip_iptest_but_not_pytest
956968
@dec.skip_win32
969+
@pytest.mark.skipif(
970+
sys.platform == "win32", reason="This test does not run under Windows"
971+
)
957972
def test_script_err():
958973
ip = get_ipython()
974+
assert asyncio.get_event_loop().is_running() is False
959975
ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
976+
assert asyncio.get_event_loop().is_running() is False
960977
nt.assert_equal(ip.user_ns['error'], 'hello\n')
961978

979+
980+
@dec.skip_iptest_but_not_pytest
962981
@dec.skip_win32
982+
@pytest.mark.skipif(
983+
sys.platform == "win32", reason="This test does not run under Windows"
984+
)
963985
def test_script_out_err():
986+
964987
ip = get_ipython()
965-
ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
966-
nt.assert_equal(ip.user_ns['output'], 'hi\n')
967-
nt.assert_equal(ip.user_ns['error'], 'hello\n')
988+
ip.run_cell_magic(
989+
"script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2"
990+
)
991+
nt.assert_equal(ip.user_ns["output"], "hi\n")
992+
nt.assert_equal(ip.user_ns["error"], "hello\n")
968993

994+
995+
@dec.skip_iptest_but_not_pytest
969996
@dec.skip_win32
997+
@pytest.mark.skipif(
998+
sys.platform == "win32", reason="This test does not run under Windows"
999+
)
9701000
async def test_script_bg_out():
9711001
ip = get_ipython()
9721002
ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
9731003
nt.assert_equal((await ip.user_ns["output"].read()), b"hi\n")
974-
ip.user_ns['output'].close()
1004+
ip.user_ns["output"].close()
1005+
asyncio.get_event_loop().stop()
9751006

1007+
@dec.skip_iptest_but_not_pytest
9761008
@dec.skip_win32
1009+
@pytest.mark.skipif(
1010+
sys.platform == "win32", reason="This test does not run under Windows"
1011+
)
9771012
async def test_script_bg_err():
9781013
ip = get_ipython()
9791014
ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
9801015
nt.assert_equal((await ip.user_ns["error"].read()), b"hello\n")
9811016
ip.user_ns["error"].close()
9821017

9831018

1019+
@dec.skip_iptest_but_not_pytest
9841020
@dec.skip_win32
1021+
@pytest.mark.skipif(
1022+
sys.platform == "win32", reason="This test does not run under Windows"
1023+
)
9851024
async def test_script_bg_out_err():
9861025
ip = get_ipython()
9871026
ip.run_cell_magic(

0 commit comments

Comments
 (0)