02-fix-for-arcadia.patch 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. --- contrib/python/botocore/py3/botocore/data/endpoints.json (index)
  2. +++ contrib/python/botocore/py3/botocore/data/endpoints.json (working tree)
  3. @@ -21165,6 +21165,46 @@
  4. "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$",
  5. "regions" : { },
  6. "services" : { }
  7. + }, {
  8. + "defaults" : {
  9. + "hostname" : "{service}.{region}.{dnsSuffix}",
  10. + "protocols" : [ "https" ],
  11. + "signatureVersions" : [ "v4" ]
  12. + },
  13. + "dnsSuffix" : "yandex.net",
  14. + "partition" : "yandex",
  15. + "partitionName" : "Yandex",
  16. + "regions" : {
  17. + "yandex" : {
  18. + "description" : "Yandex"
  19. + }
  20. + },
  21. + "services" : {
  22. + "s3" : {
  23. + "defaults" : {
  24. + "protocols" : [ "http", "https" ],
  25. + "signatureVersions" : [ "s3", "s3v4" ]
  26. + },
  27. + "endpoints" : {
  28. + "yandex" : {
  29. + "hostname" : "s3.mds.yandex.net"
  30. + },
  31. + "yandex-test" : {
  32. + "hostname" : "s3.mdst.yandex.net"
  33. + }
  34. + }
  35. + },
  36. + "sqs" : {
  37. + "defaults" : {
  38. + "protocols" : [ "http" ]
  39. + },
  40. + "endpoints" : {
  41. + "yandex" : {
  42. + "hostname": "sqs.yandex.net:8771"
  43. + }
  44. + }
  45. + }
  46. + }
  47. } ],
  48. "version" : 3
  49. }
  50. \ No newline at end of file
  51. --- contrib/python/botocore/py3/botocore/__init__.py (index)
  52. +++ contrib/python/botocore/py3/botocore/__init__.py (working tree)
  53. @@ -64,1 +64,1 @@ _xform_cache = {
  54. -BOTOCORE_ROOT = os.path.dirname(os.path.abspath(__file__))
  55. +BOTOCORE_ROOT = os.path.dirname(__file__)
  56. --- contrib/python/botocore/py3/botocore/configprovider.py (index)
  57. +++ contrib/python/botocore/py3/botocore/configprovider.py (working tree)
  58. @@ -52,1 +52,1 @@ logger = logging.getLogger(__name__)
  59. - 'region': ('region', 'AWS_DEFAULT_REGION', None, None),
  60. + 'region': ('region', 'AWS_DEFAULT_REGION', 'yandex', None),
  61. --- contrib/python/botocore/py3/botocore/loaders.py (index)
  62. +++ contrib/python/botocore/py3/botocore/loaders.py (working tree)
  63. @@ -101,14 +101,17 @@ information that doesn't quite fit in the original models, but is still needed
  64. for the sdk. For instance, additional operation parameters might be added here
  65. which don't represent the actual service api.
  66. """
  67. +import collections
  68. import logging
  69. import os
  70. from botocore import BOTOCORE_ROOT
  71. -from botocore.compat import HAS_GZIP, OrderedDict, json
  72. +from botocore.compat import HAS_GZIP, OrderedDict, json, six
  73. from botocore.exceptions import DataNotFoundError, UnknownServiceError
  74. from botocore.utils import deep_merge
  75. +from library.python import resource
  76. +
  77. _JSON_OPEN_METHODS = {
  78. '.json': open,
  79. }
  80. @@ -197,6 +200,67 @@ class JSONFileLoader(object):
  81. return None
  82. +# SQS-119
  83. +class HybridJsonLoader(JSONFileLoader):
  84. +
  85. + type_data_cache = collections.defaultdict(lambda: collections.defaultdict(set))
  86. +
  87. + arcadia_resources_path = (
  88. + 'contrib/python/awscli/awscli/data/',
  89. + 'contrib/python/boto3/py3/boto3/data/',
  90. + 'contrib/python/botocore/py3/botocore/data/',
  91. + )
  92. +
  93. + @classmethod
  94. + def collect_service_data(cls):
  95. + if cls.type_data_cache:
  96. + return
  97. +
  98. + for res in resource.resfs_files():
  99. + res = six.ensure_str(res)
  100. + if res.startswith(cls.arcadia_resources_path):
  101. + splitted_path = res.split('/data/')[1].split('/')
  102. + if len(splitted_path) >= 3:
  103. + service_name, version, type_name = splitted_path[:3]
  104. + type_name = type_name.replace('.json.gz', '').replace('.json', '')
  105. + cls.type_data_cache[type_name][service_name].add(version)
  106. +
  107. + @classmethod
  108. + def read_from_resources(cls, file_path):
  109. + for ext in _JSON_OPEN_METHODS:
  110. + for prefix in cls.arcadia_resources_path:
  111. + path = f'{prefix}{file_path}{ext}'
  112. + data = resource.resfs_read(path)
  113. + if data:
  114. + return path, ext, data
  115. + return
  116. +
  117. + def exists(self, file_path):
  118. + if self.read_from_resources(file_path):
  119. + return True
  120. + return super(HybridJsonLoader, self).exists(file_path)
  121. +
  122. + def _load_resource(self, full_path, ext, data):
  123. + # By default the file will be opened with locale encoding on Python 3.
  124. + # We specify "utf8" here to ensure the correct behavior.
  125. + if ext == ".json":
  126. + payload = data.decode('utf-8')
  127. + elif ext == ".json.gz":
  128. + import io
  129. + with gzip_open(io.BytesIO(data)) as fp:
  130. + payload = fp.read().decode('utf-8')
  131. + else:
  132. + raise ValueError(f"Unknown extension {ext}")
  133. +
  134. + logger.debug("Loading JSON file: %s", full_path)
  135. + return json.loads(payload, object_pairs_hook=OrderedDict)
  136. +
  137. + def load_file(self, file_path):
  138. + if load_args := self.read_from_resources(file_path):
  139. + return self._load_resource(*load_args)
  140. + return super(HybridJsonLoader, self).load_file(file_path)
  141. +
  142. +
  143. def create_loader(search_path_string=None):
  144. """Create a Loader class.
  145. @@ -231,7 +279,7 @@ class Loader(object):
  146. """
  147. - FILE_LOADER_CLASS = JSONFileLoader
  148. + FILE_LOADER_CLASS = HybridJsonLoader
  149. # The included models in botocore/data/ that we ship with botocore.
  150. BUILTIN_DATA_PATH = os.path.join(BOTOCORE_ROOT, 'data')
  151. # For convenience we automatically add ~/.aws/models to the data path.
  152. @@ -316,6 +364,11 @@ class Loader(object):
  153. if self.file_loader.exists(full_load_path):
  154. services.add(service_name)
  155. break
  156. +
  157. + # SQS-119
  158. + HybridJsonLoader.collect_service_data()
  159. + services = services.union(HybridJsonLoader.type_data_cache[type_name].keys())
  160. +
  161. return sorted(services)
  162. @instance_cache
  163. @@ -367,6 +420,11 @@ class Loader(object):
  164. # to the type_name passed in.
  165. if self.file_loader.exists(full_path):
  166. known_api_versions.add(dirname)
  167. +
  168. + # SQS-119
  169. + HybridJsonLoader.collect_service_data()
  170. + known_api_versions = known_api_versions.union(HybridJsonLoader.type_data_cache[type_name][service_name])
  171. +
  172. if not known_api_versions:
  173. raise DataNotFoundError(data_path=service_name)
  174. return sorted(known_api_versions)
  175. @@ -449,6 +507,11 @@ class Loader(object):
  176. if found is not None:
  177. return found, possible_path
  178. + # SQS-119
  179. + found_by_arcadia_loader = self.file_loader.load_file(name)
  180. + if found_by_arcadia_loader is not None:
  181. + return found_by_arcadia_loader, None
  182. +
  183. # We didn't find anything that matched on any path.
  184. raise DataNotFoundError(data_path=name)
  185. @@ -499,6 +562,8 @@ class Loader:
  186. :return: Whether the given path is within the package's data directory.
  187. """
  188. + if path is None:
  189. + return True
  190. path = os.path.expanduser(os.path.expandvars(path))
  191. return path.startswith(self.BUILTIN_DATA_PATH)