Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/data_util/registry.py

    ra1b8fee r3ece5dd  
    1 # This program is public domain 
    21""" 
    32File extension registry. 
     
    65and registers the built-in file extensions. 
    76""" 
    8 from __future__ import print_function 
    97 
    10 import os.path 
     8from sas.sascalc.dataloader.loader_exceptions import NoKnownLoaderException 
     9 
    1110 
    1211class ExtensionRegistry(object): 
     
    2221        # Add an association by setting an element 
    2322        registry['.zip'] = unzip 
    24          
     23 
    2524        # Multiple extensions for one loader 
    2625        registry['.tgz'] = untar 
    2726        registry['.tar.gz'] = untar 
    2827 
    29         # Generic extensions to use after trying more specific extensions;  
     28        # Generic extensions to use after trying more specific extensions; 
    3029        # these will be checked after the more specific extensions fail. 
    3130        registry['.gz'] = gunzip 
     
    3837        # Show registered extensions 
    3938        print registry.extensions() 
    40          
     39 
    4140        # Can also register a format name for explicit control from caller 
    4241        registry['cx3'] = cx3 
     
    6261    def __init__(self, **kw): 
    6362        self.loaders = {} 
     63 
    6464    def __setitem__(self, ext, loader): 
    6565        if ext not in self.loaders: 
    6666            self.loaders[ext] = [] 
    6767        self.loaders[ext].insert(0,loader) 
     68 
    6869    def __getitem__(self, ext): 
    6970        return self.loaders[ext] 
     71 
    7072    def __contains__(self, ext): 
    7173        return ext in self.loaders 
     74 
    7275    def formats(self): 
    7376        """ 
     
    7780        names.sort() 
    7881        return names 
     82 
    7983    def extensions(self): 
    8084        """ 
     
    8488        exts.sort() 
    8589        return exts 
     90 
    8691    def lookup(self, path): 
    8792        """ 
    8893        Return the loader associated with the file type of path. 
    89          
    90         Raises ValueError if file type is not known. 
    91         """         
     94 
     95        :param path: Data file path 
     96        :raises ValueError: When no loaders are found for the file. 
     97        :return: List of available readers for the file extension 
     98        """ 
    9299        # Find matching extensions 
    93100        extlist = [ext for ext in self.extensions() if path.endswith(ext)] 
     
    106113        # Raise an error if there are no matching extensions 
    107114        if len(loaders) == 0: 
    108             raise ValueError, "Unknown file type for "+path 
    109         # All done 
     115            raise ValueError("Unknown file type for "+path) 
    110116        return loaders 
     117 
    111118    def load(self, path, format=None): 
    112119        """ 
    113120        Call the loader for the file type of path. 
    114121 
    115         Raises ValueError if no loader is available. 
    116         Raises KeyError if format is not available. 
    117         May raise a loader-defined exception if loader fails.         
     122        :raise ValueError: if no loader is available. 
     123        :raise KeyError: if format is not available. 
     124        May raise a loader-defined exception if loader fails. 
    118125        """ 
     126        loaders = [] 
    119127        if format is None: 
    120             loaders = self.lookup(path) 
     128            try: 
     129                loaders = self.lookup(path) 
     130            except ValueError as e: 
     131                pass 
    121132        else: 
    122             loaders = self.loaders[format] 
     133            try: 
     134                loaders = self.loaders[format] 
     135            except KeyError as e: 
     136                pass 
     137        last_exc = None 
    123138        for fn in loaders: 
    124139            try: 
    125140                return fn(path) 
    126             except: 
    127                 pass # give other loaders a chance to succeed 
     141            except Exception as e: 
     142                last_exc = e 
     143                pass  # give other loaders a chance to succeed 
    128144        # If we get here it is because all loaders failed 
    129         raise # reraises last exception 
    130  
    131 def test(): 
    132     reg = ExtensionRegistry() 
    133     class CxError(Exception): pass 
    134     def cx(file): return 'cx' 
    135     def new_cx(file): return 'new_cx' 
    136     def fail_cx(file): raise CxError 
    137     def cat(file): return 'cat' 
    138     def gunzip(file): return 'gunzip' 
    139     reg['.cx'] = cx 
    140     reg['.cx1'] = cx 
    141     reg['.cx'] = new_cx 
    142     reg['.gz'] = gunzip 
    143     reg['.cx.gz'] = new_cx 
    144     reg['.cx1.gz'] = fail_cx 
    145     reg['.cx1'] = fail_cx 
    146     reg['.cx2'] = fail_cx 
    147     reg['new_cx'] = new_cx 
    148  
    149     # Two loaders associated with .cx 
    150     assert reg.lookup('hello.cx') == [new_cx,cx] 
    151     # Make sure the last loader applies first 
    152     assert reg.load('hello.cx') == 'new_cx' 
    153     # Make sure the next loader applies if the first fails 
    154     assert reg.load('hello.cx1') == 'cx' 
    155     # Make sure the format override works 
    156     assert reg.load('hello.cx1',format='.cx.gz') == 'new_cx' 
    157     # Make sure the format override works 
    158     assert reg.load('hello.cx1',format='new_cx') == 'new_cx' 
    159     # Make sure the case of all loaders failing is correct 
    160     try:  reg.load('hello.cx2') 
    161     except CxError: pass # correct failure 
    162     else: raise AssertError,"Incorrect error on load failure" 
    163     # Make sure the case of no loaders fails correctly 
    164     try: reg.load('hello.missing') 
    165     except ValueError,msg: 
    166         assert str(msg)=="Unknown file type for hello.missing",'Message: <%s>'%(msg) 
    167     else: raise AssertError,"No error raised for missing extension" 
    168     assert reg.formats() == ['new_cx'] 
    169     assert reg.extensions() == ['.cx','.cx.gz','.cx1','.cx1.gz','.cx2','.gz'] 
    170     # make sure that it supports multiple '.' in filename 
    171     assert reg.load('hello.extra.cx1') == 'cx' 
    172     assert reg.load('hello.gz') == 'gunzip' 
    173     assert reg.load('hello.cx1.gz') == 'gunzip' # Since .cx1.gz fails 
    174  
    175 if __name__ == "__main__": test() 
     145        if last_exc is not None and len(loaders) != 0: 
     146            # If file has associated loader(s) and they;ve failed 
     147            raise last_exc 
     148        raise NoKnownLoaderException(e.message)  # raise generic exception 
Note: See TracChangeset for help on using the changeset viewer.