spike(python): CPython 2.7.18 runs the 40250 root scripts on Android arm64
libpython2.7.a cross-builds with NDK 27.2 (API 24) after disabling HAVE_LANGINFO_H; 30 C modules built in. On a OnePlus 13 (API 36) the harness runs system.py -> prototype.RunApp() and imports the root modules with results identical to macOS (66/74; the 8 failures are stub values or dev-only scripts). py_embed_spike.py now isolates __main__ like CPythonLauncher and reports stdlib usage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,11 +8,15 @@ py_embed_spike.txt); system.py redirects stdout, so nothing useful is printed.
|
||||
|
||||
python2.7 py_embed_spike.py [--out FILE] (reference root: MT_40250_SOURCE or audit manifest)
|
||||
"""
|
||||
import sys, types, os, glob, traceback, json
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
REPO = os.path.abspath(os.path.join(HERE, "../../../.."))
|
||||
_ref = os.environ.get("MT_40250_SOURCE") or json.load(open(os.path.join(REPO, "audit/manifest.json")))["reference_root"]
|
||||
E = os.path.normpath(os.path.join(REPO, _ref, "../../Client/Eternexus"))
|
||||
import sys, types, os, glob, traceback
|
||||
if os.environ.get("MT_ETERNEXUS"): # on-device run: Eternexus tree pushed next to the binary
|
||||
E = os.environ["MT_ETERNEXUS"]
|
||||
else:
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
REPO = os.path.abspath(os.path.join(HERE, "../../../.."))
|
||||
import json
|
||||
_ref = os.environ.get("MT_40250_SOURCE") or json.load(open(os.path.join(REPO, "audit/manifest.json")))["reference_root"]
|
||||
E = str(os.path.normpath(os.path.join(REPO, _ref, "../../Client/Eternexus"))) # json gives unicode
|
||||
OUT = sys.argv[sys.argv.index("--out") + 1] if "--out" in sys.argv else "py_embed_spike.txt"
|
||||
FILES = {}
|
||||
for p in glob.glob(E + "/root/*"): FILES[os.path.basename(p).lower()] = p
|
||||
@@ -48,7 +52,11 @@ for k, v in STR.items():
|
||||
setattr(sys.modules[m], f, (lambda v: lambda *a: v)(v))
|
||||
import __builtin__
|
||||
__builtin__.TRUE = 1; __builtin__.FALSE = 0 # CPythonLauncher::Create
|
||||
import __main__
|
||||
# A fresh __main__ like CPythonLauncher::Create (whose __builtins__ is the module, not a dict);
|
||||
# system.py and prototype.py exec into it, so they must not share this script's globals.
|
||||
__main__ = types.ModuleType("__main__")
|
||||
__main__.__builtins__ = __builtin__
|
||||
sys.modules["__main__"] = __main__
|
||||
__main__.__DEBUG__ = 0
|
||||
__main__.__COMMAND_LINE__ = ""
|
||||
src = pack.Get("system.py")
|
||||
@@ -56,6 +64,7 @@ try:
|
||||
exec compile(src, "system.py", "exec") in __main__.__dict__
|
||||
except BaseException:
|
||||
LOG.write("system.py raised:\n" + traceback.format_exc())
|
||||
sys.stdout, sys.stderr = sys.__stdout__, sys.__stderr__ # system.py redirects both to dbg
|
||||
ok, bad = [], []
|
||||
_pimp = __main__.__dict__["__pack_import"]
|
||||
for name in sorted(FILES):
|
||||
@@ -66,9 +75,22 @@ for name in sorted(FILES):
|
||||
try:
|
||||
_pimp(mod); ok.append(mod)
|
||||
except BaseException as e:
|
||||
bad.append((mod, "%s: %s" % (type(e).__name__, str(e)[:100])))
|
||||
LOG.write("modules loaded %d, failed %d\n" % (len(ok), len(bad)))
|
||||
for m, e in bad: LOG.write(" FAIL %s %s\n" % (m, e))
|
||||
LOG.write("native functions called during bootstrap: %d\n" % len(MISSING))
|
||||
LOG.write(" " + " ".join(sorted(MISSING)) + "\n")
|
||||
bad.append((mod, "%s: %s" % (type(e).__name__, repr(e.args)[:100])))
|
||||
try:
|
||||
LOG.write("modules loaded %d, failed %d\n" % (len(ok), len(bad)))
|
||||
for m, e in bad: LOG.write(" FAIL %s %s\n" % (m, e))
|
||||
LOG.write("native functions called during bootstrap: %d\n" % len(MISSING))
|
||||
LOG.write(" " + " ".join(sorted(MISSING)) + "\n")
|
||||
std = []
|
||||
for name, m in sorted(sys.modules.items()):
|
||||
if m is None or name in NATIVE or name in ("pack", "__main__"): continue
|
||||
try: f = m.__dict__.get("__file__")
|
||||
except Exception: continue
|
||||
if not isinstance(f, str) and f is not None: continue
|
||||
if f is None: std.append("builtin:" + name)
|
||||
elif f.endswith(".so"): std.append("ext:" + name)
|
||||
elif not f.startswith(E) and not f.startswith("<"): std.append("py:" + name)
|
||||
LOG.write("stdlib modules in use: " + " ".join(std) + "\n")
|
||||
except BaseException:
|
||||
LOG.write("report failed:\n" + traceback.format_exc())
|
||||
LOG.close()
|
||||
|
||||
Reference in New Issue
Block a user