01-arcadia.patch 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. --- contrib/python/setuptools/py3/pkg_resources/__init__.py (index)
  2. +++ contrib/python/setuptools/py3/pkg_resources/__init__.py (working tree)
  3. @@ -3222,6 +3222,90 @@ def _mkstemp(*args, **kw):
  4. os.open = old_open
  5. +# Yandex resource support
  6. +from __res import Y_PYTHON_SOURCE_ROOT, ResourceImporter, executable
  7. +from library.python import resource
  8. +
  9. +
  10. +class ResProvider(EmptyProvider):
  11. + _resource_fs = {}
  12. +
  13. + def __init__(self, prefix):
  14. + if hasattr(prefix, '__file__'):
  15. + key = prefix.__file__.rsplit('/', 1)[0]
  16. + self.module_path = 'resfs/file/{}/'.format(key)
  17. + # Метаданные лежат на уровень выше самого пакета
  18. + key = key.rsplit('/', 1)[0]
  19. + self.egg_info = 'resfs/file/{}/.dist-info/'.format(key)
  20. + else:
  21. + # Сюда попадаем только из ResDistribution, который работает
  22. + # только метаданными, поэтому self.module_path не используется
  23. + self.egg_info = prefix
  24. +
  25. + @staticmethod
  26. + def from_module(module):
  27. + if Y_PYTHON_SOURCE_ROOT:
  28. + return DefaultProvider(module)
  29. + else:
  30. + return ResProvider(module)
  31. +
  32. + def _fn(self, base, resource_name):
  33. + return base + resource_name
  34. +
  35. + def _has(self, path):
  36. + return resource.find(path) is not None
  37. +
  38. + def _get(self, path):
  39. + result = resource.find(path)
  40. + if result is None:
  41. + raise IOError(path)
  42. + return result
  43. +
  44. + @classmethod
  45. + def _init_resource_fs(cls):
  46. + for path in resource.iterkeys(b'resfs/file/'):
  47. + path_str = path.decode('utf-8')
  48. + components = path_str.split('/')
  49. + for l in range(len(components)):
  50. + subpath = os.path.normpath('/'.join(components[:l]))
  51. + cls._resource_fs.setdefault(subpath, set()).add(components[l])
  52. +
  53. + def __lookup(self, path):
  54. + if not self._resource_fs:
  55. + self._init_resource_fs()
  56. + path = os.path.normpath(path)
  57. + return self._resource_fs.get(path)
  58. +
  59. + def _listdir(self, path):
  60. + result = self.__lookup(path)
  61. + if result is None:
  62. + return []
  63. + return list(result)
  64. +
  65. + def _isdir(self, path):
  66. + return bool(self.__lookup(path))
  67. +
  68. +
  69. +class ResDistribution(DistInfoDistribution):
  70. + def __init__(self, prefix):
  71. + super(ResDistribution, self).__init__(
  72. + location=executable,
  73. + metadata=ResProvider(prefix),
  74. + precedence=BINARY_DIST,
  75. + )
  76. + self.project_name = self._parsed_pkg_info.get('Name', self.project_name)
  77. +
  78. +
  79. +def find_in_res(importer, path_item, only=False):
  80. + for key in resource.iterkeys():
  81. + if key.endswith('.dist-info/METADATA') and not key.startswith('resfs/src/'):
  82. + yield ResDistribution(key[:-8])
  83. +
  84. +
  85. +register_finder(ResourceImporter, find_in_res)
  86. +register_loader_type(ResourceImporter, ResProvider.from_module)
  87. +
  88. +
  89. # Silence the PEP440Warning by default, so that end users don't get hit by it
  90. # randomly just because they use pkg_resources. We want to append the rule
  91. # because we want earlier uses of filterwarnings to take precedence over this