[reportlab-users] open_for_read and Window file paths

Robin Becker reportlab-users@reportlab.com
Thu, 03 Jun 2004 12:26:05 +0100


After more discussion we decided to go with this.

We attempt to open as a local resource first. That takes care of
everything except those things that happen to match both a local resource and 
something urlopen will recognise. It's also arguably the most common case.

If we error on the above we always attempt to use urlopen. We could pretend to 
detect whether there's a scheme etc, but it seems easier and more reliable to 
use urlopen itself. In error cases we will raise an exception like

IOError('Cannot open resource "path"')

This doesn't remove all ambiguity. Also if you want to use file: with c: 
filenames you'll need to use something like file:///c|/temp/filename


For those interested here's the code, please object as soon as you find the 
fatal flaw.

def open_for_read_by_name(name,mode='b'):
     if 'r' not in mode: mode = 'r'+mode
     try:
         return open(name,mode)
     except IOError:
         if _isFSD or __loader__ is None: raise
         #we have a __loader__, perhaps the filename starts with
         #the dirname(reportlab.__file__) or is relative
         name = _startswith_rl(name)
         s = __loader__.get_data(name)
         if 'b' not in mode and os.linesep!='\n': s = s.replace(os.linesep,'\n')
         return getStringIO(s)

import urllib
def open_for_read(name,mode='b', urlopen=urllib.urlopen):
     '''attempt to open a file or URL for reading'''
     if hasattr(name,'read'): return name
     try:
         return open_for_read_by_name(name,mode)
     except:
         try:
             return getStringIO(urlopen(name).read())
         except:
             raise IOError('Cannot open resource "%s"' % name)
del urllib


-- 
Robin Becker