Files
RustPython/extra_tests/not_impl_gen.py
2020-09-13 06:58:57 +09:00

143 lines
3.7 KiB
Python

# It's recommended to run this with `python3 -I not_impl_gen.py`, to make sure
# that nothing in your global Python environment interferes with what's being
# extracted here.
import pkgutil
import os
import sys
import warnings
sys.path = list(
filter(
lambda path: "site-packages" not in path and "dist-packages" not in path,
sys.path,
)
)
def attr_is_not_inherited(type_, attr):
"""
returns True if type_'s attr is not inherited from any of its base classes
"""
bases = type_.__mro__[1:]
return getattr(type_, attr) not in (getattr(base, attr, None) for base in bases)
def gen_methods(header, footer, output):
types = [
bool,
bytearray,
bytes,
complex,
dict,
enumerate,
filter,
float,
frozenset,
int,
list,
map,
memoryview,
range,
set,
slice,
str,
super,
tuple,
object,
zip,
classmethod,
staticmethod,
property,
Exception,
BaseException,
]
objects = [(t.__name__, t.__name__) for t in types]
objects.extend([
('NoneType', 'type(None)'),
])
iters = [
('bytearray_iterator', 'type(bytearray().__iter__())'),
('bytes_iterator', 'type(bytes().__iter__())'),
('dict_keyiterator', 'type(dict().__iter__())'),
('dict_valueiterator', 'type(dict().values().__iter__())'),
('dict_itemiterator', 'type(dict().items().__iter__())'),
('dict_values', 'type(dict().values())'),
('dict_items', 'type(dict().items())'),
('set_iterator', 'type(set().__iter__())'),
('list_iterator', 'type(list().__iter__())'),
('range_iterator', 'type(range(0).__iter__())'),
('str_iterator', 'type(str().__iter__())'),
('tuple_iterator', 'type(tuple().__iter__())'),
]
output.write(header.read())
output.write("expected_methods = {\n")
for name, typ_code in objects + iters:
typ = eval(typ_code)
output.write(f" '{name}': ({typ_code}, [\n")
output.write(
"\n".join(
f" {attr!r},"
for attr in dir(typ)
if attr_is_not_inherited(typ, attr)
)
)
output.write("\n ])," + ("\n" if objects[-1] == typ else "\n\n"))
output.write("}\n\n")
output.write(footer.read())
def get_module_methods(name):
with warnings.catch_warnings():
# ignore warnings caused by importing deprecated modules
warnings.filterwarnings("ignore", category=DeprecationWarning)
try:
return set(dir(__import__(name))) if name not in ("this", "antigravity") else None
except ModuleNotFoundError:
return None
except Exception as e:
print("!!! {} skipped because {}: {}".format(name, type(e).__name__, str(e)))
def gen_modules(header, footer, output):
output.write(header.read())
modules = dict(
map(
lambda mod: (
mod.name,
# check name b/c modules listed have side effects on import,
# e.g. printing something or opening a webpage
get_module_methods(mod.name)
),
pkgutil.iter_modules(),
)
)
print(
f"""
cpymods = {modules!r}
libdir = {os.path.abspath("../Lib/").encode('utf8')!r}
""",
file=output,
)
output.write(footer.read())
gen_funcs = {"methods": gen_methods, "modules": gen_modules}
for name, gen_func in gen_funcs.items():
gen_func(
header=open(f"generator/not_impl_{name}_header.txt"),
footer=open(f"generator/not_impl_{name}_footer.txt"),
output=open(f"snippets/whats_left_{name}.py", "w"),
)