@@ -88,7 +88,7 @@ def __init__(self, cls, suffix, case=True, gzip=False):
8888 self .base_names = [c .__name__ .lower () for c in self .bases ]
8989
9090 def __str__ (self ):
91- s = ",\n " .join (map (lambda x : x .__name , self .bases ))
91+ s = ",\n " .join (map (lambda x : x .__name__ , self .bases ))
9292 return (
9393 f"{ self .cls .__name__ } {{case={ self .case } , "
9494 f"suffix={ self .suffix } , gzip={ self .gzip } ,\n { s } \n }}"
@@ -244,8 +244,7 @@ def get_sile_class(filename, *args, **kwargs):
244244 if specification is None :
245245 # ensure to grab nothing
246246 specification = get_environ_variable ("SISL_IO_DEFAULT" ).strip ()
247- elif specification .strip () == "" :
248- specification = ""
247+ specification = specification .strip ()
249248
250249 # extract which comparsion method
251250 if "=" in specification :
@@ -277,15 +276,30 @@ def get_sile_class(filename, *args, **kwargs):
277276 f"Specification requirement of the file did not result in any found files: { specification } "
278277 )
279278
280- else :
281- # search everything
282- eligible_rules = __sile_rules
279+ def reduce_rules (rules ):
280+ # Reduce so we are stuck with only non-equivalent ones
281+ i = 0
282+ n = 0
283+ while n != len (rules ) and i < len (rules ):
284+ n = len (rules )
285+ # Search for classes equivalent to idx i
286+ rule = rules [i ]
287+ pop_idx = []
288+ for j in range (i + 1 , n ):
289+ if rule .is_class (rules [j ].cls ):
290+ pop_idx .append (j )
291+
292+ # Remove equivalent ones
293+ for j in reversed (pop_idx ):
294+ rules .pop (j )
295+ # Check the next i
296+ i += 1
283297
284298 if eligible_rules :
285299 if len (eligible_rules ) == 1 :
286300 return eligible_rules [0 ].cls
287301 else :
288- # nothing has been found, this may meen that we need to search *everything*
302+ # nothing has been found, this may mean that we need to search *everything*
289303 eligible_rules = __sile_rules
290304
291305 try :
@@ -355,27 +369,60 @@ def get_eligibles(end, rules):
355369 eligibles .append (sr )
356370 return eligibles
357371
358- # First we check for class AND file ending
359- for end , rules in product (end_list , (eligible_rules , __sile_rules )):
360- eligibles = get_eligibles (end , rules )
361- # Determine whether we have found a compatible sile
362- if len (eligibles ) == 1 :
363- return eligibles [0 ].cls
364- elif len (eligibles ) > 1 :
365- workable_eligibles = try_methods (eligibles )
366- if len (workable_eligibles ) == 1 :
367- return workable_eligibles [0 ].cls
368- raise ValueError (
369- f"Cannot determine the exact Sile requested, multiple hits: { tuple (e .cls .__name__ for e in eligibles )} "
370- )
372+ def run_eligibles (end_list , rules ) -> Optional [_sile_rule ]:
373+ # First we check for class AND file ending
374+ for end in end_list :
375+ eligibles = get_eligibles (end , rules )
376+ # Determine whether we have found a compatible sile
377+ if len (eligibles ) == 1 :
378+ return eligibles [0 ]
379+ elif len (eligibles ) > 1 :
380+ workable_eligibles = try_methods (eligibles )
381+ if len (workable_eligibles ) == 1 :
382+ return workable_eligibles [0 ]
383+ raise ValueError (
384+ f"Cannot determine the exact Sile requested, multiple hits: { tuple (e .cls .__name__ for e in eligibles )} "
385+ )
386+
387+ # First check for the user-requested rules
388+ # Specific is same object check!
389+ if eligible_rules and not (eligible_rules is __sile_rules ):
390+ # This will test the file-endings for all found eligible_rules
391+ # So file-endings are still preferred up to this point.
392+ rule = run_eligibles (end_list , eligible_rules )
393+
394+ if rule is not None :
395+ return rule .cls
396+
397+ # We did not find a single one, so file-endings could not produce
398+ # a match in the eligible ones.
399+ # Reduce and see if they are all the same.
400+ reduce_rules (eligible_rules )
401+ if len (eligible_rules ) == 1 :
402+ return eligible_rules [0 ].cls
403+
404+ # At this point, we issues a warning saying that the
405+ # the rules requested could not find a match
406+ eligibles = list (map (lambda x : x .cls .__name__ , eligible_rules ))
407+ warn (
408+ "Specification requirement of the file resulted in too many "
409+ f"matches: { eligibles } "
410+ )
411+
412+ rule = run_eligibles (end_list , __sile_rules )
413+
414+ if rule is not None :
415+ return rule .cls
371416
372417 # Print-out error on which extensions it tried (and full filename)
373418 if len (end_list ) == 1 :
374419 ext_list = end_list
375420 else :
376421 ext_list = end_list [1 :]
422+ # Retrieve the possible extensions searched
423+ eligibles = list (map (lambda x : x .cls .__name__ , eligible_rules ))
377424 raise NotImplementedError (
378- f"Sile for file '{ filename } ' ({ ext_list } ) could not be found, "
425+ f"Sile for file '{ filename } ' ({ ext_list } , { eligibles } ) could not be found, "
379426 "possibly the file has not been implemented."
380427 )
381428
0 commit comments