--- contrib/python/setuptools/py3/pkg_resources/__init__.py (index) +++ contrib/python/setuptools/py3/pkg_resources/__init__.py (working tree) @@ -3222,6 +3222,90 @@ def _mkstemp(*args, **kw): os.open = old_open +# Yandex resource support +from __res import Y_PYTHON_SOURCE_ROOT, ResourceImporter, executable +from library.python import resource + + +class ResProvider(EmptyProvider): + _resource_fs = {} + + def __init__(self, prefix): + if hasattr(prefix, '__file__'): + key = prefix.__file__.rsplit('/', 1)[0] + self.module_path = 'resfs/file/{}/'.format(key) + # Метаданные лежат на уровень выше самого пакета + key = key.rsplit('/', 1)[0] + self.egg_info = 'resfs/file/{}/.dist-info/'.format(key) + else: + # Сюда попадаем только из ResDistribution, который работает + # только метаданными, поэтому self.module_path не используется + self.egg_info = prefix + + @staticmethod + def from_module(module): + if Y_PYTHON_SOURCE_ROOT: + return DefaultProvider(module) + else: + return ResProvider(module) + + def _fn(self, base, resource_name): + return base + resource_name + + def _has(self, path): + return resource.find(path) is not None + + def _get(self, path): + result = resource.find(path) + if result is None: + raise IOError(path) + return result + + @classmethod + def _init_resource_fs(cls): + for path in resource.iterkeys(b'resfs/file/'): + path_str = path.decode('utf-8') + components = path_str.split('/') + for l in range(len(components)): + subpath = os.path.normpath('/'.join(components[:l])) + cls._resource_fs.setdefault(subpath, set()).add(components[l]) + + def __lookup(self, path): + if not self._resource_fs: + self._init_resource_fs() + path = os.path.normpath(path) + return self._resource_fs.get(path) + + def _listdir(self, path): + result = self.__lookup(path) + if result is None: + return [] + return list(result) + + def _isdir(self, path): + return bool(self.__lookup(path)) + + +class ResDistribution(DistInfoDistribution): + def __init__(self, prefix): + super(ResDistribution, self).__init__( + location=executable, + metadata=ResProvider(prefix), + precedence=BINARY_DIST, + ) + self.project_name = self._parsed_pkg_info.get('Name', self.project_name) + + +def find_in_res(importer, path_item, only=False): + for key in resource.iterkeys(): + if key.endswith('.dist-info/METADATA') and not key.startswith('resfs/src/'): + yield ResDistribution(key[:-8]) + + +register_finder(ResourceImporter, find_in_res) +register_loader_type(ResourceImporter, ResProvider.from_module) + + # Silence the PEP440Warning by default, so that end users don't get hit by it # randomly just because they use pkg_resources. We want to append the rule # because we want earlier uses of filterwarnings to take precedence over this