pkgdata.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """
  2. pkgdata is a simple, extensible way for a package to acquire data file
  3. resources.
  4. The getResource function is equivalent to the standard idioms, such as
  5. the following minimal implementation::
  6. import sys, os
  7. def getResource(identifier, pkgname=__name__):
  8. pkgpath = os.path.dirname(sys.modules[pkgname].__file__)
  9. path = os.path.join(pkgpath, identifier)
  10. return open(os.path.normpath(path), mode='rb')
  11. When a __loader__ is present on the module given by __name__, it will defer
  12. getResource to its get_data implementation and return it as a file-like
  13. object (such as StringIO).
  14. """
  15. import sys
  16. import os
  17. from io import StringIO
  18. def get_resource(identifier, pkgname=__name__):
  19. """
  20. Acquire a readable object for a given package name and identifier.
  21. An IOError will be raised if the resource cannot be found.
  22. For example::
  23. mydata = get_resource('mypkgdata.jpg').read()
  24. Note that the package name must be fully qualified, if given, such
  25. that it would be found in sys.modules.
  26. In some cases, getResource will return a real file object. In that
  27. case, it may be useful to use its name attribute to get the path
  28. rather than use it as a file-like object. For example, you may
  29. be handing data off to a C API.
  30. """
  31. mod = sys.modules[pkgname]
  32. fn = getattr(mod, '__file__', None)
  33. if fn is None:
  34. raise OSError("%r has no __file__!")
  35. path = os.path.join(os.path.dirname(fn), identifier)
  36. loader = getattr(mod, '__loader__', None)
  37. if loader is not None:
  38. try:
  39. data = loader.get_data(path)
  40. except (OSError, AttributeError):
  41. pass
  42. else:
  43. return StringIO(data.decode('utf-8'))
  44. return open(os.path.normpath(path), 'rb')