aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/setuptools/py3/patches/01-arcadia.patch
blob: 6f873d30e544cb723367960d6c0aadf89466d1c1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
--- contrib/python/setuptools/py3/pkg_resources/__init__.py	(index)
+++ contrib/python/setuptools/py3/pkg_resources/__init__.py	(working tree)
@@ -3229,6 +3229,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