This method returns a dictionary containing the file attributes for the file name provided

        If you would like a Pandas dataframe returned instead of a dictionary, specify results='pandas'

def file_info(self, filepath, results: str = 'dict', fileref: str = '_spfinfo', quiet: bool = False):
        """
        This method returns a dictionary containing the file attributes for the file name provided

        If you would like a Pandas dataframe returned instead of a dictionary, specify results='pandas'
        """

        if not self.nosub:
           code  = "filename "+fileref+" '"+filepath+"';\n"
           code += "%put FILEREF_EXISTS=%sysfunc(fexist("+fileref+"));"
   
           ll = self.submit(code)
   
           exists = ll['LOG'].rpartition('FILEREF_EXISTS=')[2].split('\n')[0]
   
           if exists != '1':
              if not quiet:
                 print('The filepath provided does not exist')
              ll = self.submit("filename "+fileref+" clear;")
              return None

        if results != 'dict':
           code="""
           proc delete data=work._SASPY_FILE_INFO;run;
           data work._SASPY_FILE_INFO;
              length infoname infoval $256;
              drop rc fid infonum i close;
              fid=fopen('filerefx');
              if fid then
                 do;
                    infonum=foptnum(fid);
                    do i=1 to infonum;
                       infoname=foptname(fid, i);
                       infoval=finfo(fid, infoname);
                       output;
                    end;
                 end;
              close=fclose(fid);
              rc = filename('filerefx');
           run;
           """.replace('filerefx', fileref)
   
           if self.nosub:
               print(code)
               return None
           else:
              ll  = self.submit(code, results='text')
   
           res = self.sd2df('_SASPY_FILE_INFO', 'work')
           return res


        code="""options nosource;
        data _null_;
           length infoname infoval $256;
           drop rc fid infonum i close;
           put 'INFOSTART';
           fid=fopen('filerefx');
           if fid then
              do;
                 infonum=foptnum(fid);
                 do i=1 to infonum;
                    infoname=foptname(fid, i);
                    infoval=finfo(fid, infoname);
                    put 'INFONAME=' infoname;
                    put 'INFOVAL=' infoval;
                    put 'ENDINFOVAL=';
                 end;
              end; 
           put 'INFOEND';
           close=fclose(fid);
           rc = filename('filerefx');
        run; options source;
        """.replace('filerefx', fileref)

        if self.nosub:
            print(code)
            return None
        else:
           ll  = self.submit(code, results='text')

        res = {}
        log = ll['LOG'].rpartition('INFOEND')[0].rpartition('INFOSTART')
                                                                                  
        for i in range(log[2].count('INFONAME')):                                    
           log = log[2].partition('INFONAME=')[2].partition('\n')                    
           key = log[0]                                                           
           log = log[2].partition('INFOVAL=')[2].partition('\nENDINFOVAL=')
           val = log[0].strip().replace('\n','')
           res[key] = val                                                         
                                                                                  
        return res