Files
Jyotisha/tests/test_pancha_mahapurusha_self_conjunction.py
T
Jesse_ChenandClaude Opus 5.5 de79390175 fix(yoga): Pancha Mahapurusha has one main detector; combust/afflicted only reduced (T1, BUG-1207)
Astrologer ruling 甲5. scripts/pancha_mahapurusha.py is the only detector: kendras from
the Lagna; retrograde no longer cancels; combustion (shared orb table), malefic
conjunction and malefic graha drishti (Sun 7, Mars 4/7/8, Saturn 3/7/10) mark the
yoga reduced with reasons; D9 debilitation still cancels when navamsa_sign is given
(current behaviour, ruling silent, asked next round). _detect_yogas now passes the
Sun's longitude (combustion was never checked). mahapurusha_*, *_own, moolatrikona_*,
hamsa_trikona (Jupiter 1/5/9, not classical) and bvr_maalavya_yoga are reference_only;
yogas_doshas.calc_pancha_mahapurusha_yoga is kept as reference_yogas only. The rule
engine appends main-detector rows; cmd_yoga rows now carry lon + retrograde so the
report and card get the same combustion verdict. Card label lists 部分减弱 reasons.

Changed assertions (three columns in PROGRESS): self-conjunction tests (malefic in
same sign: invalid -> reduced), run_all t31/t32 (combust/retro: invalid -> reduced /
full), run_all t54 (evaluated rules >= 400 -> evaluated + reference_only >= 400).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 12:26:22 +08:00

60 lines
2.5 KiB
Python

"""BUG-1180: a Mahapurusha planet must not count itself as the malefic conjunct with it.
Before 57782aea ``_has_malefic_aspect`` skipped ``pn == planet_sign`` (a planet name
compared with a sign name, never equal), so Mars and Saturn -- natural malefics --
always "afflicted" themselves and Ruchaka / Shasha were never valid. The fix passes
the yoga planet and skips it. Fictional placements; no birth data.
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
from pancha_mahapurusha import _has_malefic_aspect, detect_pancha_mahapurusha # noqa: E402
def _yoga(yogas: list[dict], name: str) -> dict:
return next(item for item in yogas if item["name"] == name)
def test_ruchaka_mars_alone_in_own_kendra_is_valid() -> None:
planets = {"Mars": {"sign": "Aries", "house": 1, "degree": 10.0}}
ruchaka = _yoga(detect_pancha_mahapurusha(planets), "Ruchaka Yoga")
assert ruchaka["is_valid"] is True
assert ruchaka["cancellations"] == []
def test_shasha_saturn_exalted_in_kendra_is_valid() -> None:
planets = {"Saturn": {"sign": "Libra", "house": 10, "degree": 200.0}}
shasha = _yoga(detect_pancha_mahapurusha(planets), "Shasha Yoga")
assert shasha["is_valid"] is True
def test_another_malefic_in_the_same_sign_still_cancels_and_is_named() -> None:
planets = {
"Mars": {"sign": "Aries", "house": 1, "degree": 10.0},
"Saturn": {"sign": "Aries", "house": 1, "degree": 12.0},
}
ruchaka = _yoga(detect_pancha_mahapurusha(planets), "Ruchaka Yoga")
# BUG-1207 (ruling 甲5): a malefic in the same sign only reduces the yoga.
# Was: is_valid False with the reason in `cancellations`.
assert ruchaka["is_valid"] is True
assert ruchaka["strength"] == "reduced"
assert any("土星" in reason and "火星" not in reason for reason in ruchaka["reductions"])
assert _has_malefic_aspect("Aries", planets, "Mars") == ["Saturn"]
def test_benefic_yoga_planet_unchanged() -> None:
planets = {
"Jupiter": {"sign": "Cancer", "house": 4, "degree": 95.0},
"Mars": {"sign": "Cancer", "house": 4, "degree": 100.0},
}
hamsa = _yoga(detect_pancha_mahapurusha(planets), "Hamsa Yoga")
# BUG-1207 (ruling 甲5): reduced, not cancelled (was is_valid False).
assert hamsa["is_valid"] is True
assert hamsa["strength"] == "reduced"
assert _has_malefic_aspect("Cancer", planets, "Jupiter") == ["Mars"]