koichi12 commited on
Commit
d2ae983
·
verified ·
1 Parent(s): ec07269

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. .venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/INSTALLER +1 -0
  3. .venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/METADATA +360 -0
  4. .venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/RECORD +42 -0
  5. .venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/WHEEL +4 -0
  6. .venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/licenses/LICENSE +21 -0
  7. .venv/lib/python3.11/site-packages/fsspec/__pycache__/spec.cpython-311.pyc +3 -0
  8. .venv/lib/python3.11/site-packages/pycountry/COPYRIGHT.txt +46 -0
  9. .venv/lib/python3.11/site-packages/pycountry/__init__.py +303 -0
  10. .venv/lib/python3.11/site-packages/pycountry/db.py +200 -0
  11. .venv/lib/python3.11/site-packages/pycountry/locales/an/LC_MESSAGES/iso3166-1.mo +0 -0
  12. .venv/lib/python3.11/site-packages/pycountry/locales/ay/LC_MESSAGES/iso3166-1.mo +0 -0
  13. .venv/lib/python3.11/site-packages/pycountry/locales/bar/LC_MESSAGES/iso3166-1.mo +0 -0
  14. .venv/lib/python3.11/site-packages/pycountry/locales/bi/LC_MESSAGES/iso3166-1.mo +0 -0
  15. .venv/lib/python3.11/site-packages/pycountry/locales/byn/LC_MESSAGES/iso3166-1.mo +0 -0
  16. .venv/lib/python3.11/site-packages/pycountry/locales/byn/LC_MESSAGES/iso3166-3.mo +0 -0
  17. .venv/lib/python3.11/site-packages/pycountry/locales/byn/LC_MESSAGES/iso639-3.mo +0 -0
  18. .venv/lib/python3.11/site-packages/pycountry/locales/ch/LC_MESSAGES/iso3166-1.mo +0 -0
  19. .venv/lib/python3.11/site-packages/pycountry/locales/ckb/LC_MESSAGES/iso3166-1.mo +0 -0
  20. .venv/lib/python3.11/site-packages/pycountry/locales/csb/LC_MESSAGES/iso3166-1.mo +0 -0
  21. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso15924.mo +0 -0
  22. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso3166-1.mo +0 -0
  23. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso3166-2.mo +0 -0
  24. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso3166-3.mo +0 -0
  25. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso4217.mo +0 -0
  26. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso639-3.mo +0 -0
  27. .venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso639-5.mo +0 -0
  28. .venv/lib/python3.11/site-packages/pycountry/locales/gez/LC_MESSAGES/iso3166-1.mo +0 -0
  29. .venv/lib/python3.11/site-packages/pycountry/locales/gez/LC_MESSAGES/iso3166-3.mo +0 -0
  30. .venv/lib/python3.11/site-packages/pycountry/locales/gez/LC_MESSAGES/iso639-3.mo +0 -0
  31. .venv/lib/python3.11/site-packages/pycountry/locales/haw/LC_MESSAGES/iso3166-1.mo +0 -0
  32. .venv/lib/python3.11/site-packages/pycountry/locales/haw/LC_MESSAGES/iso3166-3.mo +0 -0
  33. .venv/lib/python3.11/site-packages/pycountry/locales/jam/LC_MESSAGES/iso3166-1.mo +0 -0
  34. .venv/lib/python3.11/site-packages/pycountry/locales/nah/LC_MESSAGES/iso3166-1.mo +0 -0
  35. .venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso15924.mo +0 -0
  36. .venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso3166-1.mo +0 -0
  37. .venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso3166-3.mo +0 -0
  38. .venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso4217.mo +0 -0
  39. .venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso639-3.mo +0 -0
  40. .venv/lib/python3.11/site-packages/pycountry/locales/or/LC_MESSAGES/iso3166-1.mo +0 -0
  41. .venv/lib/python3.11/site-packages/pycountry/locales/or/LC_MESSAGES/iso3166-3.mo +0 -0
  42. .venv/lib/python3.11/site-packages/pycountry/locales/pa_PK/LC_MESSAGES/iso15924.mo +0 -0
  43. .venv/lib/python3.11/site-packages/pycountry/locales/pa_PK/LC_MESSAGES/iso3166-2.mo +0 -0
  44. .venv/lib/python3.11/site-packages/pycountry/locales/pa_PK/LC_MESSAGES/iso3166-3.mo +0 -0
  45. .venv/lib/python3.11/site-packages/pycountry/locales/pi/LC_MESSAGES/iso3166-1.mo +0 -0
  46. .venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso15924.mo +0 -0
  47. .venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso3166-1.mo +0 -0
  48. .venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso3166-3.mo +0 -0
  49. .venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso4217.mo +0 -0
  50. .venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso639-3.mo +0 -0
.gitattributes CHANGED
@@ -212,3 +212,4 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/torch/_inductor/_
212
  .venv/lib/python3.11/site-packages/frozenlist/_frozenlist.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
213
  .venv/lib/python3.11/site-packages/uvloop/loop.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
214
  .venv/lib/python3.11/site-packages/functorch/_C.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
 
 
212
  .venv/lib/python3.11/site-packages/frozenlist/_frozenlist.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
213
  .venv/lib/python3.11/site-packages/uvloop/loop.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
214
  .venv/lib/python3.11/site-packages/functorch/_C.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
215
+ .venv/lib/python3.11/site-packages/fsspec/__pycache__/spec.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
.venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/METADATA ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.3
2
+ Name: einops
3
+ Version: 0.8.0
4
+ Summary: A new flavour of deep learning operations
5
+ Project-URL: Homepage, https://github.com/arogozhnikov/einops
6
+ Author: Alex Rogozhnikov
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Keywords: deep learning,einops,machine learning,neural networks,scientific computations,tensor manipulation
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+
16
+
17
+ <!--
18
+ <a href='http://arogozhnikov.github.io/images/einops/einops_video.mp4' >
19
+ <div align="center">
20
+ <img src="http://arogozhnikov.github.io/images/einops/einops_video.gif" alt="einops package examples" />
21
+ <br>
22
+ <small><a href='http://arogozhnikov.github.io/images/einops/einops_video.mp4'>This video in high quality (mp4)</a></small>
23
+ <br><br>
24
+ </div>
25
+ </a>
26
+ -->
27
+
28
+ <!-- this link magically rendered as video, unfortunately not in docs -->
29
+
30
+ https://user-images.githubusercontent.com/6318811/177030658-66f0eb5d-e136-44d8-99c9-86ae298ead5b.mp4
31
+
32
+
33
+
34
+
35
+ # einops
36
+ [![Run tests](https://github.com/arogozhnikov/einops/actions/workflows/run_tests.yml/badge.svg)](https://github.com/arogozhnikov/einops/actions/workflows/run_tests.yml)
37
+ [![PyPI version](https://badge.fury.io/py/einops.svg)](https://badge.fury.io/py/einops)
38
+ [![Documentation](https://img.shields.io/badge/documentation-link-blue.svg)](https://einops.rocks/)
39
+ ![Supported python versions](https://raw.githubusercontent.com/arogozhnikov/einops/master/docs/resources/python_badge.svg)
40
+
41
+
42
+ Flexible and powerful tensor operations for readable and reliable code. <br />
43
+ Supports numpy, pytorch, tensorflow, jax, and [others](#supported-frameworks).
44
+
45
+ ## Recent updates:
46
+
47
+ - 0.7.0: no-hassle `torch.compile`, support of [array api standard](https://data-apis.org/array-api/latest/API_specification/index.html) and more
48
+ - 10'000🎉: github reports that more than 10k project use einops
49
+ - einops 0.6.1: paddle backend added
50
+ - einops 0.6 introduces [packing and unpacking](https://github.com/arogozhnikov/einops/blob/master/docs/4-pack-and-unpack.ipynb)
51
+ - einops 0.5: einsum is now a part of einops
52
+ - [Einops paper](https://openreview.net/pdf?id=oapKSVM2bcj) is accepted for oral presentation at ICLR 2022 (yes, it worth reading).
53
+ Talk recordings are [available](https://iclr.cc/virtual/2022/oral/6603)
54
+
55
+
56
+ <details markdown="1">
57
+ <summary>Previous updates</summary>
58
+ - flax and oneflow backend added
59
+ - torch.jit.script is supported for pytorch layers
60
+ - powerful EinMix added to einops. [Einmix tutorial notebook](https://github.com/arogozhnikov/einops/blob/master/docs/3-einmix-layer.ipynb)
61
+ </details>
62
+
63
+ <!--<div align="center">
64
+ <img src="http://arogozhnikov.github.io/images/einops/einops_logo_350x350.png"
65
+ alt="einops package logo" width="250" height="250" />
66
+ <br><br>
67
+ </div> -->
68
+
69
+
70
+ ## Tweets
71
+
72
+ > In case you need convincing arguments for setting aside time to learn about einsum and einops...
73
+ [Tim Rocktäschel](https://twitter.com/_rockt/status/1230818967205425152)
74
+
75
+ > Writing better code with PyTorch and einops 👌
76
+ [Andrej Karpathy](https://twitter.com/karpathy/status/1290826075916779520)
77
+
78
+ > Slowly but surely, einops is seeping in to every nook and cranny of my code. If you find yourself shuffling around bazillion dimensional tensors, this might change your life
79
+ [Nasim Rahaman](https://twitter.com/nasim_rahaman/status/1216022614755463169)
80
+
81
+ [More testimonials](https://einops.rocks/pages/testimonials/)
82
+
83
+ <!--
84
+ ## Recordings of talk at ICLR 2022
85
+
86
+ <a href='https://iclr.cc/virtual/2022/oral/6603'>
87
+ <img width="922" alt="Screen Shot 2022-07-03 at 1 00 15 AM" src="https://user-images.githubusercontent.com/6318811/177030789-89d349bf-ef75-4af5-a71f-609896d1c8d9.png">
88
+ </a>
89
+
90
+ Watch [a 15-minute talk](https://iclr.cc/virtual/2022/oral/6603) focused on main problems of standard tensor manipulation methods, and how einops improves this process.
91
+ -->
92
+
93
+ ## Contents
94
+
95
+ - [Installation](#Installation)
96
+ - [Documentation](https://einops.rocks/)
97
+ - [Tutorial](#Tutorials)
98
+ - [API micro-reference](#API)
99
+ - [Why using einops](#Why-using-einops-notation)
100
+ - [Supported frameworks](#Supported-frameworks)
101
+ - [Citing](#Citing)
102
+ - [Repository](https://github.com/arogozhnikov/einops) and [discussions](https://github.com/arogozhnikov/einops/discussions)
103
+
104
+ ## Installation <a name="Installation"></a>
105
+
106
+ Plain and simple:
107
+ ```bash
108
+ pip install einops
109
+ ```
110
+
111
+ <!--
112
+ `einops` has no mandatory dependencies (code examples also require jupyter, pillow + backends).
113
+ To obtain the latest github version
114
+
115
+ ```bash
116
+ pip install https://github.com/arogozhnikov/einops/archive/master.zip
117
+ ```
118
+ -->
119
+
120
+ ## Tutorials <a name="Tutorials"></a>
121
+
122
+ Tutorials are the most convenient way to see `einops` in action
123
+
124
+ - part 1: [einops fundamentals](https://github.com/arogozhnikov/einops/blob/master/docs/1-einops-basics.ipynb)
125
+ - part 2: [einops for deep learning](https://github.com/arogozhnikov/einops/blob/master/docs/2-einops-for-deep-learning.ipynb)
126
+ - part 3: [packing and unpacking](https://github.com/arogozhnikov/einops/blob/master/docs/4-pack-and-unpack.ipynb)
127
+ - part 4: [improve pytorch code with einops](http://einops.rocks/pytorch-examples.html)
128
+
129
+ Kapil Sachdeva recorded a small [intro to einops](https://www.youtube.com/watch?v=xGy75Pjsqzo).
130
+
131
+ ## API <a name="API"></a>
132
+
133
+ `einops` has a minimalistic yet powerful API.
134
+
135
+ Three core operations provided ([einops tutorial](https://github.com/arogozhnikov/einops/blob/master/docs/)
136
+ shows those cover stacking, reshape, transposition, squeeze/unsqueeze, repeat, tile, concatenate, view and numerous reductions)
137
+
138
+ ```python
139
+ from einops import rearrange, reduce, repeat
140
+ # rearrange elements according to the pattern
141
+ output_tensor = rearrange(input_tensor, 't b c -> b c t')
142
+ # combine rearrangement and reduction
143
+ output_tensor = reduce(input_tensor, 'b c (h h2) (w w2) -> b h w c', 'mean', h2=2, w2=2)
144
+ # copy along a new axis
145
+ output_tensor = repeat(input_tensor, 'h w -> h w c', c=3)
146
+ ```
147
+
148
+ Later additions to the family are `pack` and `unpack` functions (better than stack/split/concatenate):
149
+
150
+ ```python
151
+ from einops import pack, unpack
152
+ # pack and unpack allow reversibly 'packing' multiple tensors into one.
153
+ # Packed tensors may be of different dimensionality:
154
+ packed, ps = pack([class_token_bc, image_tokens_bhwc, text_tokens_btc], 'b * c')
155
+ class_emb_bc, image_emb_bhwc, text_emb_btc = unpack(transformer(packed), ps, 'b * c')
156
+ ```
157
+
158
+ Finally, einops provides einsum with a support of multi-lettered names:
159
+
160
+ ```python
161
+ from einops import einsum, pack, unpack
162
+ # einsum is like ... einsum, generic and flexible dot-product
163
+ # but 1) axes can be multi-lettered 2) pattern goes last 3) works with multiple frameworks
164
+ C = einsum(A, B, 'b t1 head c, b t2 head c -> b head t1 t2')
165
+ ```
166
+
167
+ ### EinMix
168
+
169
+ `EinMix` is a generic linear layer, perfect for MLP Mixers and similar architectures.
170
+
171
+ ### Layers
172
+
173
+ Einops provides layers (`einops` keeps a separate version for each framework) that reflect corresponding functions
174
+
175
+ ```python
176
+ from einops.layers.torch import Rearrange, Reduce
177
+ from einops.layers.tensorflow import Rearrange, Reduce
178
+ from einops.layers.flax import Rearrange, Reduce
179
+ from einops.layers.paddle import Rearrange, Reduce
180
+ from einops.layers.chainer import Rearrange, Reduce
181
+ ```
182
+
183
+ <details markdown="1">
184
+ <summary>Example of using layers within a pytorch model</summary>
185
+ Example given for pytorch, but code in other frameworks is almost identical
186
+
187
+ ```python
188
+ from torch.nn import Sequential, Conv2d, MaxPool2d, Linear, ReLU
189
+ from einops.layers.torch import Rearrange
190
+
191
+ model = Sequential(
192
+ ...,
193
+ Conv2d(6, 16, kernel_size=5),
194
+ MaxPool2d(kernel_size=2),
195
+ # flattening without need to write forward
196
+ Rearrange('b c h w -> b (c h w)'),
197
+ Linear(16*5*5, 120),
198
+ ReLU(),
199
+ Linear(120, 10),
200
+ )
201
+ ```
202
+
203
+ No more flatten needed!
204
+
205
+ Additionally, torch users will benefit from layers as those are script-able and compile-able.
206
+ </details>
207
+
208
+
209
+
210
+
211
+ ## Naming <a name="Naming"></a>
212
+
213
+ `einops` stands for Einstein-Inspired Notation for operations
214
+ (though "Einstein operations" is more attractive and easier to remember).
215
+
216
+ Notation was loosely inspired by Einstein summation (in particular by `numpy.einsum` operation).
217
+
218
+ ## Why use `einops` notation?! <a name="Why-using-einops-notation"></a>
219
+
220
+
221
+ ### Semantic information (being verbose in expectations)
222
+
223
+ ```python
224
+ y = x.view(x.shape[0], -1)
225
+ y = rearrange(x, 'b c h w -> b (c h w)')
226
+ ```
227
+ While these two lines are doing the same job in *some* context,
228
+ the second one provides information about the input and output.
229
+ In other words, `einops` focuses on interface: *what is the input and output*, not *how* the output is computed.
230
+
231
+ The next operation looks similar:
232
+
233
+ ```python
234
+ y = rearrange(x, 'time c h w -> time (c h w)')
235
+ ```
236
+ but it gives the reader a hint:
237
+ this is not an independent batch of images we are processing,
238
+ but rather a sequence (video).
239
+
240
+ Semantic information makes the code easier to read and maintain.
241
+
242
+ ### Convenient checks
243
+
244
+ Reconsider the same example:
245
+
246
+ ```python
247
+ y = x.view(x.shape[0], -1) # x: (batch, 256, 19, 19)
248
+ y = rearrange(x, 'b c h w -> b (c h w)')
249
+ ```
250
+ The second line checks that the input has four dimensions,
251
+ but you can also specify particular dimensions.
252
+ That's opposed to just writing comments about shapes since comments don't prevent mistakes, not tested, and without code review tend to be outdated
253
+ ```python
254
+ y = x.view(x.shape[0], -1) # x: (batch, 256, 19, 19)
255
+ y = rearrange(x, 'b c h w -> b (c h w)', c=256, h=19, w=19)
256
+ ```
257
+
258
+ ### Result is strictly determined
259
+
260
+ Below we have at least two ways to define the depth-to-space operation
261
+ ```python
262
+ # depth-to-space
263
+ rearrange(x, 'b c (h h2) (w w2) -> b (c h2 w2) h w', h2=2, w2=2)
264
+ rearrange(x, 'b c (h h2) (w w2) -> b (h2 w2 c) h w', h2=2, w2=2)
265
+ ```
266
+ There are at least four more ways to do it. Which one is used by the framework?
267
+
268
+ These details are ignored, since *usually* it makes no difference,
269
+ but it can make a big difference (e.g. if you use grouped convolutions in the next stage),
270
+ and you'd like to specify this in your code.
271
+
272
+
273
+ ### Uniformity
274
+
275
+ ```python
276
+ reduce(x, 'b c (x dx) -> b c x', 'max', dx=2)
277
+ reduce(x, 'b c (x dx) (y dy) -> b c x y', 'max', dx=2, dy=3)
278
+ reduce(x, 'b c (x dx) (y dy) (z dz) -> b c x y z', 'max', dx=2, dy=3, dz=4)
279
+ ```
280
+ These examples demonstrated that we don't use separate operations for 1d/2d/3d pooling,
281
+ those are all defined in a uniform way.
282
+
283
+ Space-to-depth and depth-to space are defined in many frameworks but how about width-to-height? Here you go:
284
+
285
+ ```python
286
+ rearrange(x, 'b c h (w w2) -> b c (h w2) w', w2=2)
287
+ ```
288
+
289
+ ### Framework independent behavior
290
+
291
+ Even simple functions are defined differently by different frameworks
292
+
293
+ ```python
294
+ y = x.flatten() # or flatten(x)
295
+ ```
296
+
297
+ Suppose `x`'s shape was `(3, 4, 5)`, then `y` has shape ...
298
+
299
+ - numpy, pytorch, cupy, chainer: `(60,)`
300
+ - keras, tensorflow.layers, gluon: `(3, 20)`
301
+
302
+ `einops` works the same way in all frameworks.
303
+
304
+ ### Independence of framework terminology
305
+
306
+ Example: `tile` vs `repeat` causes lots of confusion. To copy image along width:
307
+ ```python
308
+ np.tile(image, (1, 2)) # in numpy
309
+ image.repeat(1, 2) # pytorch's repeat ~ numpy's tile
310
+ ```
311
+
312
+ With einops you don't need to decipher which axis was repeated:
313
+ ```python
314
+ repeat(image, 'h w -> h (tile w)', tile=2) # in numpy
315
+ repeat(image, 'h w -> h (tile w)', tile=2) # in pytorch
316
+ repeat(image, 'h w -> h (tile w)', tile=2) # in tf
317
+ repeat(image, 'h w -> h (tile w)', tile=2) # in jax
318
+ repeat(image, 'h w -> h (tile w)', tile=2) # in cupy
319
+ ... (etc.)
320
+ ```
321
+
322
+ [Testimonials](https://einops.rocks/pages/testimonials/) provide users' perspective on the same question.
323
+
324
+ ## Supported frameworks <a name="Supported-frameworks"></a>
325
+
326
+ Einops works with ...
327
+
328
+ - [numpy](http://www.numpy.org/)
329
+ - [pytorch](https://pytorch.org/)
330
+ - [tensorflow](https://www.tensorflow.org/)
331
+ - [jax](https://github.com/google/jax)
332
+ - [cupy](https://cupy.chainer.org/)
333
+ - [chainer](https://chainer.org/)
334
+ - [tf.keras](https://www.tensorflow.org/guide/keras)
335
+ - [flax](https://github.com/google/flax) (experimental)
336
+ - [paddle](https://github.com/PaddlePaddle/Paddle) (experimental)
337
+ - [oneflow](https://github.com/Oneflow-Inc/oneflow) (community)
338
+ - [tinygrad](https://github.com/tinygrad/tinygrad) (community)
339
+
340
+ Additionally, starting from einops 0.7.0 einops can be used with any framework that supports [Python array API standard](https://data-apis.org/array-api/latest/API_specification/index.html)
341
+
342
+ ## Citing einops <a name="Citing"></a>
343
+
344
+ Please use the following bibtex record
345
+
346
+ ```text
347
+ @inproceedings{
348
+ rogozhnikov2022einops,
349
+ title={Einops: Clear and Reliable Tensor Manipulations with Einstein-like Notation},
350
+ author={Alex Rogozhnikov},
351
+ booktitle={International Conference on Learning Representations},
352
+ year={2022},
353
+ url={https://openreview.net/forum?id=oapKSVM2bcj}
354
+ }
355
+ ```
356
+
357
+
358
+ ## Supported python versions
359
+
360
+ `einops` works with python 3.8 or later.
.venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/RECORD ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ einops-0.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ einops-0.8.0.dist-info/METADATA,sha256=5hTpaWnwYNe3QvhbXYTpA_LUJ2lSlyspSc0gRGni7sY,12926
3
+ einops-0.8.0.dist-info/RECORD,,
4
+ einops-0.8.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
5
+ einops-0.8.0.dist-info/licenses/LICENSE,sha256=MNmENkKW9R_67K1LAe4SfpUlDFBokY1LZvyWIGcj5DQ,1073
6
+ einops/__init__.py,sha256=UdixJ9CShlEOQfw0xcU6zYtrAn6Durgh6jCQWdcaQK4,422
7
+ einops/__pycache__/__init__.cpython-311.pyc,,
8
+ einops/__pycache__/_backends.cpython-311.pyc,,
9
+ einops/__pycache__/_torch_specific.cpython-311.pyc,,
10
+ einops/__pycache__/array_api.cpython-311.pyc,,
11
+ einops/__pycache__/einops.cpython-311.pyc,,
12
+ einops/__pycache__/packing.cpython-311.pyc,,
13
+ einops/__pycache__/parsing.cpython-311.pyc,,
14
+ einops/_backends.py,sha256=VHPPrL1mf0PDTvyFPZvmZeTqGJoWflqv7b-eoJUHudo,21081
15
+ einops/_torch_specific.py,sha256=yMaQeqAZhBLWR1Q-Jv6uRINJfzROhLb-rzKKevpefUU,4138
16
+ einops/array_api.py,sha256=FcKZSo7l8jC5HL8qudutz1K5x9cFpwACMDcjfbvEKmQ,5251
17
+ einops/einops.py,sha256=AYZe5yMlH-EXO0MWFv27ajyPdVTFpYloaSCRM9jw5sA,37252
18
+ einops/experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ einops/experimental/__pycache__/__init__.cpython-311.pyc,,
20
+ einops/experimental/__pycache__/indexing.cpython-311.pyc,,
21
+ einops/experimental/indexing.py,sha256=4NtRNmSOrpUURvwhrbbGNK3NeTxHI4EW8R6ct3JZyLw,14868
22
+ einops/layers/__init__.py,sha256=vBtnAt2afs4QlqpeFU4dlZNxBuC9IXl3fmilk-2OzHM,3747
23
+ einops/layers/__pycache__/__init__.cpython-311.pyc,,
24
+ einops/layers/__pycache__/_einmix.cpython-311.pyc,,
25
+ einops/layers/__pycache__/chainer.cpython-311.pyc,,
26
+ einops/layers/__pycache__/flax.cpython-311.pyc,,
27
+ einops/layers/__pycache__/keras.cpython-311.pyc,,
28
+ einops/layers/__pycache__/oneflow.cpython-311.pyc,,
29
+ einops/layers/__pycache__/paddle.cpython-311.pyc,,
30
+ einops/layers/__pycache__/tensorflow.cpython-311.pyc,,
31
+ einops/layers/__pycache__/torch.cpython-311.pyc,,
32
+ einops/layers/_einmix.py,sha256=0cl3r4Xp44S2HO-tx0MHa4cMFD2KJXpG5O-4gJM5AtU,8464
33
+ einops/layers/chainer.py,sha256=hUB-XSjN5CP8zALZtalL3n2lQkq7vymftRI8okEMO2Q,1861
34
+ einops/layers/flax.py,sha256=zFy83gSLRm31cLuKFRvZ82_HsefnXPbRvkKZh1KkC1I,2536
35
+ einops/layers/keras.py,sha256=-7So0w94phvf9HdW0xi2mSeBg02qVPvAyfp_1XR02NM,212
36
+ einops/layers/oneflow.py,sha256=YEPzz4xc7BDRQfb8ulD3teqQJdbO6qQg7Z4KIPVTLz8,1864
37
+ einops/layers/paddle.py,sha256=8cRZQ8BT9vYEczh7pNProuTM_3XjLty2ht2sdvXNFiI,1907
38
+ einops/layers/tensorflow.py,sha256=T9uhSVwbXREahc31ARAHoN5K-7zsuS8NRNPdY6Zk1Bc,3324
39
+ einops/layers/torch.py,sha256=504G99kEgy7dk1UPBbj9hzJmZkAHwVhMDFN_8J-p3C8,2399
40
+ einops/packing.py,sha256=Ln2lAMko9hobi_qd-4dPtQY0Ks5hRK7x-5FthL2gunk,7654
41
+ einops/parsing.py,sha256=xbqcvwReLiROEucoegZ20WQiEHlLg0uxo_vYoezKB_4,6746
42
+ einops/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
.venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.24.2
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
.venv/lib/python3.11/site-packages/einops-0.8.0.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Alex Rogozhnikov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.11/site-packages/fsspec/__pycache__/spec.cpython-311.pyc ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:35393347e555c64ec1f982848d600d95a4cba3d655679aa08a140b06534d80c6
3
+ size 100192
.venv/lib/python3.11/site-packages/pycountry/COPYRIGHT.txt ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ COPYRIGHT (c) 2008 - 2023, pycountry
2
+
3
+ Pycountry is free software; you can redistribute it and/or modify
4
+ it under the terms of the GNU Lesser General Public License as published by
5
+ the Free Software Foundation; either version 2.1 of the License, or any later version.
6
+
7
+ This project is distributed in the hope that it will be useful,
8
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ GNU Lesser General Public License for more details.
11
+
12
+ Contributors:
13
+ - Christian Theune (2008-2020, 2022)
14
+ - Nate Schimmoller (2022-2023)
15
+ - Zachary Ware (2016, 2023)
16
+ - Alan Orth (2023)
17
+ - Ashok Argent-Katwala (2020)
18
+ - Bastien Vallet (2020)
19
+ - Chris R Bunney 2020
20
+ - Christian Zagrodnick (2012-2013)
21
+ - Christoph Zwerschke (2013)
22
+ - Jakub Wilk (2020)
23
+ - Janis Kirsteins (2019)
24
+ - Justin Ryan Wagner 2014
25
+ - Kevin Deldycke (2014, 2016)
26
+ - Louis Sautier (2020)
27
+ - Lucas Wiman (2015)
28
+ - Mario Vilas (2014)
29
+ - Michael Howitz (2020)
30
+ - Michał Bielawski (2021, 2023)
31
+ - Michał Górny (2020)
32
+ - Mike Taves (2023)
33
+ - Pedro Ferreira (2013)
34
+ - Stuart Prescott (2021)
35
+ - Victor Mireyev (2016)
36
+ - simon klemenc (2016)
37
+
38
+ Additional Acknowledgements and Licensing Information:
39
+ - Data in the /src/databases/ and /src/locales/ folders is sourced from the Debian iso-codes project, available at: https://salsa.debian.org/iso-codes-team/iso-codes. This data is used under the terms of the GNU Lesser General Public License Version 2.1 (February 1999).
40
+
41
+ The Debian iso-codes project is a collection of code lists for different standards, maintained and made available under the GNU Lesser General Public License Version 2.1. We gratefully acknowledge the Debian iso-codes team and contributors for their work and for making this resource freely available.
42
+
43
+ The full text of the GNU Lesser General Public License Version 2.1 can be found at: https://salsa.debian.org/iso-codes-team/iso-codes/-/blob/main/COPYING.
44
+
45
+ For the full text of the GNU Lesser General Public License,
46
+ see https://github.com/pycountry/pycountry/blob/main/LICENSE.txt.
.venv/lib/python3.11/site-packages/pycountry/__init__.py ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """pycountry"""
2
+
3
+ import os.path
4
+ import unicodedata
5
+ from importlib import metadata as _importlib_metadata
6
+ from typing import Dict, List, Optional, Type
7
+
8
+ import pycountry.db
9
+
10
+ # We prioritise importing the backported `importlib_resources`
11
+ # because the function we use (`importlib.resources.files`) is only
12
+ # available from Python 3.9, but the module itself exists since 3.7.
13
+ # We install `importlib_resources` on Python < 3.9.
14
+ # TODO: Remove usage of importlib_resources once support for Python 3.8 is dropped
15
+ try:
16
+ import importlib_resources # type: ignore
17
+ except ModuleNotFoundError:
18
+ from importlib import resources as importlib_resources # type: ignore
19
+
20
+
21
+ def resource_filename(package_or_requirement: str, resource_name: str) -> str:
22
+ return str(
23
+ importlib_resources.files(package_or_requirement) / resource_name
24
+ )
25
+
26
+
27
+ def get_version(distribution_name: str) -> Optional[str]:
28
+ try:
29
+ return _importlib_metadata.version(distribution_name)
30
+ except _importlib_metadata.PackageNotFoundError:
31
+ return "n/a"
32
+
33
+
34
+ # Variable annotations
35
+ LOCALES_DIR: str = resource_filename("pycountry", "locales")
36
+ DATABASE_DIR: str = resource_filename("pycountry", "databases")
37
+ __version__: Optional[str] = get_version("pycountry")
38
+
39
+
40
+ def remove_accents(input_str: str) -> str:
41
+ output_str = input_str
42
+ if not input_str.isascii():
43
+ # Borrowed from https://stackoverflow.com/a/517974/1509718
44
+ nfkd_form = unicodedata.normalize("NFKD", input_str)
45
+ output_str = "".join(
46
+ [c for c in nfkd_form if not unicodedata.combining(c)]
47
+ )
48
+ return output_str
49
+
50
+
51
+ class ExistingCountries(pycountry.db.Database):
52
+ """Provides access to an ISO 3166 database (Countries)."""
53
+
54
+ data_class = pycountry.db.Country
55
+ root_key = "3166-1"
56
+
57
+ def search_fuzzy(self, query: str) -> List[Type["ExistingCountries"]]:
58
+ query = remove_accents(query.strip().lower())
59
+
60
+ # A country-code to points mapping for later sorting countries
61
+ # based on the query's matching incidence.
62
+ results: dict[str, int] = {}
63
+
64
+ def add_result(country: "pycountry.db.Country", points: int) -> None:
65
+ results.setdefault(country.alpha_2, 0)
66
+ results[country.alpha_2] += points
67
+
68
+ # Prio 1: exact matches on country names
69
+ try:
70
+ add_result(self.lookup(query), 50)
71
+ except LookupError:
72
+ pass
73
+
74
+ # Prio 2: exact matches on subdivision names
75
+ match_subdivions = pycountry.Subdivisions.match(
76
+ self=subdivisions, query=query
77
+ )
78
+ for candidate in match_subdivions:
79
+ add_result(candidate.country, 49)
80
+
81
+ # Prio 3: partial matches on country names
82
+ for candidate in self:
83
+ # Higher priority for a match on the common name
84
+ for v in [
85
+ candidate._fields.get("name"),
86
+ candidate._fields.get("official_name"),
87
+ candidate._fields.get("comment"),
88
+ ]:
89
+ if v is not None:
90
+ v = remove_accents(v.lower())
91
+ if query in v:
92
+ # This prefers countries with a match early in their name
93
+ # and also balances against countries with a number of
94
+ # partial matches and their name containing 'new' in the
95
+ # middle
96
+ add_result(
97
+ candidate, max([5, 30 - (2 * v.find(query))])
98
+ )
99
+ break
100
+
101
+ # Prio 4: partial matches on subdivision names
102
+ partial_match_subdivisions = pycountry.Subdivisions.partial_match(
103
+ self=subdivisions, query=query
104
+ )
105
+ for candidate in partial_match_subdivisions:
106
+ v = candidate._fields.get("name")
107
+ v = remove_accents(v.lower())
108
+ if query in v:
109
+ add_result(candidate.country, max([1, 5 - v.find(query)]))
110
+
111
+ if not results:
112
+ raise LookupError(query)
113
+
114
+ sorted_results = [
115
+ self.get(alpha_2=x[0])
116
+ # sort by points first, by alpha2 code second, and to ensure stable
117
+ # results the negative value allows us to sort reversely on the
118
+ # points but ascending on the country code.
119
+ for x in sorted(results.items(), key=lambda x: (-x[1], x[0]))
120
+ ]
121
+ return sorted_results
122
+
123
+
124
+ class HistoricCountries(ExistingCountries):
125
+ """Provides access to an ISO 3166-3 database
126
+ (Countries that have been removed from the standard)."""
127
+
128
+ data_class = pycountry.db.Country
129
+ root_key = "3166-3"
130
+
131
+
132
+ class Scripts(pycountry.db.Database):
133
+ """Provides access to an ISO 15924 database (Scripts)."""
134
+
135
+ data_class = "Script"
136
+ root_key = "15924"
137
+
138
+
139
+ class Currencies(pycountry.db.Database):
140
+ """Provides access to an ISO 4217 database (Currencies)."""
141
+
142
+ data_class = "Currency"
143
+ root_key = "4217"
144
+
145
+
146
+ class Languages(pycountry.db.Database):
147
+ """Provides access to an ISO 639-1/2T/3 database (Languages)."""
148
+
149
+ no_index = ["status", "scope", "type", "inverted_name", "common_name"]
150
+
151
+ data_class = "Language"
152
+ root_key = "639-3"
153
+
154
+
155
+ class LanguageFamilies(pycountry.db.Database):
156
+ """Provides access to an ISO 639-5 database
157
+ (Language Families and Groups)."""
158
+
159
+ data_class = "LanguageFamily"
160
+ root_key = "639-5"
161
+
162
+
163
+ class SubdivisionHierarchy(pycountry.db.Data):
164
+ def __init__(self, **kw):
165
+ if "parent" in kw:
166
+ kw["parent_code"] = kw["parent"]
167
+ else:
168
+ kw["parent_code"] = None
169
+ super().__init__(**kw)
170
+ self.country_code = self.code.split("-")[0]
171
+ if self.parent_code is not None:
172
+ # Split the parent_code to check if the country_code is already present
173
+ parts = self.parent_code.split("-")
174
+ if parts[0] != self.country_code:
175
+ self.parent_code = f"{self.country_code}-{self.parent_code}"
176
+
177
+ @property
178
+ def country(self):
179
+ return countries.get(alpha_2=self.country_code)
180
+
181
+ @property
182
+ def parent(self):
183
+ if not self.parent_code:
184
+ return None
185
+ return subdivisions.get(code=self.parent_code)
186
+
187
+
188
+ class Subdivisions(pycountry.db.Database):
189
+ # Note: subdivisions can be hierarchical to other subdivisions. The
190
+ # parent_code attribute is related to other subdivisions, *not*
191
+ # the country!
192
+
193
+ data_class = SubdivisionHierarchy
194
+ no_index = ["name", "parent_code", "parent", "type"]
195
+ root_key = "3166-2"
196
+
197
+ def _load(self, *args, **kw):
198
+ super()._load(*args, **kw)
199
+
200
+ # Add index for the country code.
201
+ self.indices["country_code"] = {}
202
+ for subdivision in self:
203
+ divs = self.indices["country_code"].setdefault(
204
+ subdivision.country_code.lower(), set()
205
+ )
206
+ divs.add(subdivision)
207
+
208
+ def get(self, **kw):
209
+ default = kw.setdefault("default", None)
210
+ subdivisions = super().get(**kw)
211
+ if subdivisions is default and "country_code" in kw:
212
+ # This handles the case where we know about a country but there
213
+ # are no subdivisions: we return an empty list in this case
214
+ # (sticking to the expected type here) instead of None.
215
+ if countries.get(alpha_2=kw["country_code"]) is not None:
216
+ return []
217
+ return subdivisions
218
+
219
+ def match(self, query):
220
+ query = remove_accents(query.strip().lower())
221
+ matching_candidates = []
222
+ for candidate in subdivisions:
223
+ for v in candidate._fields.values():
224
+ if v is not None:
225
+ v = remove_accents(v.lower())
226
+ # Some names include alternative versions which we want to
227
+ # match exactly.
228
+ for w in v.split(";"):
229
+ if w == query:
230
+ matching_candidates.append(candidate)
231
+ break
232
+
233
+ return matching_candidates
234
+
235
+ def partial_match(self, query):
236
+ query = remove_accents(query.strip().lower())
237
+ matching_candidates = []
238
+ for candidate in subdivisions:
239
+ v = candidate._fields.get("name")
240
+ v = remove_accents(v.lower())
241
+ if query in v:
242
+ matching_candidates.append(candidate)
243
+
244
+ return matching_candidates
245
+
246
+ def search_fuzzy(self, query: str) -> List[Type["Subdivisions"]]:
247
+ query = remove_accents(query.strip().lower())
248
+
249
+ # A Subdivision's code to points mapping for later sorting subdivisions
250
+ # based on the query's matching incidence.
251
+ results: dict[str, int] = {}
252
+
253
+ def add_result(
254
+ subdivision: "pycountry.db.Subdivision", points: int
255
+ ) -> None:
256
+ results.setdefault(subdivision.code, 0)
257
+ results[subdivision.code] += points
258
+
259
+ # Prio 1: exact matches on subdivision names
260
+ match_subdivisions = self.match(query)
261
+ for candidate in match_subdivisions:
262
+ add_result(candidate, 50)
263
+
264
+ # Prio 2: partial matches on subdivision names
265
+ partial_match_subdivisions = self.partial_match(query)
266
+ for candidate in partial_match_subdivisions:
267
+ v = candidate._fields.get("name")
268
+ v = remove_accents(v.lower())
269
+ if query in v:
270
+ add_result(candidate, max([1, 5 - v.find(query)]))
271
+
272
+ if not results:
273
+ raise LookupError(query)
274
+
275
+ sorted_results = [
276
+ self.get(code=x[0])
277
+ # sort by points first, by alpha2 code second, and to ensure stable
278
+ # results the negative value allows us to sort reversely on the
279
+ # points but ascending on the country code.
280
+ for x in sorted(results.items(), key=lambda x: (-x[1], x[0]))
281
+ ]
282
+ return sorted_results
283
+
284
+
285
+ # Initialize instances with type hints
286
+ countries: ExistingCountries = ExistingCountries(
287
+ os.path.join(DATABASE_DIR, "iso3166-1.json")
288
+ )
289
+ subdivisions: Subdivisions = Subdivisions(
290
+ os.path.join(DATABASE_DIR, "iso3166-2.json")
291
+ )
292
+ historic_countries: HistoricCountries = HistoricCountries(
293
+ os.path.join(DATABASE_DIR, "iso3166-3.json")
294
+ )
295
+
296
+ currencies: Currencies = Currencies(os.path.join(DATABASE_DIR, "iso4217.json"))
297
+
298
+ languages: Languages = Languages(os.path.join(DATABASE_DIR, "iso639-3.json"))
299
+ language_families: LanguageFamilies = LanguageFamilies(
300
+ os.path.join(DATABASE_DIR, "iso639-5.json")
301
+ )
302
+
303
+ scripts: Scripts = Scripts(os.path.join(DATABASE_DIR, "iso15924.json"))
.venv/lib/python3.11/site-packages/pycountry/db.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import logging
3
+ import threading
4
+ from typing import Any, Iterator, List, Optional, Type, Union
5
+
6
+ logger = logging.getLogger("pycountry.db")
7
+
8
+
9
+ class Data:
10
+ def __init__(self, **fields: str):
11
+ self._fields = fields
12
+
13
+ def __getattr__(self, key):
14
+ if key in self._fields:
15
+ return self._fields[key]
16
+ raise AttributeError(key)
17
+
18
+ def __setattr__(self, key: str, value: str) -> None:
19
+ if key != "_fields":
20
+ self._fields[key] = value
21
+ super().__setattr__(key, value)
22
+
23
+ def __repr__(self) -> str:
24
+ cls_name = self.__class__.__name__
25
+ fields = ", ".join("%s=%r" % i for i in sorted(self._fields.items()))
26
+ return f"{cls_name}({fields})"
27
+
28
+ def __dir__(self) -> List[str]:
29
+ return dir(self.__class__) + list(self._fields)
30
+
31
+ def __iter__(self):
32
+ # allow casting into a dict
33
+ for field in self._fields:
34
+ yield field, getattr(self, field)
35
+
36
+
37
+ class Country(Data):
38
+ pass
39
+
40
+
41
+ class Subdivision(Data):
42
+ pass
43
+
44
+
45
+ def lazy_load(f):
46
+ def load_if_needed(self, *args, **kw):
47
+ if not self._is_loaded:
48
+ with self._load_lock:
49
+ self._load()
50
+ return f(self, *args, **kw)
51
+
52
+ return load_if_needed
53
+
54
+
55
+ class Database:
56
+ data_class: Union[Type, str]
57
+ root_key: Optional[str] = None
58
+ no_index: List[str] = []
59
+
60
+ def __init__(self, filename: str) -> None:
61
+ self.filename = filename
62
+ self._is_loaded = False
63
+ self._load_lock = threading.Lock()
64
+
65
+ if isinstance(self.data_class, str):
66
+ self.factory = type(self.data_class, (Data,), {})
67
+ else:
68
+ self.factory = self.data_class
69
+
70
+ def _clear(self):
71
+ self._is_loaded = False
72
+ self.objects = []
73
+ self.index_names = set()
74
+ self.indices = {}
75
+
76
+ def _load(self) -> None:
77
+ if self._is_loaded:
78
+ # Help keeping the _load_if_needed code easier
79
+ # to read.
80
+ return
81
+ self._clear()
82
+
83
+ with open(self.filename, encoding="utf-8") as f:
84
+ tree = json.load(f)
85
+
86
+ for entry in tree[self.root_key]:
87
+ obj = self.factory(**entry)
88
+ self.objects.append(obj)
89
+ # Inject into index.
90
+ for key, value in entry.items():
91
+ if key in self.no_index:
92
+ continue
93
+ # Lookups and searches are case insensitive. Normalize
94
+ # here.
95
+ index = self.indices.setdefault(key, {})
96
+ value = value.lower()
97
+ if value in index:
98
+ logger.debug(
99
+ "%s %r already taken in index %r and will be "
100
+ "ignored. This is an error in the databases."
101
+ % (self.factory.__name__, value, key)
102
+ )
103
+ index[value] = obj
104
+
105
+ self._is_loaded = True
106
+
107
+ # Public API
108
+
109
+ @lazy_load
110
+ def add_entry(self, **kw):
111
+ # create the object with the correct dynamic type
112
+ obj = self.factory(**kw)
113
+
114
+ # append object
115
+ self.objects.append(obj)
116
+
117
+ # update indices
118
+ for key, value in kw.items():
119
+ if key in self.no_index:
120
+ continue
121
+ value = value.lower()
122
+ index = self.indices.setdefault(key, {})
123
+ index[value] = obj
124
+
125
+ @lazy_load
126
+ def remove_entry(self, **kw):
127
+ # make sure that we receive None if no entry found
128
+ if "default" in kw:
129
+ del kw["default"]
130
+ obj = self.get(**kw)
131
+ if not obj:
132
+ raise KeyError(
133
+ f"{self.factory.__name__} not found and cannot be removed: {kw}"
134
+ )
135
+
136
+ # remove object
137
+ self.objects.remove(obj)
138
+
139
+ # update indices
140
+ for key, value in obj:
141
+ if key in self.no_index:
142
+ continue
143
+ value = value.lower()
144
+ index = self.indices.setdefault(key, {})
145
+ if value in index:
146
+ del index[value]
147
+
148
+ @lazy_load
149
+ def __iter__(self) -> Iterator["Database"]:
150
+ return iter(self.objects)
151
+
152
+ @lazy_load
153
+ def __len__(self) -> int:
154
+ return len(self.objects)
155
+
156
+ @lazy_load
157
+ def get(
158
+ self, *, default: Optional[Any] = None, **kw: Optional[str]
159
+ ) -> Optional[Any]:
160
+ if len(kw) != 1:
161
+ raise TypeError("Only one criteria may be given")
162
+ field, value = kw.popitem()
163
+ if not isinstance(value, str):
164
+ raise LookupError()
165
+ # Normalize for case-insensitivity
166
+ value = value.lower()
167
+ index = self.indices[field]
168
+ try:
169
+ return index[value]
170
+ except KeyError:
171
+ # Pythonic APIs implementing get() shouldn't raise KeyErrors.
172
+ # Those are a bit unexpected and they should rather support
173
+ # returning `None` by default and allow customization.
174
+ return default
175
+
176
+ @lazy_load
177
+ def lookup(self, value: str) -> Type:
178
+ if not isinstance(value, str):
179
+ raise LookupError()
180
+
181
+ # Normalize for case-insensitivity
182
+ value = value.lower()
183
+
184
+ # Use indexes first
185
+ for key in self.indices:
186
+ try:
187
+ return self.indices[key][value]
188
+ except LookupError:
189
+ pass
190
+
191
+ # Use non-indexed values now. Avoid going through indexed values.
192
+ for candidate in self:
193
+ for k in self.no_index:
194
+ v = candidate._fields.get(k)
195
+ if v is None:
196
+ continue
197
+ if v.lower() == value:
198
+ return candidate
199
+
200
+ raise LookupError("Could not find a record for %r" % value)
.venv/lib/python3.11/site-packages/pycountry/locales/an/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (3.81 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ay/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (521 Bytes). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/bar/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (6.86 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/bi/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (526 Bytes). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/byn/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (5.71 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/byn/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (474 Bytes). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/byn/LC_MESSAGES/iso639-3.mo ADDED
Binary file (5.69 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ch/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (1.42 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ckb/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (10.4 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/csb/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (4.45 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso15924.mo ADDED
Binary file (1.86 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (30.8 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso3166-2.mo ADDED
Binary file (9.26 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (3.43 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso4217.mo ADDED
Binary file (9.43 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso639-3.mo ADDED
Binary file (57.4 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/el/LC_MESSAGES/iso639-5.mo ADDED
Binary file (2.39 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/gez/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (5.76 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/gez/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (476 Bytes). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/gez/LC_MESSAGES/iso639-3.mo ADDED
Binary file (5.7 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/haw/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (1.31 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/haw/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (395 Bytes). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/jam/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (8.32 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/nah/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (8.12 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso15924.mo ADDED
Binary file (3.46 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (22 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (2.6 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso4217.mo ADDED
Binary file (7.57 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/nn/LC_MESSAGES/iso639-3.mo ADDED
Binary file (7.46 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/or/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (34.1 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/or/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (3.98 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/pa_PK/LC_MESSAGES/iso15924.mo ADDED
Binary file (1.42 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/pa_PK/LC_MESSAGES/iso3166-2.mo ADDED
Binary file (1.02 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/pa_PK/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (601 Bytes). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/pi/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (9.26 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso15924.mo ADDED
Binary file (12.7 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso3166-1.mo ADDED
Binary file (29.8 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso3166-3.mo ADDED
Binary file (3.48 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso4217.mo ADDED
Binary file (11.5 kB). View file
 
.venv/lib/python3.11/site-packages/pycountry/locales/ru/LC_MESSAGES/iso639-3.mo ADDED
Binary file (18.4 kB). View file