forked from nedbat/byterun
-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathbuiltins.py
More file actions
128 lines (103 loc) · 3.79 KB
/
Copy pathbuiltins.py
File metadata and controls
128 lines (103 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""
Compatibility of built-in functions between different Python versions.
"""
from typing import Any, Callable
from xdis.version_info import PYTHON_VERSION_TRIPLE
import importlib
from builtins import input
from functools import reduce
from importlib import reload
import_fn = importlib.__import__
from io import open
from sys import intern
def make_compatible_builtins(builtins: dict, target_python: tuple) -> None:
"""
Add functions in builtins dictionary with functions that do the same
thing.
This is needed when doing cross-bytecode interpretation
because the list of builtin functions varies between different Python versions.
"""
if type(target_python) is not tuple:
target_python = (int(str(target_python)[0]), int(str(target_python)[2]))
short_name = f"builtins_{target_python[0]}{target_python[1]}"
import_name = f"xpython.stdlib.{short_name}"
try:
module_root = import_fn(import_name)
except Exception:
return
if hasattr(module_root, "stdlib"):
stdlib_mod = getattr(module_root, "stdlib")
if hasattr(stdlib_mod, short_name):
module = getattr(stdlib_mod, short_name)
needs_compat = module.builtins - builtins.keys()
for builtin_name in needs_compat:
if builtin_name in compatable_fns:
# print("XXX", builtin_name)
builtins[builtin_name] = compatable_fns[builtin_name]
else:
print(
"FIXME: add %s-compatible builtin function for %s from Python %s"
% (
".".join([str(i) for i in target_python[:2]]),
builtin_name,
PYTHON_VERSION_TRIPLE[:2],
)
)
def apply(f: Callable, args=None, kwargs=None) -> Any:
"""
Python 1-2.x apply for Python 3.x
"""
return f(*args, **kwargs)
def breakpoint(*args, **kwargs) -> None:
"""
Python Python 3.8- breakpoint (compare) for Python 3.x
"""
print("Not implimeneted yet")
def cmp(x, y) -> int:
"""
Python 1-2.x cmp (compare) for Python 3.x
"""
return (x > y) - (x < y)
numeric_types = (int, float, complex)
def coerce(x, y) -> tuple:
"""
Python 1-2.x coerce for Python 3.x
"""
if not isinstance(x, numeric_types):
raise TypeError("number coercion failed")
if not isinstance(y, numeric_types):
raise TypeError("number coercion failed")
raise TypeError
# Leave unchanged and other operations do the coercion
return x, y
def execfile(path: str) -> None:
"""
Python 1-2.x execfile for Python 3.x
"""
exec(compile(open(path).read()))
class OverflowWarning(RuntimeError):
"""A Python 1.x - 2.6 RuntimeError."""
def __str__(self) -> str:
return "OverflowError: Numerical result out of range"
# Mapping of builtin function name (a str) to a function that implements it compatibly
compatable_fns = {
"apply": apply, # Python 1.x-2.x
"basestring": str, # Python 1.x-2.x
"breakpoint": breakpoint, # Python 1.x-3.7
"buffer": memoryview, # Python 1.x-2.x
"cmp": cmp, # Python 1.x-2.x
"coerce": coerce, # Python 1.x-2.x
"execfile": execfile, # Python 1.x-2.x
"file": open, # Python 1.x-2.x. Do we eneed to worry about open() mode "rb",
# vs "rt"?
"intern": intern, # Python 1.x-2.x
"long": int, # Python 1.x-2.x
"reduce": reduce, # Python 1.x-2.x
"reload": reload, # Python 1.x-2.x
"raw_input": input, # Python 1.x-2.x
"unichr": chr, # Python 1.x-2.x
"unicode": str, # Python 1.x-2.x
"xrange": range, # Python 1.x-2.x
"OverflowWarning": OverflowWarning, # Python 1.x-2.6
"StandardError": Exception, # Python 1.x-2.x
}