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
60 lines
2.5 KiB
Python
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"]
|