@@ -978,14 +978,22 @@ static void fallback_to_python_v(const char *self_dir, char **argv,
978978
979979 /* Try the config first */
980980 if (!read_self_config (self_dir , py , sizeof (py )) || !file_exists (py )) {
981- /* Try common names in self_dir */
981+ /* Try common names in self_dir, then parent (Scripts/ -> prefix/ on Windows). */
982982 const char * names [] = {"python3.11" ,"python3.10" ,"python3.9" ,
983- "python3" ,"python" ,NULL };
983+ "python3" ,"python" ,"python.exe" , NULL };
984984 int found = 0 ;
985985 for (int i = 0 ; names [i ]; i ++ ) {
986986 snprintf (py , sizeof (py ), "%s/%s" , self_dir , names [i ]);
987987 if (file_exists (py )) { found = 1 ; break ; }
988988 }
989+ if (!found ) {
990+ char parent_dir [MAX_PATH ];
991+ dir_of (self_dir , parent_dir , sizeof (parent_dir ));
992+ for (int i = 0 ; names [i ]; i ++ ) {
993+ snprintf (py , sizeof (py ), "%s/%s" , parent_dir , names [i ]);
994+ if (file_exists (py )) { found = 1 ; break ; }
995+ }
996+ }
989997 if (!found ) {
990998 fprintf (stderr , "omnipkg: cannot find host Python for fallback\n" );
991999 exit (1 );
@@ -1591,8 +1599,25 @@ int main(int argc, char **argv) {
15911599 if (cli_version ) {
15921600 char venv_root [MAX_PATH ];
15931601 find_venv_root (self_real , venv_root , sizeof (venv_root ));
1594- if (venv_root [0 ] && registry_lookup (venv_root , cli_version ,
1595- target_python , sizeof (target_python ))) {
1602+
1603+ /* Multi-candidate registry lookup: find_venv_root may miss on Windows
1604+ * (uses strrchr('/') only). Try venv_root, self_dir, self_dir parent. */
1605+ int reg_hit = 0 ;
1606+ if (venv_root [0 ])
1607+ reg_hit = registry_lookup (venv_root , cli_version ,
1608+ target_python , sizeof (target_python ));
1609+ if (!reg_hit )
1610+ reg_hit = registry_lookup (self_dir , cli_version ,
1611+ target_python , sizeof (target_python ));
1612+ if (!reg_hit ) {
1613+ char parent_dir [MAX_PATH ];
1614+ dir_of (self_dir , parent_dir , sizeof (parent_dir ));
1615+ if (parent_dir [0 ])
1616+ reg_hit = registry_lookup (parent_dir , cli_version ,
1617+ target_python , sizeof (target_python ));
1618+ }
1619+
1620+ if (reg_hit ) {
15961621 if (!file_exists (target_python )) {
15971622 /* Not adopted yet → fallback to Python for auto-adopt */
15981623 if (debug ) fprintf (stderr , "[C-DISPATCH] %s not found → auto-adopt fallback\n" , target_python );
@@ -1602,28 +1627,30 @@ int main(int argc, char **argv) {
16021627 fprintf (stderr , "[C-DISPATCH] registry hit %s → %s\n" ,
16031628 cli_version , target_python );
16041629 } else {
1605- /* Registry miss — could be the native interpreter (not adopted, so not
1606- * in registry.json). Check if the self-aware config python matches the
1607- * requested version before giving up and paying the Python fallback cost. */
1630+ /* Registry miss — check if self-aware config python matches.
1631+ * Handle Windows where basename may be "python.exe". */
16081632 char self_py [MAX_PATH ] = "" ;
16091633 read_self_config (self_dir , self_py , sizeof (self_py ));
16101634 if (self_py [0 ] && file_exists (self_py )) {
1611- /* Extract version from the path, e.g. ".../bin/python3.11" → "3.11" */
1635+ /* Extract version from path. Try both / and \\ separators. */
16121636 const char * base = strrchr (self_py , '/' );
1637+ const char * base2 = strrchr (self_py , '\\' );
1638+ if (base2 && (!base || base2 > base )) base = base2 ;
16131639 base = base ? base + 1 : self_py ;
1614- /* skip "python" prefix */
16151640 const char * ver_in_path = base ;
16161641 if (strncmp (ver_in_path , "python" , 6 ) == 0 ) ver_in_path += 6 ;
1617- if (strncmp (ver_in_path , "3." , 2 ) == 0 &&
1618- strcmp (ver_in_path , cli_version ) == 0 ) {
1619- /* Native interpreter matches — use it directly, no fallback needed */
1642+ char ver_buf [32 ] = "" ;
1643+ strncpy (ver_buf , ver_in_path , sizeof (ver_buf ) - 1 );
1644+ char * dot_exe = strstr (ver_buf , ".exe" );
1645+ if (dot_exe ) * dot_exe = '\0' ;
1646+ if (strncmp (ver_buf , "3." , 2 ) == 0 &&
1647+ strcmp (ver_buf , cli_version ) == 0 ) {
16201648 strncpy (target_python , self_py , sizeof (target_python ) - 1 );
16211649 target_python [sizeof (target_python ) - 1 ] = '\0' ;
16221650 if (debug )
16231651 fprintf (stderr , "[C-DISPATCH] native match %s → %s\n" ,
16241652 cli_version , target_python );
16251653 } else {
1626- /* Genuinely unknown version → Python fallback for auto-adopt */
16271654 if (debug ) fprintf (stderr , "[C-DISPATCH] unknown version %s → fallback\n" , cli_version );
16281655 fallback_to_python_v (self_dir , argv , cli_version );
16291656 }
0 commit comments