瑜伽角宫主和三方主按名字排序,不再随进程哈希变(BUG-1320,上游 0337b77f)

同一张盘在两个哈希种子下,宫主名单和瑜伽参与者顺序一致。pytest tests/test_yoga_lord_order_stable.py 1 通过。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-10-14 00:48:53 +08:00
co-authored by Grok (agent loop)
parent 2748e43871
commit 4cdb997800
3 changed files with 91 additions and 2 deletions
+72
View File
@@ -0,0 +1,72 @@
"""BUG-1320: kendra and trikona lord lists do not follow PYTHONHASHSEED.
Upstream 0337b77f. Two processes with different hash seeds must list the
same yoga participants in the same order.
"""
from __future__ import annotations
import json
import os
import subprocess
import sys
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
_PROBE = r"""
import json
import sys
sys.path.insert(0, "scripts")
from yoga_engine import YogaContext, YogaEngine, detect_yogas
planets = {
"Sun": {"sign": "Leo", "house": 5, "degree": 10},
"Moon": {"sign": "Cancer", "house": 4, "degree": 5},
"Mars": {"sign": "Aries", "house": 1, "degree": 8},
"Mercury": {"sign": "Virgo", "house": 6, "degree": 12},
"Jupiter": {"sign": "Sagittarius", "house": 9, "degree": 15},
"Venus": {"sign": "Libra", "house": 7, "degree": 3},
"Saturn": {"sign": "Capricorn", "house": 10, "degree": 20},
"Rahu": {"sign": "Taurus", "house": 2, "degree": 9},
"Ketu": {"sign": "Scorpio", "house": 8, "degree": 9},
}
rules = "references/yoga_rules.json"
engine = YogaEngine(rules)
ctx = YogaContext(planets, "Aries")
namespace = engine._build_custom_exec_globals(ctx, {}, {})
rows = detect_yogas(planets, "Aries", rules)
print(json.dumps({
"kendra": namespace["kendra_lords_list"](),
"trikona": namespace["trikona_lords_list"](),
"participants": [
[row.get("rule_id"), str(row.get("combination"))]
for row in rows
],
}, ensure_ascii=False))
"""
def _run(seed: str) -> dict:
env = os.environ.copy()
env["PYTHONHASHSEED"] = seed
env["PYTHONIOENCODING"] = "utf-8"
completed = subprocess.run(
[sys.executable, "-c", _PROBE],
cwd=ROOT,
env=env,
check=True,
capture_output=True,
text=True,
encoding="utf-8",
)
return json.loads(completed.stdout)
def test_yoga_participants_keep_the_same_order_across_hash_seeds() -> None:
first = _run("0")
second = _run("1")
assert first == second
assert first["kendra"] == sorted(first["kendra"])
assert first["trikona"] == sorted(first["trikona"])
assert first["kendra"] == ["Mars", "Moon", "Saturn", "Venus"]
assert first["trikona"] == ["Jupiter", "Mars", "Sun"]