pkgdata.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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 file(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. __all__ = ['getResource']
  16. import sys
  17. import os
  18. from pygame.compat import get_BytesIO
  19. BytesIO = get_BytesIO()
  20. try:
  21. from pkg_resources import resource_stream, resource_exists
  22. except ImportError:
  23. def resource_exists(package_or_requirement, resource_name):
  24. return False
  25. def resource_stream(package_of_requirement, resource_name):
  26. raise NotImplementedError
  27. def getResource(identifier, pkgname=__name__):
  28. """
  29. Acquire a readable object for a given package name and identifier.
  30. An IOError will be raised if the resource can not be found.
  31. For example:
  32. mydata = getResource('mypkgdata.jpg').read()
  33. Note that the package name must be fully qualified, if given, such
  34. that it would be found in sys.modules.
  35. In some cases, getResource will return a real file object. In that
  36. case, it may be useful to use its name attribute to get the path
  37. rather than use it as a file-like object. For example, you may
  38. be handing data off to a C API.
  39. """
  40. if resource_exists(pkgname, identifier):
  41. return resource_stream(pkgname, identifier)
  42. mod = sys.modules[pkgname]
  43. fn = getattr(mod, '__file__', None)
  44. if fn is None:
  45. raise IOError("%s has no __file__!" % repr(mod))
  46. path = os.path.join(os.path.dirname(fn), identifier)
  47. if sys.version_info < (3, 3):
  48. loader = getattr(mod, '__loader__', None)
  49. if loader is not None:
  50. try:
  51. data = loader.get_data(path)
  52. except IOError:
  53. pass
  54. else:
  55. return BytesIO(data)
  56. return open(os.path.normpath(path), 'rb')