Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit38cfa92

Browse files
[3.13]gh-118908: Use __main__ for the default PyREPL namespace (GH-121054) (#121059)
1 parent64c4139 commit38cfa92

File tree

4 files changed

+75
-67
lines changed

4 files changed

+75
-67
lines changed

‎Lib/_pyrepl/__main__.py

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,3 @@
1-
importos
2-
importsys
3-
4-
CAN_USE_PYREPL:bool
5-
ifsys.platform!="win32":
6-
CAN_USE_PYREPL=True
7-
else:
8-
CAN_USE_PYREPL=sys.getwindowsversion().build>=10586# Windows 10 TH2
9-
10-
11-
definteractive_console(mainmodule=None,quiet=False,pythonstartup=False):
12-
globalCAN_USE_PYREPL
13-
ifnotCAN_USE_PYREPL:
14-
returnsys._baserepl()
15-
16-
startup_path=os.getenv("PYTHONSTARTUP")
17-
ifpythonstartupandstartup_path:
18-
importtokenize
19-
withtokenize.open(startup_path)asf:
20-
startup_code=compile(f.read(),startup_path,"exec")
21-
exec(startup_code)
22-
23-
# set sys.{ps1,ps2} just before invoking the interactive interpreter. This
24-
# mimics what CPython does in pythonrun.c
25-
ifnothasattr(sys,"ps1"):
26-
sys.ps1=">>> "
27-
ifnothasattr(sys,"ps2"):
28-
sys.ps2="... "
29-
30-
run_interactive=None
31-
try:
32-
importerrno
33-
ifnotos.isatty(sys.stdin.fileno()):
34-
raiseOSError(errno.ENOTTY,"tty required","stdin")
35-
from .simple_interactimportcheck
36-
iferr:=check():
37-
raiseRuntimeError(err)
38-
from .simple_interactimportrun_multiline_interactive_console
39-
run_interactive=run_multiline_interactive_console
40-
exceptExceptionase:
41-
from .traceimporttrace
42-
msg=f"warning: can't use pyrepl:{e}"
43-
trace(msg)
44-
print(msg,file=sys.stderr)
45-
CAN_USE_PYREPL=False
46-
ifrun_interactiveisNone:
47-
returnsys._baserepl()
48-
returnrun_interactive(mainmodule)
49-
501
if__name__=="__main__":
51-
interactive_console()
2+
from .mainimportinteractive_consoleas__pyrepl_interactive_console
3+
__pyrepl_interactive_console()

‎Lib/_pyrepl/main.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
importos
2+
importsys
3+
4+
CAN_USE_PYREPL:bool
5+
ifsys.platform!="win32":
6+
CAN_USE_PYREPL=True
7+
else:
8+
CAN_USE_PYREPL=sys.getwindowsversion().build>=10586# Windows 10 TH2
9+
10+
11+
definteractive_console(mainmodule=None,quiet=False,pythonstartup=False):
12+
globalCAN_USE_PYREPL
13+
ifnotCAN_USE_PYREPL:
14+
returnsys._baserepl()
15+
16+
ifmainmodule:
17+
namespace=mainmodule.__dict__
18+
else:
19+
import__main__
20+
namespace=__main__.__dict__
21+
namespace.pop("__pyrepl_interactive_console",None)
22+
23+
startup_path=os.getenv("PYTHONSTARTUP")
24+
ifpythonstartupandstartup_path:
25+
importtokenize
26+
withtokenize.open(startup_path)asf:
27+
startup_code=compile(f.read(),startup_path,"exec")
28+
exec(startup_code,namespace)
29+
30+
# set sys.{ps1,ps2} just before invoking the interactive interpreter. This
31+
# mimics what CPython does in pythonrun.c
32+
ifnothasattr(sys,"ps1"):
33+
sys.ps1=">>> "
34+
ifnothasattr(sys,"ps2"):
35+
sys.ps2="... "
36+
37+
run_interactive=None
38+
try:
39+
importerrno
40+
ifnotos.isatty(sys.stdin.fileno()):
41+
raiseOSError(errno.ENOTTY,"tty required","stdin")
42+
from .simple_interactimportcheck
43+
iferr:=check():
44+
raiseRuntimeError(err)
45+
from .simple_interactimportrun_multiline_interactive_console
46+
run_interactive=run_multiline_interactive_console
47+
exceptExceptionase:
48+
from .traceimporttrace
49+
msg=f"warning: can't use pyrepl:{e}"
50+
trace(msg)
51+
print(msg,file=sys.stderr)
52+
CAN_USE_PYREPL=False
53+
ifrun_interactiveisNone:
54+
returnsys._baserepl()
55+
run_interactive(namespace)

‎Lib/_pyrepl/simple_interact.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,13 @@ def _clear_screen():
8080
"clear":_clear_screen,
8181
}
8282

83-
DEFAULT_NAMESPACE:dict[str,Any]= {
84-
'__name__':'__main__',
85-
'__doc__':None,
86-
'__package__':None,
87-
'__loader__':None,
88-
'__spec__':None,
89-
'__annotations__': {},
90-
'__builtins__':builtins,
91-
}
9283

9384
defrun_multiline_interactive_console(
94-
mainmodule:ModuleType|None=None,
85+
namespace:dict[str,Any],
9586
future_flags:int=0,
9687
console:code.InteractiveConsole|None=None,
9788
)->None:
9889
from .readlineimport_setup
99-
namespace=mainmodule.__dict__ifmainmoduleelseDEFAULT_NAMESPACE
10090
_setup(namespace)
10191

10292
ifconsoleisNone:

‎Lib/test/test_pyrepl/test_pyrepl.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -843,15 +843,26 @@ def test_bracketed_paste_single_line(self):
843843
classTestMain(TestCase):
844844
@force_not_colorized
845845
deftest_exposed_globals_in_repl(self):
846-
expected_output= (
847-
"[\'__annotations__\',\'__builtins__\',\'__doc__\',\'__loader__\', "
848-
"\'__name__\',\'__package__\',\'__spec__\']"
849-
)
846+
pre="['__annotations__', '__builtins__'"
847+
post="'__loader__', '__name__', '__package__', '__spec__']"
850848
output,exit_code=self.run_repl(["sorted(dir())","exit"])
851-
if"can\'t use pyrepl"inoutput:
849+
if"can't use pyrepl"inoutput:
852850
self.skipTest("pyrepl not available")
853851
self.assertEqual(exit_code,0)
854-
self.assertIn(expected_output,output)
852+
853+
# if `__main__` is not a file (impossible with pyrepl)
854+
case1=f"{pre}, '__doc__',{post}"inoutput
855+
856+
# if `__main__` is an uncached .py file (no .pyc)
857+
case2=f"{pre}, '__doc__', '__file__',{post}"inoutput
858+
859+
# if `__main__` is a cached .pyc file and the .py source exists
860+
case3=f"{pre}, '__cached__', '__doc__', '__file__',{post}"inoutput
861+
862+
# if `__main__` is a cached .pyc file but there's no .py source file
863+
case4=f"{pre}, '__cached__', '__doc__',{post}"inoutput
864+
865+
self.assertTrue(case1orcase2orcase3orcase4,output)
855866

856867
deftest_dumb_terminal_exits_cleanly(self):
857868
env=os.environ.copy()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp