0-hero commited on
Commit
a1271b8
·
verified ·
1 Parent(s): d655b38

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. .cache/pip/http-v2/c/1/8/1/b/c181b620c2b2b493dad2f552b5d974d23e75efd41c009d6df2cc1357.body +0 -0
  2. .cache/pip/http-v2/c/2/0/9/b/c209b6730b4a3a67d7d68f436a023e57f848dcba7c8db3fd04a54862 +0 -0
  3. .cache/pip/http-v2/c/2/0/9/b/c209b6730b4a3a67d7d68f436a023e57f848dcba7c8db3fd04a54862.body +1060 -0
  4. .cache/pip/http-v2/c/4/2/0/3/c4203c5060d0f778eafd521050eab23e6aaa0f9eefa17eb1e671212c +0 -0
  5. .cache/pip/http-v2/c/4/2/0/3/c4203c5060d0f778eafd521050eab23e6aaa0f9eefa17eb1e671212c.body +0 -0
  6. .cache/pip/http-v2/c/5/4/0/3/c5403a101bbaf526810b4c472004bc3b03b96b7c8118e06c7a081e63.body +0 -0
  7. .cache/pip/http-v2/c/d/5/d/e/cd5de44b899cbe1869765c21b55cffc53c0c0ffa9d3c6f1fd40a42a2.body +0 -0
  8. .cache/pip/http-v2/f/0/4/f/6/f04f619fe804fd38ac24d3bad7c02b3e6461727bd3a1ce45e316d44a +0 -0
  9. .cache/pip/http-v2/f/0/4/f/6/f04f619fe804fd38ac24d3bad7c02b3e6461727bd3a1ce45e316d44a.body +0 -0
  10. .cache/pip/http-v2/f/4/3/c/e/f43ce2cb74a8c7ad77da70314e043a539a7f01416550c3167312132b +0 -0
  11. .cache/pip/http-v2/f/4/3/c/e/f43ce2cb74a8c7ad77da70314e043a539a7f01416550c3167312132b.body +131 -0
  12. .cache/pip/http-v2/f/4/4/1/e/f441e9f50c61e41b200d99c506edae810953f5810bcb8a4e8bae463c.body +0 -0
  13. .cache/pip/http-v2/f/6/8/9/5/f689581dbe86ea3c1a14226c252116f97e87dde2c835d7d60fd42b59 +0 -0
  14. .cache/pip/http-v2/f/6/8/9/5/f689581dbe86ea3c1a14226c252116f97e87dde2c835d7d60fd42b59.body +280 -0
  15. .cache/pip/http-v2/f/a/0/e/b/fa0eb94064e725636a09e766c68812661f1423e7568ddc8b81c74949.body +1591 -0
  16. .cache/pip/http-v2/f/c/a/5/b/fca5b18fd877930924e4c3ed44a7de4862861d131c1248697b107213 +0 -0
  17. .cache/pip/http-v2/f/c/a/5/b/fca5b18fd877930924e4c3ed44a7de4862861d131c1248697b107213.body +420 -0
  18. .cache/wandb/logs/core-debug-20240926_055222.log +14 -0
  19. .cache/wandb/logs/core-debug-20240926_192831.log +12 -0
  20. .jupyter/jupyter_nbconvert_config.json +13 -0
  21. .jupyter/jupyter_notebook_config.json +7 -0
  22. .jupyter/lab/workspaces/default-37a8.jupyterlab-workspace +1 -0
  23. .jupyter/migrated +1 -0
  24. .jupyter/nbconfig/notebook.json +7 -0
  25. .jupyter/nbconfig/tree.json +6 -0
  26. .local/share/jupyter/nbextensions/addbefore/addbefore.yaml +7 -0
  27. .local/share/jupyter/nbextensions/addbefore/main.js +42 -0
  28. .local/share/jupyter/nbextensions/autosavetime/README.md +20 -0
  29. .local/share/jupyter/nbextensions/autosavetime/autosavetime.yaml +22 -0
  30. .local/share/jupyter/nbextensions/autosavetime/icon.png +0 -0
  31. .local/share/jupyter/nbextensions/autoscroll/autoscroll.yaml +26 -0
  32. .local/share/jupyter/nbextensions/autoscroll/main.js +130 -0
  33. .local/share/jupyter/nbextensions/cell_filter/cell_filter.js +133 -0
  34. .local/share/jupyter/nbextensions/code_font_size/README.md +4 -0
  35. .local/share/jupyter/nbextensions/code_font_size/code_font_size.js +70 -0
  36. .local/share/jupyter/nbextensions/code_font_size/code_font_size.yaml +7 -0
  37. .local/share/jupyter/nbextensions/code_prettify/2to3.yaml +65 -0
  38. .local/share/jupyter/nbextensions/code_prettify/README.md +302 -0
  39. .local/share/jupyter/nbextensions/code_prettify/README_autopep8.md +136 -0
  40. .local/share/jupyter/nbextensions/code_prettify/README_isort.md +44 -0
  41. .local/share/jupyter/nbextensions/code_prettify/autopep8.js +36 -0
  42. .local/share/jupyter/nbextensions/code_prettify/autopep8.yaml +67 -0
  43. .local/share/jupyter/nbextensions/code_prettify/code_prettify.js +56 -0
  44. .local/share/jupyter/nbextensions/code_prettify/code_prettify.yaml +77 -0
  45. .local/share/jupyter/nbextensions/code_prettify/demo-R.gif +0 -0
  46. .local/share/jupyter/nbextensions/code_prettify/demo-jv.gif +0 -0
  47. .local/share/jupyter/nbextensions/code_prettify/demo_2to3.gif +0 -0
  48. .local/share/jupyter/nbextensions/code_prettify/isort.js +43 -0
  49. .local/share/jupyter/nbextensions/code_prettify/isort.yaml +40 -0
  50. .local/share/jupyter/nbextensions/code_prettify/kernel_exec_on_cell.js +356 -0
.cache/pip/http-v2/c/1/8/1/b/c181b620c2b2b493dad2f552b5d974d23e75efd41c009d6df2cc1357.body ADDED
Binary file (347 kB). View file
 
.cache/pip/http-v2/c/2/0/9/b/c209b6730b4a3a67d7d68f436a023e57f848dcba7c8db3fd04a54862 ADDED
Binary file (1.2 kB). View file
 
.cache/pip/http-v2/c/2/0/9/b/c209b6730b4a3a67d7d68f436a023e57f848dcba7c8db3fd04a54862.body ADDED
@@ -0,0 +1,1060 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: regex
3
+ Version: 2024.9.11
4
+ Summary: Alternative regular expression module, to replace re.
5
+ Home-page: https://github.com/mrabarnett/mrab-regex
6
+ Author: Matthew Barnett
7
+ Author-email: [email protected]
8
+ License: Apache Software License
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Text Processing
22
+ Classifier: Topic :: Text Processing :: General
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/x-rst
25
+ License-File: LICENSE.txt
26
+
27
+ Introduction
28
+ ------------
29
+
30
+ This regex implementation is backwards-compatible with the standard 're' module, but offers additional functionality.
31
+
32
+ Python 2
33
+ --------
34
+
35
+ Python 2 is no longer supported. The last release that supported Python 2 was 2021.11.10.
36
+
37
+ PyPy
38
+ ----
39
+
40
+ This module is targeted at CPython. It expects that all codepoints are the same width, so it won't behave properly with PyPy outside U+0000..U+007F because PyPy stores strings as UTF-8.
41
+
42
+ Multithreading
43
+ --------------
44
+
45
+ The regex module releases the GIL during matching on instances of the built-in (immutable) string classes, enabling other Python threads to run concurrently. It is also possible to force the regex module to release the GIL during matching by calling the matching methods with the keyword argument ``concurrent=True``. The behaviour is undefined if the string changes during matching, so use it *only* when it is guaranteed that that won't happen.
46
+
47
+ Unicode
48
+ -------
49
+
50
+ This module supports Unicode 16.0.0. Full Unicode case-folding is supported.
51
+
52
+ Flags
53
+ -----
54
+
55
+ There are 2 kinds of flag: scoped and global. Scoped flags can apply to only part of a pattern and can be turned on or off; global flags apply to the entire pattern and can only be turned on.
56
+
57
+ The scoped flags are: ``ASCII (?a)``, ``FULLCASE (?f)``, ``IGNORECASE (?i)``, ``LOCALE (?L)``, ``MULTILINE (?m)``, ``DOTALL (?s)``, ``UNICODE (?u)``, ``VERBOSE (?x)``, ``WORD (?w)``.
58
+
59
+ The global flags are: ``BESTMATCH (?b)``, ``ENHANCEMATCH (?e)``, ``POSIX (?p)``, ``REVERSE (?r)``, ``VERSION0 (?V0)``, ``VERSION1 (?V1)``.
60
+
61
+ If neither the ``ASCII``, ``LOCALE`` nor ``UNICODE`` flag is specified, it will default to ``UNICODE`` if the regex pattern is a Unicode string and ``ASCII`` if it's a bytestring.
62
+
63
+ The ``ENHANCEMATCH`` flag makes fuzzy matching attempt to improve the fit of the next match that it finds.
64
+
65
+ The ``BESTMATCH`` flag makes fuzzy matching search for the best match instead of the next match.
66
+
67
+ Old vs new behaviour
68
+ --------------------
69
+
70
+ In order to be compatible with the re module, this module has 2 behaviours:
71
+
72
+ * **Version 0** behaviour (old behaviour, compatible with the re module):
73
+
74
+ Please note that the re module's behaviour may change over time, and I'll endeavour to match that behaviour in version 0.
75
+
76
+ * Indicated by the ``VERSION0`` flag.
77
+
78
+ * Zero-width matches are not handled correctly in the re module before Python 3.7. The behaviour in those earlier versions is:
79
+
80
+ * ``.split`` won't split a string at a zero-width match.
81
+
82
+ * ``.sub`` will advance by one character after a zero-width match.
83
+
84
+ * Inline flags apply to the entire pattern, and they can't be turned off.
85
+
86
+ * Only simple sets are supported.
87
+
88
+ * Case-insensitive matches in Unicode use simple case-folding by default.
89
+
90
+ * **Version 1** behaviour (new behaviour, possibly different from the re module):
91
+
92
+ * Indicated by the ``VERSION1`` flag.
93
+
94
+ * Zero-width matches are handled correctly.
95
+
96
+ * Inline flags apply to the end of the group or pattern, and they can be turned off.
97
+
98
+ * Nested sets and set operations are supported.
99
+
100
+ * Case-insensitive matches in Unicode use full case-folding by default.
101
+
102
+ If no version is specified, the regex module will default to ``regex.DEFAULT_VERSION``.
103
+
104
+ Case-insensitive matches in Unicode
105
+ -----------------------------------
106
+
107
+ The regex module supports both simple and full case-folding for case-insensitive matches in Unicode. Use of full case-folding can be turned on using the ``FULLCASE`` flag. Please note that this flag affects how the ``IGNORECASE`` flag works; the ``FULLCASE`` flag itself does not turn on case-insensitive matching.
108
+
109
+ Version 0 behaviour: the flag is off by default.
110
+
111
+ Version 1 behaviour: the flag is on by default.
112
+
113
+ Nested sets and set operations
114
+ ------------------------------
115
+
116
+ It's not possible to support both simple sets, as used in the re module, and nested sets at the same time because of a difference in the meaning of an unescaped ``"["`` in a set.
117
+
118
+ For example, the pattern ``[[a-z]--[aeiou]]`` is treated in the version 0 behaviour (simple sets, compatible with the re module) as:
119
+
120
+ * Set containing "[" and the letters "a" to "z"
121
+
122
+ * Literal "--"
123
+
124
+ * Set containing letters "a", "e", "i", "o", "u"
125
+
126
+ * Literal "]"
127
+
128
+ but in the version 1 behaviour (nested sets, enhanced behaviour) as:
129
+
130
+ * Set which is:
131
+
132
+ * Set containing the letters "a" to "z"
133
+
134
+ * but excluding:
135
+
136
+ * Set containing the letters "a", "e", "i", "o", "u"
137
+
138
+ Version 0 behaviour: only simple sets are supported.
139
+
140
+ Version 1 behaviour: nested sets and set operations are supported.
141
+
142
+ Notes on named groups
143
+ ---------------------
144
+
145
+ All groups have a group number, starting from 1.
146
+
147
+ Groups with the same group name will have the same group number, and groups with a different group name will have a different group number.
148
+
149
+ The same name can be used by more than one group, with later captures 'overwriting' earlier captures. All the captures of the group will be available from the ``captures`` method of the match object.
150
+
151
+ Group numbers will be reused across different branches of a branch reset, eg. ``(?|(first)|(second))`` has only group 1. If groups have different group names then they will, of course, have different group numbers, eg. ``(?|(?P<foo>first)|(?P<bar>second))`` has group 1 ("foo") and group 2 ("bar").
152
+
153
+ In the regex ``(\s+)(?|(?P<foo>[A-Z]+)|(\w+) (?P<foo>[0-9]+)`` there are 2 groups:
154
+
155
+ * ``(\s+)`` is group 1.
156
+
157
+ * ``(?P<foo>[A-Z]+)`` is group 2, also called "foo".
158
+
159
+ * ``(\w+)`` is group 2 because of the branch reset.
160
+
161
+ * ``(?P<foo>[0-9]+)`` is group 2 because it's called "foo".
162
+
163
+ If you want to prevent ``(\w+)`` from being group 2, you need to name it (different name, different group number).
164
+
165
+ Additional features
166
+ -------------------
167
+
168
+ The issue numbers relate to the Python bug tracker, except where listed otherwise.
169
+
170
+ Added ``\p{Horiz_Space}`` and ``\p{Vert_Space}`` (`GitHub issue 477 <https://github.com/mrabarnett/mrab-regex/issues/477#issuecomment-1216779547>`_)
171
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
172
+
173
+ ``\p{Horiz_Space}`` or ``\p{H}`` matches horizontal whitespace and ``\p{Vert_Space}`` or ``\p{V}`` matches vertical whitespace.
174
+
175
+ Added support for lookaround in conditional pattern (`Hg issue 163 <https://github.com/mrabarnett/mrab-regex/issues/163>`_)
176
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
177
+
178
+ The test of a conditional pattern can be a lookaround.
179
+
180
+ .. sourcecode:: python
181
+
182
+ >>> regex.match(r'(?(?=\d)\d+|\w+)', '123abc')
183
+ <regex.Match object; span=(0, 3), match='123'>
184
+ >>> regex.match(r'(?(?=\d)\d+|\w+)', 'abc123')
185
+ <regex.Match object; span=(0, 6), match='abc123'>
186
+
187
+ This is not quite the same as putting a lookaround in the first branch of a pair of alternatives.
188
+
189
+ .. sourcecode:: python
190
+
191
+ >>> print(regex.match(r'(?:(?=\d)\d+\b|\w+)', '123abc'))
192
+ <regex.Match object; span=(0, 6), match='123abc'>
193
+ >>> print(regex.match(r'(?(?=\d)\d+\b|\w+)', '123abc'))
194
+ None
195
+
196
+ In the first example, the lookaround matched, but the remainder of the first branch failed to match, and so the second branch was attempted, whereas in the second example, the lookaround matched, and the first branch failed to match, but the second branch was **not** attempted.
197
+
198
+ Added POSIX matching (leftmost longest) (`Hg issue 150 <https://github.com/mrabarnett/mrab-regex/issues/150>`_)
199
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
200
+
201
+ The POSIX standard for regex is to return the leftmost longest match. This can be turned on using the ``POSIX`` flag.
202
+
203
+ .. sourcecode:: python
204
+
205
+ >>> # Normal matching.
206
+ >>> regex.search(r'Mr|Mrs', 'Mrs')
207
+ <regex.Match object; span=(0, 2), match='Mr'>
208
+ >>> regex.search(r'one(self)?(selfsufficient)?', 'oneselfsufficient')
209
+ <regex.Match object; span=(0, 7), match='oneself'>
210
+ >>> # POSIX matching.
211
+ >>> regex.search(r'(?p)Mr|Mrs', 'Mrs')
212
+ <regex.Match object; span=(0, 3), match='Mrs'>
213
+ >>> regex.search(r'(?p)one(self)?(selfsufficient)?', 'oneselfsufficient')
214
+ <regex.Match object; span=(0, 17), match='oneselfsufficient'>
215
+
216
+ Note that it will take longer to find matches because when it finds a match at a certain position, it won't return that immediately, but will keep looking to see if there's another longer match there.
217
+
218
+ Added ``(?(DEFINE)...)`` (`Hg issue 152 <https://github.com/mrabarnett/mrab-regex/issues/152>`_)
219
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
220
+
221
+ If there's no group called "DEFINE", then ... will be ignored except that any groups defined within it can be called and that the normal rules for numbering groups still apply.
222
+
223
+ .. sourcecode:: python
224
+
225
+ >>> regex.search(r'(?(DEFINE)(?P<quant>\d+)(?P<item>\w+))(?&quant) (?&item)', '5 elephants')
226
+ <regex.Match object; span=(0, 11), match='5 elephants'>
227
+
228
+ Added ``(*PRUNE)``, ``(*SKIP)`` and ``(*FAIL)`` (`Hg issue 153 <https://github.com/mrabarnett/mrab-regex/issues/153>`_)
229
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
230
+
231
+ ``(*PRUNE)`` discards the backtracking info up to that point. When used in an atomic group or a lookaround, it won't affect the enclosing pattern.
232
+
233
+ ``(*SKIP)`` is similar to ``(*PRUNE)``, except that it also sets where in the text the next attempt to match will start. When used in an atomic group or a lookaround, it won't affect the enclosing pattern.
234
+
235
+ ``(*FAIL)`` causes immediate backtracking. ``(*F)`` is a permitted abbreviation.
236
+
237
+ Added ``\K`` (`Hg issue 151 <https://github.com/mrabarnett/mrab-regex/issues/151>`_)
238
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
239
+
240
+ Keeps the part of the entire match after the position where ``\K`` occurred; the part before it is discarded.
241
+
242
+ It does not affect what groups return.
243
+
244
+ .. sourcecode:: python
245
+
246
+ >>> m = regex.search(r'(\w\w\K\w\w\w)', 'abcdef')
247
+ >>> m[0]
248
+ 'cde'
249
+ >>> m[1]
250
+ 'abcde'
251
+ >>>
252
+ >>> m = regex.search(r'(?r)(\w\w\K\w\w\w)', 'abcdef')
253
+ >>> m[0]
254
+ 'bc'
255
+ >>> m[1]
256
+ 'bcdef'
257
+
258
+ Added capture subscripting for ``expandf`` and ``subf``/``subfn`` (`Hg issue 133 <https://github.com/mrabarnett/mrab-regex/issues/133>`_)
259
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
260
+
261
+ You can use subscripting to get the captures of a repeated group.
262
+
263
+ .. sourcecode:: python
264
+
265
+ >>> m = regex.match(r"(\w)+", "abc")
266
+ >>> m.expandf("{1}")
267
+ 'c'
268
+ >>> m.expandf("{1[0]} {1[1]} {1[2]}")
269
+ 'a b c'
270
+ >>> m.expandf("{1[-1]} {1[-2]} {1[-3]}")
271
+ 'c b a'
272
+ >>>
273
+ >>> m = regex.match(r"(?P<letter>\w)+", "abc")
274
+ >>> m.expandf("{letter}")
275
+ 'c'
276
+ >>> m.expandf("{letter[0]} {letter[1]} {letter[2]}")
277
+ 'a b c'
278
+ >>> m.expandf("{letter[-1]} {letter[-2]} {letter[-3]}")
279
+ 'c b a'
280
+
281
+ Added support for referring to a group by number using ``(?P=...)``
282
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283
+
284
+ This is in addition to the existing ``\g<...>``.
285
+
286
+ Fixed the handling of locale-sensitive regexes
287
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
288
+
289
+ The ``LOCALE`` flag is intended for legacy code and has limited support. You're still recommended to use Unicode instead.
290
+
291
+ Added partial matches (`Hg issue 102 <https://github.com/mrabarnett/mrab-regex/issues/102>`_)
292
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
293
+
294
+ A partial match is one that matches up to the end of string, but that string has been truncated and you want to know whether a complete match could be possible if the string had not been truncated.
295
+
296
+ Partial matches are supported by ``match``, ``search``, ``fullmatch`` and ``finditer`` with the ``partial`` keyword argument.
297
+
298
+ Match objects have a ``partial`` attribute, which is ``True`` if it's a partial match.
299
+
300
+ For example, if you wanted a user to enter a 4-digit number and check it character by character as it was being entered:
301
+
302
+ .. sourcecode:: python
303
+
304
+ >>> pattern = regex.compile(r'\d{4}')
305
+
306
+ >>> # Initially, nothing has been entered:
307
+ >>> print(pattern.fullmatch('', partial=True))
308
+ <regex.Match object; span=(0, 0), match='', partial=True>
309
+
310
+ >>> # An empty string is OK, but it's only a partial match.
311
+ >>> # The user enters a letter:
312
+ >>> print(pattern.fullmatch('a', partial=True))
313
+ None
314
+ >>> # It'll never match.
315
+
316
+ >>> # The user deletes that and enters a digit:
317
+ >>> print(pattern.fullmatch('1', partial=True))
318
+ <regex.Match object; span=(0, 1), match='1', partial=True>
319
+ >>> # It matches this far, but it's only a partial match.
320
+
321
+ >>> # The user enters 2 more digits:
322
+ >>> print(pattern.fullmatch('123', partial=True))
323
+ <regex.Match object; span=(0, 3), match='123', partial=True>
324
+ >>> # It matches this far, but it's only a partial match.
325
+
326
+ >>> # The user enters another digit:
327
+ >>> print(pattern.fullmatch('1234', partial=True))
328
+ <regex.Match object; span=(0, 4), match='1234'>
329
+ >>> # It's a complete match.
330
+
331
+ >>> # If the user enters another digit:
332
+ >>> print(pattern.fullmatch('12345', partial=True))
333
+ None
334
+ >>> # It's no longer a match.
335
+
336
+ >>> # This is a partial match:
337
+ >>> pattern.match('123', partial=True).partial
338
+ True
339
+
340
+ >>> # This is a complete match:
341
+ >>> pattern.match('1233', partial=True).partial
342
+ False
343
+
344
+ ``*`` operator not working correctly with sub() (`Hg issue 106 <https://github.com/mrabarnett/mrab-regex/issues/106>`_)
345
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
346
+
347
+ Sometimes it's not clear how zero-width matches should be handled. For example, should ``.*`` match 0 characters directly after matching >0 characters?
348
+
349
+ .. sourcecode:: python
350
+
351
+ >>> regex.sub('.*', 'x', 'test')
352
+ 'xx'
353
+ >>> regex.sub('.*?', '|', 'test')
354
+ '|||||||||'
355
+
356
+ Added ``capturesdict`` (`Hg issue 86 <https://github.com/mrabarnett/mrab-regex/issues/86>`_)
357
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
358
+
359
+ ``capturesdict`` is a combination of ``groupdict`` and ``captures``:
360
+
361
+ ``groupdict`` returns a dict of the named groups and the last capture of those groups.
362
+
363
+ ``captures`` returns a list of all the captures of a group
364
+
365
+ ``capturesdict`` returns a dict of the named groups and lists of all the captures of those groups.
366
+
367
+ .. sourcecode:: python
368
+
369
+ >>> m = regex.match(r"(?:(?P<word>\w+) (?P<digits>\d+)\n)+", "one 1\ntwo 2\nthree 3\n")
370
+ >>> m.groupdict()
371
+ {'word': 'three', 'digits': '3'}
372
+ >>> m.captures("word")
373
+ ['one', 'two', 'three']
374
+ >>> m.captures("digits")
375
+ ['1', '2', '3']
376
+ >>> m.capturesdict()
377
+ {'word': ['one', 'two', 'three'], 'digits': ['1', '2', '3']}
378
+
379
+ Added ``allcaptures`` and ``allspans`` (`Git issue 474 <https://github.com/mrabarnett/mrab-regex/issues/474>`_)
380
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
381
+
382
+ ``allcaptures`` returns a list of all the captures of all the groups.
383
+
384
+ ``allspans`` returns a list of all the spans of the all captures of all the groups.
385
+
386
+ .. sourcecode:: python
387
+
388
+ >>> m = regex.match(r"(?:(?P<word>\w+) (?P<digits>\d+)\n)+", "one 1\ntwo 2\nthree 3\n")
389
+ >>> m.allcaptures()
390
+ (['one 1\ntwo 2\nthree 3\n'], ['one', 'two', 'three'], ['1', '2', '3'])
391
+ >>> m.allspans()
392
+ ([(0, 20)], [(0, 3), (6, 9), (12, 17)], [(4, 5), (10, 11), (18, 19)])
393
+
394
+ Allow duplicate names of groups (`Hg issue 87 <https://github.com/mrabarnett/mrab-regex/issues/87>`_)
395
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
396
+
397
+ Group names can be duplicated.
398
+
399
+ .. sourcecode:: python
400
+
401
+ >>> # With optional groups:
402
+ >>>
403
+ >>> # Both groups capture, the second capture 'overwriting' the first.
404
+ >>> m = regex.match(r"(?P<item>\w+)? or (?P<item>\w+)?", "first or second")
405
+ >>> m.group("item")
406
+ 'second'
407
+ >>> m.captures("item")
408
+ ['first', 'second']
409
+ >>> # Only the second group captures.
410
+ >>> m = regex.match(r"(?P<item>\w+)? or (?P<item>\w+)?", " or second")
411
+ >>> m.group("item")
412
+ 'second'
413
+ >>> m.captures("item")
414
+ ['second']
415
+ >>> # Only the first group captures.
416
+ >>> m = regex.match(r"(?P<item>\w+)? or (?P<item>\w+)?", "first or ")
417
+ >>> m.group("item")
418
+ 'first'
419
+ >>> m.captures("item")
420
+ ['first']
421
+ >>>
422
+ >>> # With mandatory groups:
423
+ >>>
424
+ >>> # Both groups capture, the second capture 'overwriting' the first.
425
+ >>> m = regex.match(r"(?P<item>\w*) or (?P<item>\w*)?", "first or second")
426
+ >>> m.group("item")
427
+ 'second'
428
+ >>> m.captures("item")
429
+ ['first', 'second']
430
+ >>> # Again, both groups capture, the second capture 'overwriting' the first.
431
+ >>> m = regex.match(r"(?P<item>\w*) or (?P<item>\w*)", " or second")
432
+ >>> m.group("item")
433
+ 'second'
434
+ >>> m.captures("item")
435
+ ['', 'second']
436
+ >>> # And yet again, both groups capture, the second capture 'overwriting' the first.
437
+ >>> m = regex.match(r"(?P<item>\w*) or (?P<item>\w*)", "first or ")
438
+ >>> m.group("item")
439
+ ''
440
+ >>> m.captures("item")
441
+ ['first', '']
442
+
443
+ Added ``fullmatch`` (`issue #16203 <https://bugs.python.org/issue16203>`_)
444
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
445
+
446
+ ``fullmatch`` behaves like ``match``, except that it must match all of the string.
447
+
448
+ .. sourcecode:: python
449
+
450
+ >>> print(regex.fullmatch(r"abc", "abc").span())
451
+ (0, 3)
452
+ >>> print(regex.fullmatch(r"abc", "abcx"))
453
+ None
454
+ >>> print(regex.fullmatch(r"abc", "abcx", endpos=3).span())
455
+ (0, 3)
456
+ >>> print(regex.fullmatch(r"abc", "xabcy", pos=1, endpos=4).span())
457
+ (1, 4)
458
+ >>>
459
+ >>> regex.match(r"a.*?", "abcd").group(0)
460
+ 'a'
461
+ >>> regex.fullmatch(r"a.*?", "abcd").group(0)
462
+ 'abcd'
463
+
464
+ Added ``subf`` and ``subfn``
465
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
466
+
467
+ ``subf`` and ``subfn`` are alternatives to ``sub`` and ``subn`` respectively. When passed a replacement string, they treat it as a format string.
468
+
469
+ .. sourcecode:: python
470
+
471
+ >>> regex.subf(r"(\w+) (\w+)", "{0} => {2} {1}", "foo bar")
472
+ 'foo bar => bar foo'
473
+ >>> regex.subf(r"(?P<word1>\w+) (?P<word2>\w+)", "{word2} {word1}", "foo bar")
474
+ 'bar foo'
475
+
476
+ Added ``expandf`` to match object
477
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
478
+
479
+ ``expandf`` is an alternative to ``expand``. When passed a replacement string, it treats it as a format string.
480
+
481
+ .. sourcecode:: python
482
+
483
+ >>> m = regex.match(r"(\w+) (\w+)", "foo bar")
484
+ >>> m.expandf("{0} => {2} {1}")
485
+ 'foo bar => bar foo'
486
+ >>>
487
+ >>> m = regex.match(r"(?P<word1>\w+) (?P<word2>\w+)", "foo bar")
488
+ >>> m.expandf("{word2} {word1}")
489
+ 'bar foo'
490
+
491
+ Detach searched string
492
+ ^^^^^^^^^^^^^^^^^^^^^^
493
+
494
+ A match object contains a reference to the string that was searched, via its ``string`` attribute. The ``detach_string`` method will 'detach' that string, making it available for garbage collection, which might save valuable memory if that string is very large.
495
+
496
+ .. sourcecode:: python
497
+
498
+ >>> m = regex.search(r"\w+", "Hello world")
499
+ >>> print(m.group())
500
+ Hello
501
+ >>> print(m.string)
502
+ Hello world
503
+ >>> m.detach_string()
504
+ >>> print(m.group())
505
+ Hello
506
+ >>> print(m.string)
507
+ None
508
+
509
+ Recursive patterns (`Hg issue 27 <https://github.com/mrabarnett/mrab-regex/issues/27>`_)
510
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
511
+
512
+ Recursive and repeated patterns are supported.
513
+
514
+ ``(?R)`` or ``(?0)`` tries to match the entire regex recursively. ``(?1)``, ``(?2)``, etc, try to match the relevant group.
515
+
516
+ ``(?&name)`` tries to match the named group.
517
+
518
+ .. sourcecode:: python
519
+
520
+ >>> regex.match(r"(Tarzan|Jane) loves (?1)", "Tarzan loves Jane").groups()
521
+ ('Tarzan',)
522
+ >>> regex.match(r"(Tarzan|Jane) loves (?1)", "Jane loves Tarzan").groups()
523
+ ('Jane',)
524
+
525
+ >>> m = regex.search(r"(\w)(?:(?R)|(\w?))\1", "kayak")
526
+ >>> m.group(0, 1, 2)
527
+ ('kayak', 'k', None)
528
+
529
+ The first two examples show how the subpattern within the group is reused, but is _not_ itself a group. In other words, ``"(Tarzan|Jane) loves (?1)"`` is equivalent to ``"(Tarzan|Jane) loves (?:Tarzan|Jane)"``.
530
+
531
+ It's possible to backtrack into a recursed or repeated group.
532
+
533
+ You can't call a group if there is more than one group with that group name or group number (``"ambiguous group reference"``).
534
+
535
+ The alternative forms ``(?P>name)`` and ``(?P&name)`` are also supported.
536
+
537
+ Full Unicode case-folding is supported
538
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
539
+
540
+ In version 1 behaviour, the regex module uses full case-folding when performing case-insensitive matches in Unicode.
541
+
542
+ .. sourcecode:: python
543
+
544
+ >>> regex.match(r"(?iV1)strasse", "stra\N{LATIN SMALL LETTER SHARP S}e").span()
545
+ (0, 6)
546
+ >>> regex.match(r"(?iV1)stra\N{LATIN SMALL LETTER SHARP S}e", "STRASSE").span()
547
+ (0, 7)
548
+
549
+ In version 0 behaviour, it uses simple case-folding for backward compatibility with the re module.
550
+
551
+ Approximate "fuzzy" matching (`Hg issue 12 <https://github.com/mrabarnett/mrab-regex/issues/12>`_, `Hg issue 41 <https://github.com/mrabarnett/mrab-regex/issues/41>`_, `Hg issue 109 <https://github.com/mrabarnett/mrab-regex/issues/109>`_)
552
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
553
+
554
+ Regex usually attempts an exact match, but sometimes an approximate, or "fuzzy", match is needed, for those cases where the text being searched may contain errors in the form of inserted, deleted or substituted characters.
555
+
556
+ A fuzzy regex specifies which types of errors are permitted, and, optionally, either the minimum and maximum or only the maximum permitted number of each type. (You cannot specify only a minimum.)
557
+
558
+ The 3 types of error are:
559
+
560
+ * Insertion, indicated by "i"
561
+
562
+ * Deletion, indicated by "d"
563
+
564
+ * Substitution, indicated by "s"
565
+
566
+ In addition, "e" indicates any type of error.
567
+
568
+ The fuzziness of a regex item is specified between "{" and "}" after the item.
569
+
570
+ Examples:
571
+
572
+ * ``foo`` match "foo" exactly
573
+
574
+ * ``(?:foo){i}`` match "foo", permitting insertions
575
+
576
+ * ``(?:foo){d}`` match "foo", permitting deletions
577
+
578
+ * ``(?:foo){s}`` match "foo", permitting substitutions
579
+
580
+ * ``(?:foo){i,s}`` match "foo", permitting insertions and substitutions
581
+
582
+ * ``(?:foo){e}`` match "foo", permitting errors
583
+
584
+ If a certain type of error is specified, then any type not specified will **not** be permitted.
585
+
586
+ In the following examples I'll omit the item and write only the fuzziness:
587
+
588
+ * ``{d<=3}`` permit at most 3 deletions, but no other types
589
+
590
+ * ``{i<=1,s<=2}`` permit at most 1 insertion and at most 2 substitutions, but no deletions
591
+
592
+ * ``{1<=e<=3}`` permit at least 1 and at most 3 errors
593
+
594
+ * ``{i<=2,d<=2,e<=3}`` permit at most 2 insertions, at most 2 deletions, at most 3 errors in total, but no substitutions
595
+
596
+ It's also possible to state the costs of each type of error and the maximum permitted total cost.
597
+
598
+ Examples:
599
+
600
+ * ``{2i+2d+1s<=4}`` each insertion costs 2, each deletion costs 2, each substitution costs 1, the total cost must not exceed 4
601
+
602
+ * ``{i<=1,d<=1,s<=1,2i+2d+1s<=4}`` at most 1 insertion, at most 1 deletion, at most 1 substitution; each insertion costs 2, each deletion costs 2, each substitution costs 1, the total cost must not exceed 4
603
+
604
+ You can also use "<" instead of "<=" if you want an exclusive minimum or maximum.
605
+
606
+ You can add a test to perform on a character that's substituted or inserted.
607
+
608
+ Examples:
609
+
610
+ * ``{s<=2:[a-z]}`` at most 2 substitutions, which must be in the character set ``[a-z]``.
611
+
612
+ * ``{s<=2,i<=3:\d}`` at most 2 substitutions, at most 3 insertions, which must be digits.
613
+
614
+ By default, fuzzy matching searches for the first match that meets the given constraints. The ``ENHANCEMATCH`` flag will cause it to attempt to improve the fit (i.e. reduce the number of errors) of the match that it has found.
615
+
616
+ The ``BESTMATCH`` flag will make it search for the best match instead.
617
+
618
+ Further examples to note:
619
+
620
+ * ``regex.search("(dog){e}", "cat and dog")[1]`` returns ``"cat"`` because that matches ``"dog"`` with 3 errors (an unlimited number of errors is permitted).
621
+
622
+ * ``regex.search("(dog){e<=1}", "cat and dog")[1]`` returns ``" dog"`` (with a leading space) because that matches ``"dog"`` with 1 error, which is within the limit.
623
+
624
+ * ``regex.search("(?e)(dog){e<=1}", "cat and dog")[1]`` returns ``"dog"`` (without a leading space) because the fuzzy search matches ``" dog"`` with 1 error, which is within the limit, and the ``(?e)`` then it attempts a better fit.
625
+
626
+ In the first two examples there are perfect matches later in the string, but in neither case is it the first possible match.
627
+
628
+ The match object has an attribute ``fuzzy_counts`` which gives the total number of substitutions, insertions and deletions.
629
+
630
+ .. sourcecode:: python
631
+
632
+ >>> # A 'raw' fuzzy match:
633
+ >>> regex.fullmatch(r"(?:cats|cat){e<=1}", "cat").fuzzy_counts
634
+ (0, 0, 1)
635
+ >>> # 0 substitutions, 0 insertions, 1 deletion.
636
+
637
+ >>> # A better match might be possible if the ENHANCEMATCH flag used:
638
+ >>> regex.fullmatch(r"(?e)(?:cats|cat){e<=1}", "cat").fuzzy_counts
639
+ (0, 0, 0)
640
+ >>> # 0 substitutions, 0 insertions, 0 deletions.
641
+
642
+ The match object also has an attribute ``fuzzy_changes`` which gives a tuple of the positions of the substitutions, insertions and deletions.
643
+
644
+ .. sourcecode:: python
645
+
646
+ >>> m = regex.search('(fuu){i<=2,d<=2,e<=5}', 'anaconda foo bar')
647
+ >>> m
648
+ <regex.Match object; span=(7, 10), match='a f', fuzzy_counts=(0, 2, 2)>
649
+ >>> m.fuzzy_changes
650
+ ([], [7, 8], [10, 11])
651
+
652
+ What this means is that if the matched part of the string had been:
653
+
654
+ .. sourcecode:: python
655
+
656
+ 'anacondfuuoo bar'
657
+
658
+ it would've been an exact match.
659
+
660
+ However, there were insertions at positions 7 and 8:
661
+
662
+ .. sourcecode:: python
663
+
664
+ 'anaconda fuuoo bar'
665
+ ^^
666
+
667
+ and deletions at positions 10 and 11:
668
+
669
+ .. sourcecode:: python
670
+
671
+ 'anaconda f~~oo bar'
672
+ ^^
673
+
674
+ So the actual string was:
675
+
676
+ .. sourcecode:: python
677
+
678
+ 'anaconda foo bar'
679
+
680
+ Named lists ``\L<name>`` (`Hg issue 11 <https://github.com/mrabarnett/mrab-regex/issues/11>`_)
681
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
682
+
683
+ There are occasions where you may want to include a list (actually, a set) of options in a regex.
684
+
685
+ One way is to build the pattern like this:
686
+
687
+ .. sourcecode:: python
688
+
689
+ >>> p = regex.compile(r"first|second|third|fourth|fifth")
690
+
691
+ but if the list is large, parsing the resulting regex can take considerable time, and care must also be taken that the strings are properly escaped and properly ordered, for example, "cats" before "cat".
692
+
693
+ The new alternative is to use a named list:
694
+
695
+ .. sourcecode:: python
696
+
697
+ >>> option_set = ["first", "second", "third", "fourth", "fifth"]
698
+ >>> p = regex.compile(r"\L<options>", options=option_set)
699
+
700
+ The order of the items is irrelevant, they are treated as a set. The named lists are available as the ``.named_lists`` attribute of the pattern object :
701
+
702
+ .. sourcecode:: python
703
+
704
+ >>> print(p.named_lists)
705
+ {'options': frozenset({'third', 'first', 'fifth', 'fourth', 'second'})}
706
+
707
+ If there are any unused keyword arguments, ``ValueError`` will be raised unless you tell it otherwise:
708
+
709
+ .. sourcecode:: python
710
+
711
+ >>> option_set = ["first", "second", "third", "fourth", "fifth"]
712
+ >>> p = regex.compile(r"\L<options>", options=option_set, other_options=[])
713
+ Traceback (most recent call last):
714
+ File "<stdin>", line 1, in <module>
715
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 353, in compile
716
+ return _compile(pattern, flags, ignore_unused, kwargs, cache_pattern)
717
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 500, in _compile
718
+ complain_unused_args()
719
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 483, in complain_unused_args
720
+ raise ValueError('unused keyword argument {!a}'.format(any_one))
721
+ ValueError: unused keyword argument 'other_options'
722
+ >>> p = regex.compile(r"\L<options>", options=option_set, other_options=[], ignore_unused=True)
723
+ >>> p = regex.compile(r"\L<options>", options=option_set, other_options=[], ignore_unused=False)
724
+ Traceback (most recent call last):
725
+ File "<stdin>", line 1, in <module>
726
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 353, in compile
727
+ return _compile(pattern, flags, ignore_unused, kwargs, cache_pattern)
728
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 500, in _compile
729
+ complain_unused_args()
730
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 483, in complain_unused_args
731
+ raise ValueError('unused keyword argument {!a}'.format(any_one))
732
+ ValueError: unused keyword argument 'other_options'
733
+ >>>
734
+
735
+ Start and end of word
736
+ ^^^^^^^^^^^^^^^^^^^^^
737
+
738
+ ``\m`` matches at the start of a word.
739
+
740
+ ``\M`` matches at the end of a word.
741
+
742
+ Compare with ``\b``, which matches at the start or end of a word.
743
+
744
+ Unicode line separators
745
+ ^^^^^^^^^^^^^^^^^^^^^^^
746
+
747
+ Normally the only line separator is ``\n`` (``\x0A``), but if the ``WORD`` flag is turned on then the line separators are ``\x0D\x0A``, ``\x0A``, ``\x0B``, ``\x0C`` and ``\x0D``, plus ``\x85``, ``\u2028`` and ``\u2029`` when working with Unicode.
748
+
749
+ This affects the regex dot ``"."``, which, with the ``DOTALL`` flag turned off, matches any character except a line separator. It also affects the line anchors ``^`` and ``$`` (in multiline mode).
750
+
751
+ Set operators
752
+ ^^^^^^^^^^^^^
753
+
754
+ **Version 1 behaviour only**
755
+
756
+ Set operators have been added, and a set ``[...]`` can include nested sets.
757
+
758
+ The operators, in order of increasing precedence, are:
759
+
760
+ * ``||`` for union ("x||y" means "x or y")
761
+
762
+ * ``~~`` (double tilde) for symmetric difference ("x~~y" means "x or y, but not both")
763
+
764
+ * ``&&`` for intersection ("x&&y" means "x and y")
765
+
766
+ * ``--`` (double dash) for difference ("x--y" means "x but not y")
767
+
768
+ Implicit union, ie, simple juxtaposition like in ``[ab]``, has the highest precedence. Thus, ``[ab&&cd]`` is the same as ``[[a||b]&&[c||d]]``.
769
+
770
+ Examples:
771
+
772
+ * ``[ab]`` # Set containing 'a' and 'b'
773
+
774
+ * ``[a-z]`` # Set containing 'a' .. 'z'
775
+
776
+ * ``[[a-z]--[qw]]`` # Set containing 'a' .. 'z', but not 'q' or 'w'
777
+
778
+ * ``[a-z--qw]`` # Same as above
779
+
780
+ * ``[\p{L}--QW]`` # Set containing all letters except 'Q' and 'W'
781
+
782
+ * ``[\p{N}--[0-9]]`` # Set containing all numbers except '0' .. '9'
783
+
784
+ * ``[\p{ASCII}&&\p{Letter}]`` # Set containing all characters which are ASCII and letter
785
+
786
+ regex.escape (`issue #2650 <https://bugs.python.org/issue2650>`_)
787
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
788
+
789
+ regex.escape has an additional keyword parameter ``special_only``. When True, only 'special' regex characters, such as '?', are escaped.
790
+
791
+ .. sourcecode:: python
792
+
793
+ >>> regex.escape("foo!?", special_only=False)
794
+ 'foo\\!\\?'
795
+ >>> regex.escape("foo!?", special_only=True)
796
+ 'foo!\\?'
797
+
798
+ regex.escape (`Hg issue 249 <https://github.com/mrabarnett/mrab-regex/issues/249>`_)
799
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
800
+
801
+ regex.escape has an additional keyword parameter ``literal_spaces``. When True, spaces are not escaped.
802
+
803
+ .. sourcecode:: python
804
+
805
+ >>> regex.escape("foo bar!?", literal_spaces=False)
806
+ 'foo\\ bar!\\?'
807
+ >>> regex.escape("foo bar!?", literal_spaces=True)
808
+ 'foo bar!\\?'
809
+
810
+ Repeated captures (`issue #7132 <https://bugs.python.org/issue7132>`_)
811
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
812
+
813
+ A match object has additional methods which return information on all the successful matches of a repeated group. These methods are:
814
+
815
+ * ``matchobject.captures([group1, ...])``
816
+
817
+ * Returns a list of the strings matched in a group or groups. Compare with ``matchobject.group([group1, ...])``.
818
+
819
+ * ``matchobject.starts([group])``
820
+
821
+ * Returns a list of the start positions. Compare with ``matchobject.start([group])``.
822
+
823
+ * ``matchobject.ends([group])``
824
+
825
+ * Returns a list of the end positions. Compare with ``matchobject.end([group])``.
826
+
827
+ * ``matchobject.spans([group])``
828
+
829
+ * Returns a list of the spans. Compare with ``matchobject.span([group])``.
830
+
831
+ .. sourcecode:: python
832
+
833
+ >>> m = regex.search(r"(\w{3})+", "123456789")
834
+ >>> m.group(1)
835
+ '789'
836
+ >>> m.captures(1)
837
+ ['123', '456', '789']
838
+ >>> m.start(1)
839
+ 6
840
+ >>> m.starts(1)
841
+ [0, 3, 6]
842
+ >>> m.end(1)
843
+ 9
844
+ >>> m.ends(1)
845
+ [3, 6, 9]
846
+ >>> m.span(1)
847
+ (6, 9)
848
+ >>> m.spans(1)
849
+ [(0, 3), (3, 6), (6, 9)]
850
+
851
+ Atomic grouping ``(?>...)`` (`issue #433030 <https://bugs.python.org/issue433030>`_)
852
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
853
+
854
+ If the following pattern subsequently fails, then the subpattern as a whole will fail.
855
+
856
+ Possessive quantifiers
857
+ ^^^^^^^^^^^^^^^^^^^^^^
858
+
859
+ ``(?:...)?+`` ; ``(?:...)*+`` ; ``(?:...)++`` ; ``(?:...){min,max}+``
860
+
861
+ The subpattern is matched up to 'max' times. If the following pattern subsequently fails, then all the repeated subpatterns will fail as a whole. For example, ``(?:...)++`` is equivalent to ``(?>(?:...)+)``.
862
+
863
+ Scoped flags (`issue #433028 <https://bugs.python.org/issue433028>`_)
864
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
865
+
866
+ ``(?flags-flags:...)``
867
+
868
+ The flags will apply only to the subpattern. Flags can be turned on or off.
869
+
870
+ Definition of 'word' character (`issue #1693050 <https://bugs.python.org/issue1693050>`_)
871
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
872
+
873
+ The definition of a 'word' character has been expanded for Unicode. It conforms to the Unicode specification at ``http://www.unicode.org/reports/tr29/``.
874
+
875
+ Variable-length lookbehind
876
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
877
+
878
+ A lookbehind can match a variable-length string.
879
+
880
+ Flags argument for regex.split, regex.sub and regex.subn (`issue #3482 <https://bugs.python.org/issue3482>`_)
881
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
882
+
883
+ ``regex.split``, ``regex.sub`` and ``regex.subn`` support a 'flags' argument.
884
+
885
+ Pos and endpos arguments for regex.sub and regex.subn
886
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
887
+
888
+ ``regex.sub`` and ``regex.subn`` support 'pos' and 'endpos' arguments.
889
+
890
+ 'Overlapped' argument for regex.findall and regex.finditer
891
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
892
+
893
+ ``regex.findall`` and ``regex.finditer`` support an 'overlapped' flag which permits overlapped matches.
894
+
895
+ Splititer
896
+ ^^^^^^^^^
897
+
898
+ ``regex.splititer`` has been added. It's a generator equivalent of ``regex.split``.
899
+
900
+ Subscripting match objects for groups
901
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
902
+
903
+ A match object accepts access to the groups via subscripting and slicing:
904
+
905
+ .. sourcecode:: python
906
+
907
+ >>> m = regex.search(r"(?P<before>.*?)(?P<num>\d+)(?P<after>.*)", "pqr123stu")
908
+ >>> print(m["before"])
909
+ pqr
910
+ >>> print(len(m))
911
+ 4
912
+ >>> print(m[:])
913
+ ('pqr123stu', 'pqr', '123', 'stu')
914
+
915
+ Named groups
916
+ ^^^^^^^^^^^^
917
+
918
+ Groups can be named with ``(?<name>...)`` as well as the existing ``(?P<name>...)``.
919
+
920
+ Group references
921
+ ^^^^^^^^^^^^^^^^
922
+
923
+ Groups can be referenced within a pattern with ``\g<name>``. This also allows there to be more than 99 groups.
924
+
925
+ Named characters ``\N{name}``
926
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
927
+
928
+ Named characters are supported. Note that only those known by Python's Unicode database will be recognised.
929
+
930
+ Unicode codepoint properties, including scripts and blocks
931
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
932
+
933
+ ``\p{property=value}``; ``\P{property=value}``; ``\p{value}`` ; ``\P{value}``
934
+
935
+ Many Unicode properties are supported, including blocks and scripts. ``\p{property=value}`` or ``\p{property:value}`` matches a character whose property ``property`` has value ``value``. The inverse of ``\p{property=value}`` is ``\P{property=value}`` or ``\p{^property=value}``.
936
+
937
+ If the short form ``\p{value}`` is used, the properties are checked in the order: ``General_Category``, ``Script``, ``Block``, binary property:
938
+
939
+ * ``Latin``, the 'Latin' script (``Script=Latin``).
940
+
941
+ * ``BasicLatin``, the 'BasicLatin' block (``Block=BasicLatin``).
942
+
943
+ * ``Alphabetic``, the 'Alphabetic' binary property (``Alphabetic=Yes``).
944
+
945
+ A short form starting with ``Is`` indicates a script or binary property:
946
+
947
+ * ``IsLatin``, the 'Latin' script (``Script=Latin``).
948
+
949
+ * ``IsAlphabetic``, the 'Alphabetic' binary property (``Alphabetic=Yes``).
950
+
951
+ A short form starting with ``In`` indicates a block property:
952
+
953
+ * ``InBasicLatin``, the 'BasicLatin' block (``Block=BasicLatin``).
954
+
955
+ POSIX character classes
956
+ ^^^^^^^^^^^^^^^^^^^^^^^
957
+
958
+ ``[[:alpha:]]``; ``[[:^alpha:]]``
959
+
960
+ POSIX character classes are supported. These are normally treated as an alternative form of ``\p{...}``.
961
+
962
+ The exceptions are ``alnum``, ``digit``, ``punct`` and ``xdigit``, whose definitions are different from those of Unicode.
963
+
964
+ ``[[:alnum:]]`` is equivalent to ``\p{posix_alnum}``.
965
+
966
+ ``[[:digit:]]`` is equivalent to ``\p{posix_digit}``.
967
+
968
+ ``[[:punct:]]`` is equivalent to ``\p{posix_punct}``.
969
+
970
+ ``[[:xdigit:]]`` is equivalent to ``\p{posix_xdigit}``.
971
+
972
+ Search anchor ``\G``
973
+ ^^^^^^^^^^^^^^^^^^^^
974
+
975
+ A search anchor has been added. It matches at the position where each search started/continued and can be used for contiguous matches or in negative variable-length lookbehinds to limit how far back the lookbehind goes:
976
+
977
+ .. sourcecode:: python
978
+
979
+ >>> regex.findall(r"\w{2}", "abcd ef")
980
+ ['ab', 'cd', 'ef']
981
+ >>> regex.findall(r"\G\w{2}", "abcd ef")
982
+ ['ab', 'cd']
983
+
984
+ * The search starts at position 0 and matches 'ab'.
985
+
986
+ * The search continues at position 2 and matches 'cd'.
987
+
988
+ * The search continues at position 4 and fails to match any letters.
989
+
990
+ * The anchor stops the search start position from being advanced, so there are no more results.
991
+
992
+ Reverse searching
993
+ ^^^^^^^^^^^^^^^^^
994
+
995
+ Searches can also work backwards:
996
+
997
+ .. sourcecode:: python
998
+
999
+ >>> regex.findall(r".", "abc")
1000
+ ['a', 'b', 'c']
1001
+ >>> regex.findall(r"(?r).", "abc")
1002
+ ['c', 'b', 'a']
1003
+
1004
+ Note that the result of a reverse search is not necessarily the reverse of a forward search:
1005
+
1006
+ .. sourcecode:: python
1007
+
1008
+ >>> regex.findall(r"..", "abcde")
1009
+ ['ab', 'cd']
1010
+ >>> regex.findall(r"(?r)..", "abcde")
1011
+ ['de', 'bc']
1012
+
1013
+ Matching a single grapheme ``\X``
1014
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1015
+
1016
+ The grapheme matcher is supported. It conforms to the Unicode specification at ``http://www.unicode.org/reports/tr29/``.
1017
+
1018
+ Branch reset ``(?|...|...)``
1019
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1020
+
1021
+ Group numbers will be reused across the alternatives, but groups with different names will have different group numbers.
1022
+
1023
+ .. sourcecode:: python
1024
+
1025
+ >>> regex.match(r"(?|(first)|(second))", "first").groups()
1026
+ ('first',)
1027
+ >>> regex.match(r"(?|(first)|(second))", "second").groups()
1028
+ ('second',)
1029
+
1030
+ Note that there is only one group.
1031
+
1032
+ Default Unicode word boundary
1033
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1034
+
1035
+ The ``WORD`` flag changes the definition of a 'word boundary' to that of a default Unicode word boundary. This applies to ``\b`` and ``\B``.
1036
+
1037
+ Timeout
1038
+ ^^^^^^^
1039
+
1040
+ The matching methods and functions support timeouts. The timeout (in seconds) applies to the entire operation:
1041
+
1042
+ .. sourcecode:: python
1043
+
1044
+ >>> from time import sleep
1045
+ >>>
1046
+ >>> def fast_replace(m):
1047
+ ... return 'X'
1048
+ ...
1049
+ >>> def slow_replace(m):
1050
+ ... sleep(0.5)
1051
+ ... return 'X'
1052
+ ...
1053
+ >>> regex.sub(r'[a-z]', fast_replace, 'abcde', timeout=2)
1054
+ 'XXXXX'
1055
+ >>> regex.sub(r'[a-z]', slow_replace, 'abcde', timeout=2)
1056
+ Traceback (most recent call last):
1057
+ File "<stdin>", line 1, in <module>
1058
+ File "C:\Python310\lib\site-packages\regex\regex.py", line 278, in sub
1059
+ return pat.sub(repl, string, count, pos, endpos, concurrent, timeout)
1060
+ TimeoutError: regex timed out
.cache/pip/http-v2/c/4/2/0/3/c4203c5060d0f778eafd521050eab23e6aaa0f9eefa17eb1e671212c ADDED
Binary file (1.81 kB). View file
 
.cache/pip/http-v2/c/4/2/0/3/c4203c5060d0f778eafd521050eab23e6aaa0f9eefa17eb1e671212c.body ADDED
Binary file (306 kB). View file
 
.cache/pip/http-v2/c/5/4/0/3/c5403a101bbaf526810b4c472004bc3b03b96b7c8118e06c7a081e63.body ADDED
Binary file (266 kB). View file
 
.cache/pip/http-v2/c/d/5/d/e/cd5de44b899cbe1869765c21b55cffc53c0c0ffa9d3c6f1fd40a42a2.body ADDED
Binary file (178 kB). View file
 
.cache/pip/http-v2/f/0/4/f/6/f04f619fe804fd38ac24d3bad7c02b3e6461727bd3a1ce45e316d44a ADDED
Binary file (1.16 kB). View file
 
.cache/pip/http-v2/f/0/4/f/6/f04f619fe804fd38ac24d3bad7c02b3e6461727bd3a1ce45e316d44a.body ADDED
Binary file (12.2 kB). View file
 
.cache/pip/http-v2/f/4/3/c/e/f43ce2cb74a8c7ad77da70314e043a539a7f01416550c3167312132b ADDED
Binary file (1.16 kB). View file
 
.cache/pip/http-v2/f/4/3/c/e/f43ce2cb74a8c7ad77da70314e043a539a7f01416550c3167312132b.body ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: async-timeout
3
+ Version: 4.0.3
4
+ Summary: Timeout context manager for asyncio programs
5
+ Home-page: https://github.com/aio-libs/async-timeout
6
+ Author: Andrew Svetlov <[email protected]>
7
+ Author-email: [email protected]
8
+ License: Apache 2
9
+ Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby
10
+ Project-URL: CI: GitHub Actions, https://github.com/aio-libs/async-timeout/actions
11
+ Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/async-timeout
12
+ Project-URL: GitHub: issues, https://github.com/aio-libs/async-timeout/issues
13
+ Project-URL: GitHub: repo, https://github.com/aio-libs/async-timeout
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Classifier: Framework :: AsyncIO
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: Apache Software License
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.7
23
+ Classifier: Programming Language :: Python :: 3.8
24
+ Classifier: Programming Language :: Python :: 3.9
25
+ Classifier: Programming Language :: Python :: 3.10
26
+ Classifier: Programming Language :: Python :: 3.11
27
+ Requires-Python: >=3.7
28
+ Description-Content-Type: text/x-rst
29
+ License-File: LICENSE
30
+ Requires-Dist: typing-extensions >=3.6.5 ; python_version < "3.8"
31
+
32
+ async-timeout
33
+ =============
34
+ .. image:: https://travis-ci.com/aio-libs/async-timeout.svg?branch=master
35
+ :target: https://travis-ci.com/aio-libs/async-timeout
36
+ .. image:: https://codecov.io/gh/aio-libs/async-timeout/branch/master/graph/badge.svg
37
+ :target: https://codecov.io/gh/aio-libs/async-timeout
38
+ .. image:: https://img.shields.io/pypi/v/async-timeout.svg
39
+ :target: https://pypi.python.org/pypi/async-timeout
40
+ .. image:: https://badges.gitter.im/Join%20Chat.svg
41
+ :target: https://gitter.im/aio-libs/Lobby
42
+ :alt: Chat on Gitter
43
+
44
+ asyncio-compatible timeout context manager.
45
+
46
+
47
+ Usage example
48
+ -------------
49
+
50
+
51
+ The context manager is useful in cases when you want to apply timeout
52
+ logic around block of code or in cases when ``asyncio.wait_for()`` is
53
+ not suitable. Also it's much faster than ``asyncio.wait_for()``
54
+ because ``timeout`` doesn't create a new task.
55
+
56
+ The ``timeout(delay, *, loop=None)`` call returns a context manager
57
+ that cancels a block on *timeout* expiring::
58
+
59
+ from async_timeout import timeout
60
+ async with timeout(1.5):
61
+ await inner()
62
+
63
+ 1. If ``inner()`` is executed faster than in ``1.5`` seconds nothing
64
+ happens.
65
+ 2. Otherwise ``inner()`` is cancelled internally by sending
66
+ ``asyncio.CancelledError`` into but ``asyncio.TimeoutError`` is
67
+ raised outside of context manager scope.
68
+
69
+ *timeout* parameter could be ``None`` for skipping timeout functionality.
70
+
71
+
72
+ Alternatively, ``timeout_at(when)`` can be used for scheduling
73
+ at the absolute time::
74
+
75
+ loop = asyncio.get_event_loop()
76
+ now = loop.time()
77
+
78
+ async with timeout_at(now + 1.5):
79
+ await inner()
80
+
81
+
82
+ Please note: it is not POSIX time but a time with
83
+ undefined starting base, e.g. the time of the system power on.
84
+
85
+
86
+ Context manager has ``.expired`` property for check if timeout happens
87
+ exactly in context manager::
88
+
89
+ async with timeout(1.5) as cm:
90
+ await inner()
91
+ print(cm.expired)
92
+
93
+ The property is ``True`` if ``inner()`` execution is cancelled by
94
+ timeout context manager.
95
+
96
+ If ``inner()`` call explicitly raises ``TimeoutError`` ``cm.expired``
97
+ is ``False``.
98
+
99
+ The scheduled deadline time is available as ``.deadline`` property::
100
+
101
+ async with timeout(1.5) as cm:
102
+ cm.deadline
103
+
104
+ Not finished yet timeout can be rescheduled by ``shift_by()``
105
+ or ``shift_to()`` methods::
106
+
107
+ async with timeout(1.5) as cm:
108
+ cm.shift(1) # add another second on waiting
109
+ cm.update(loop.time() + 5) # reschedule to now+5 seconds
110
+
111
+ Rescheduling is forbidden if the timeout is expired or after exit from ``async with``
112
+ code block.
113
+
114
+
115
+ Installation
116
+ ------------
117
+
118
+ ::
119
+
120
+ $ pip install async-timeout
121
+
122
+ The library is Python 3 only!
123
+
124
+
125
+
126
+ Authors and License
127
+ -------------------
128
+
129
+ The module is written by Andrew Svetlov.
130
+
131
+ It's *Apache 2* licensed and freely available.
.cache/pip/http-v2/f/4/4/1/e/f441e9f50c61e41b200d99c506edae810953f5810bcb8a4e8bae463c.body ADDED
Binary file (18.9 kB). View file
 
.cache/pip/http-v2/f/6/8/9/5/f689581dbe86ea3c1a14226c252116f97e87dde2c835d7d60fd42b59 ADDED
Binary file (1.19 kB). View file
 
.cache/pip/http-v2/f/6/8/9/5/f689581dbe86ea3c1a14226c252116f97e87dde2c835d7d60fd42b59.body ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: dill
3
+ Version: 0.3.8
4
+ Summary: serialize all of Python
5
+ Home-page: https://github.com/uqfoundation/dill
6
+ Author: Mike McKerns
7
+ Author-email: [email protected]
8
+ Maintainer: Mike McKerns
9
+ Maintainer-email: [email protected]
10
+ License: BSD-3-Clause
11
+ Download-URL: https://pypi.org/project/dill/#files
12
+ Project-URL: Documentation, http://dill.rtfd.io
13
+ Project-URL: Source Code, https://github.com/uqfoundation/dill
14
+ Project-URL: Bug Tracker, https://github.com/uqfoundation/dill/issues
15
+ Platform: Linux
16
+ Platform: Windows
17
+ Platform: Mac
18
+ Classifier: Development Status :: 5 - Production/Stable
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: Intended Audience :: Science/Research
21
+ Classifier: License :: OSI Approved :: BSD License
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.8
24
+ Classifier: Programming Language :: Python :: 3.9
25
+ Classifier: Programming Language :: Python :: 3.10
26
+ Classifier: Programming Language :: Python :: 3.11
27
+ Classifier: Programming Language :: Python :: 3.12
28
+ Classifier: Programming Language :: Python :: Implementation :: CPython
29
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
30
+ Classifier: Topic :: Scientific/Engineering
31
+ Classifier: Topic :: Software Development
32
+ Requires-Python: >=3.8
33
+ Provides-Extra: graph
34
+ Requires-Dist: objgraph (>=1.7.2) ; extra == 'graph'
35
+ Provides-Extra: profile
36
+ Requires-Dist: gprof2dot (>=2022.7.29) ; extra == 'profile'
37
+ Provides-Extra: readline
38
+
39
+ -----------------------------
40
+ dill: serialize all of Python
41
+ -----------------------------
42
+
43
+ About Dill
44
+ ==========
45
+
46
+ ``dill`` extends Python's ``pickle`` module for serializing and de-serializing
47
+ Python objects to the majority of the built-in Python types. Serialization
48
+ is the process of converting an object to a byte stream, and the inverse
49
+ of which is converting a byte stream back to a Python object hierarchy.
50
+
51
+ ``dill`` provides the user the same interface as the ``pickle`` module, and
52
+ also includes some additional features. In addition to pickling Python
53
+ objects, ``dill`` provides the ability to save the state of an interpreter
54
+ session in a single command. Hence, it would be feasible to save an
55
+ interpreter session, close the interpreter, ship the pickled file to
56
+ another computer, open a new interpreter, unpickle the session and
57
+ thus continue from the 'saved' state of the original interpreter
58
+ session.
59
+
60
+ ``dill`` can be used to store Python objects to a file, but the primary
61
+ usage is to send Python objects across the network as a byte stream.
62
+ ``dill`` is quite flexible, and allows arbitrary user defined classes
63
+ and functions to be serialized. Thus ``dill`` is not intended to be
64
+ secure against erroneously or maliciously constructed data. It is
65
+ left to the user to decide whether the data they unpickle is from
66
+ a trustworthy source.
67
+
68
+ ``dill`` is part of ``pathos``, a Python framework for heterogeneous computing.
69
+ ``dill`` is in active development, so any user feedback, bug reports, comments,
70
+ or suggestions are highly appreciated. A list of issues is located at
71
+ https://github.com/uqfoundation/dill/issues, with a legacy list maintained at
72
+ https://uqfoundation.github.io/project/pathos/query.
73
+
74
+
75
+ Major Features
76
+ ==============
77
+
78
+ ``dill`` can pickle the following standard types:
79
+
80
+ - none, type, bool, int, float, complex, bytes, str,
81
+ - tuple, list, dict, file, buffer, builtin,
82
+ - Python classes, namedtuples, dataclasses, metaclasses,
83
+ - instances of classes,
84
+ - set, frozenset, array, functions, exceptions
85
+
86
+ ``dill`` can also pickle more 'exotic' standard types:
87
+
88
+ - functions with yields, nested functions, lambdas,
89
+ - cell, method, unboundmethod, module, code, methodwrapper,
90
+ - methoddescriptor, getsetdescriptor, memberdescriptor, wrapperdescriptor,
91
+ - dictproxy, slice, notimplemented, ellipsis, quit
92
+
93
+ ``dill`` cannot yet pickle these standard types:
94
+
95
+ - frame, generator, traceback
96
+
97
+ ``dill`` also provides the capability to:
98
+
99
+ - save and load Python interpreter sessions
100
+ - save and extract the source code from functions and classes
101
+ - interactively diagnose pickling errors
102
+
103
+
104
+ Current Release
105
+ ===============
106
+
107
+ The latest released version of ``dill`` is available from:
108
+
109
+ https://pypi.org/project/dill
110
+
111
+ ``dill`` is distributed under a 3-clause BSD license.
112
+
113
+
114
+ Development Version
115
+ ===================
116
+
117
+ You can get the latest development version with all the shiny new features at:
118
+
119
+ https://github.com/uqfoundation
120
+
121
+ If you have a new contribution, please submit a pull request.
122
+
123
+
124
+ Installation
125
+ ============
126
+
127
+ ``dill`` can be installed with ``pip``::
128
+
129
+ $ pip install dill
130
+
131
+ To optionally include the ``objgraph`` diagnostic tool in the install::
132
+
133
+ $ pip install dill[graph]
134
+
135
+ To optionally include the ``gprof2dot`` diagnostic tool in the install::
136
+
137
+ $ pip install dill[profile]
138
+
139
+ For windows users, to optionally install session history tools::
140
+
141
+ $ pip install dill[readline]
142
+
143
+
144
+ Requirements
145
+ ============
146
+
147
+ ``dill`` requires:
148
+
149
+ - ``python`` (or ``pypy``), **>=3.8**
150
+ - ``setuptools``, **>=42**
151
+
152
+ Optional requirements:
153
+
154
+ - ``objgraph``, **>=1.7.2**
155
+ - ``gprof2dot``, **>=2022.7.29**
156
+ - ``pyreadline``, **>=1.7.1** (on windows)
157
+
158
+
159
+ Basic Usage
160
+ ===========
161
+
162
+ ``dill`` is a drop-in replacement for ``pickle``. Existing code can be
163
+ updated to allow complete pickling using::
164
+
165
+ >>> import dill as pickle
166
+
167
+ or::
168
+
169
+ >>> from dill import dumps, loads
170
+
171
+ ``dumps`` converts the object to a unique byte string, and ``loads`` performs
172
+ the inverse operation::
173
+
174
+ >>> squared = lambda x: x**2
175
+ >>> loads(dumps(squared))(3)
176
+ 9
177
+
178
+ There are a number of options to control serialization which are provided
179
+ as keyword arguments to several ``dill`` functions:
180
+
181
+ * with *protocol*, the pickle protocol level can be set. This uses the
182
+ same value as the ``pickle`` module, *DEFAULT_PROTOCOL*.
183
+ * with *byref=True*, ``dill`` to behave a lot more like pickle with
184
+ certain objects (like modules) pickled by reference as opposed to
185
+ attempting to pickle the object itself.
186
+ * with *recurse=True*, objects referred to in the global dictionary are
187
+ recursively traced and pickled, instead of the default behavior of
188
+ attempting to store the entire global dictionary.
189
+ * with *fmode*, the contents of the file can be pickled along with the file
190
+ handle, which is useful if the object is being sent over the wire to a
191
+ remote system which does not have the original file on disk. Options are
192
+ *HANDLE_FMODE* for just the handle, *CONTENTS_FMODE* for the file content
193
+ and *FILE_FMODE* for content and handle.
194
+ * with *ignore=False*, objects reconstructed with types defined in the
195
+ top-level script environment use the existing type in the environment
196
+ rather than a possibly different reconstructed type.
197
+
198
+ The default serialization can also be set globally in *dill.settings*.
199
+ Thus, we can modify how ``dill`` handles references to the global dictionary
200
+ locally or globally::
201
+
202
+ >>> import dill.settings
203
+ >>> dumps(absolute) == dumps(absolute, recurse=True)
204
+ False
205
+ >>> dill.settings['recurse'] = True
206
+ >>> dumps(absolute) == dumps(absolute, recurse=True)
207
+ True
208
+
209
+ ``dill`` also includes source code inspection, as an alternate to pickling::
210
+
211
+ >>> import dill.source
212
+ >>> print(dill.source.getsource(squared))
213
+ squared = lambda x:x**2
214
+
215
+ To aid in debugging pickling issues, use *dill.detect* which provides
216
+ tools like pickle tracing::
217
+
218
+ >>> import dill.detect
219
+ >>> with dill.detect.trace():
220
+ >>> dumps(squared)
221
+ ┬ F1: <function <lambda> at 0x7fe074f8c280>
222
+ ├┬ F2: <function _create_function at 0x7fe074c49c10>
223
+ │└ # F2 [34 B]
224
+ ├┬ Co: <code object <lambda> at 0x7fe07501eb30, file "<stdin>", line 1>
225
+ │├┬ F2: <function _create_code at 0x7fe074c49ca0>
226
+ ││└ # F2 [19 B]
227
+ │└ # Co [87 B]
228
+ ├┬ D1: <dict object at 0x7fe0750d4680>
229
+ │└ # D1 [22 B]
230
+ ├┬ D2: <dict object at 0x7fe074c5a1c0>
231
+ │└ # D2 [2 B]
232
+ ├┬ D2: <dict object at 0x7fe074f903c0>
233
+ │├┬ D2: <dict object at 0x7fe074f8ebc0>
234
+ ││└ # D2 [2 B]
235
+ │└ # D2 [23 B]
236
+ └ # F1 [180 B]
237
+
238
+ With trace, we see how ``dill`` stored the lambda (``F1``) by first storing
239
+ ``_create_function``, the underlying code object (``Co``) and ``_create_code``
240
+ (which is used to handle code objects), then we handle the reference to
241
+ the global dict (``D2``) plus other dictionaries (``D1`` and ``D2``) that
242
+ save the lambda object's state. A ``#`` marks when the object is actually stored.
243
+
244
+
245
+ More Information
246
+ ================
247
+
248
+ Probably the best way to get started is to look at the documentation at
249
+ http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
250
+ demonstrate how ``dill`` can serialize different Python objects. You can
251
+ run the test suite with ``python -m dill.tests``. The contents of any
252
+ pickle file can be examined with ``undill``. As ``dill`` conforms to
253
+ the ``pickle`` interface, the examples and documentation found at
254
+ http://docs.python.org/library/pickle.html also apply to ``dill``
255
+ if one will ``import dill as pickle``. The source code is also generally
256
+ well documented, so further questions may be resolved by inspecting the
257
+ code itself. Please feel free to submit a ticket on github, or ask a
258
+ question on stackoverflow (**@Mike McKerns**).
259
+ If you would like to share how you use ``dill`` in your work, please send
260
+ an email (to **mmckerns at uqfoundation dot org**).
261
+
262
+
263
+ Citation
264
+ ========
265
+
266
+ If you use ``dill`` to do research that leads to publication, we ask that you
267
+ acknowledge use of ``dill`` by citing the following in your publication::
268
+
269
+ M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
270
+ "Building a framework for predictive science", Proceedings of
271
+ the 10th Python in Science Conference, 2011;
272
+ http://arxiv.org/pdf/1202.1056
273
+
274
+ Michael McKerns and Michael Aivazis,
275
+ "pathos: a framework for heterogeneous computing", 2010- ;
276
+ https://uqfoundation.github.io/project/pathos
277
+
278
+ Please see https://uqfoundation.github.io/project/pathos or
279
+ http://arxiv.org/pdf/1202.1056 for further information.
280
+
.cache/pip/http-v2/f/a/0/e/b/fa0eb94064e725636a09e766c68812661f1423e7568ddc8b81c74949.body ADDED
@@ -0,0 +1,1591 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: tqdm
3
+ Version: 4.66.5
4
+ Summary: Fast, Extensible Progress Meter
5
+ Maintainer-email: tqdm developers <[email protected]>
6
+ License: MPL-2.0 AND MIT
7
+ Project-URL: homepage, https://tqdm.github.io
8
+ Project-URL: repository, https://github.com/tqdm/tqdm
9
+ Project-URL: changelog, https://tqdm.github.io/releases
10
+ Project-URL: wiki, https://github.com/tqdm/tqdm/wiki
11
+ Keywords: progressbar,progressmeter,progress,bar,meter,rate,eta,console,terminal,time
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Environment :: MacOS X
15
+ Classifier: Environment :: Other Environment
16
+ Classifier: Environment :: Win32 (MS Windows)
17
+ Classifier: Environment :: X11 Applications
18
+ Classifier: Framework :: IPython
19
+ Classifier: Framework :: Jupyter
20
+ Classifier: Intended Audience :: Developers
21
+ Classifier: Intended Audience :: Education
22
+ Classifier: Intended Audience :: End Users/Desktop
23
+ Classifier: Intended Audience :: Other Audience
24
+ Classifier: Intended Audience :: System Administrators
25
+ Classifier: License :: OSI Approved :: MIT License
26
+ Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
27
+ Classifier: Operating System :: MacOS
28
+ Classifier: Operating System :: MacOS :: MacOS X
29
+ Classifier: Operating System :: Microsoft
30
+ Classifier: Operating System :: Microsoft :: MS-DOS
31
+ Classifier: Operating System :: Microsoft :: Windows
32
+ Classifier: Operating System :: POSIX
33
+ Classifier: Operating System :: POSIX :: BSD
34
+ Classifier: Operating System :: POSIX :: BSD :: FreeBSD
35
+ Classifier: Operating System :: POSIX :: Linux
36
+ Classifier: Operating System :: POSIX :: SunOS/Solaris
37
+ Classifier: Operating System :: Unix
38
+ Classifier: Programming Language :: Python
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.7
41
+ Classifier: Programming Language :: Python :: 3.8
42
+ Classifier: Programming Language :: Python :: 3.9
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
45
+ Classifier: Programming Language :: Python :: 3.12
46
+ Classifier: Programming Language :: Python :: 3 :: Only
47
+ Classifier: Programming Language :: Python :: Implementation
48
+ Classifier: Programming Language :: Python :: Implementation :: IronPython
49
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
50
+ Classifier: Programming Language :: Unix Shell
51
+ Classifier: Topic :: Desktop Environment
52
+ Classifier: Topic :: Education :: Computer Aided Instruction (CAI)
53
+ Classifier: Topic :: Education :: Testing
54
+ Classifier: Topic :: Office/Business
55
+ Classifier: Topic :: Other/Nonlisted Topic
56
+ Classifier: Topic :: Software Development :: Build Tools
57
+ Classifier: Topic :: Software Development :: Libraries
58
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
59
+ Classifier: Topic :: Software Development :: Pre-processors
60
+ Classifier: Topic :: Software Development :: User Interfaces
61
+ Classifier: Topic :: System :: Installation/Setup
62
+ Classifier: Topic :: System :: Logging
63
+ Classifier: Topic :: System :: Monitoring
64
+ Classifier: Topic :: System :: Shells
65
+ Classifier: Topic :: Terminals
66
+ Classifier: Topic :: Utilities
67
+ Requires-Python: >=3.7
68
+ Description-Content-Type: text/x-rst
69
+ License-File: LICENCE
70
+ Requires-Dist: colorama ; platform_system == "Windows"
71
+ Provides-Extra: dev
72
+ Requires-Dist: pytest >=6 ; extra == 'dev'
73
+ Requires-Dist: pytest-cov ; extra == 'dev'
74
+ Requires-Dist: pytest-timeout ; extra == 'dev'
75
+ Requires-Dist: pytest-xdist ; extra == 'dev'
76
+ Provides-Extra: notebook
77
+ Requires-Dist: ipywidgets >=6 ; extra == 'notebook'
78
+ Provides-Extra: slack
79
+ Requires-Dist: slack-sdk ; extra == 'slack'
80
+ Provides-Extra: telegram
81
+ Requires-Dist: requests ; extra == 'telegram'
82
+
83
+ |Logo|
84
+
85
+ tqdm
86
+ ====
87
+
88
+ |Py-Versions| |Versions| |Conda-Forge-Status| |Docker| |Snapcraft|
89
+
90
+ |Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade| |Libraries-Rank| |PyPI-Downloads|
91
+
92
+ |LICENCE| |OpenHub-Status| |binder-demo| |awesome-python|
93
+
94
+ ``tqdm`` derives from the Arabic word *taqaddum* (تقدّم) which can mean "progress,"
95
+ and is an abbreviation for "I love you so much" in Spanish (*te quiero demasiado*).
96
+
97
+ Instantly make your loops show a smart progress meter - just wrap any
98
+ iterable with ``tqdm(iterable)``, and you're done!
99
+
100
+ .. code:: python
101
+
102
+ from tqdm import tqdm
103
+ for i in tqdm(range(10000)):
104
+ ...
105
+
106
+ ``76%|████████████████████████        | 7568/10000 [00:33<00:10, 229.00it/s]``
107
+
108
+ ``trange(N)`` can be also used as a convenient shortcut for
109
+ ``tqdm(range(N))``.
110
+
111
+ |Screenshot|
112
+ |Video| |Slides| |Merch|
113
+
114
+ It can also be executed as a module with pipes:
115
+
116
+ .. code:: sh
117
+
118
+ $ seq 9999999 | tqdm --bytes | wc -l
119
+ 75.2MB [00:00, 217MB/s]
120
+ 9999999
121
+
122
+ $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
123
+ > backup.tgz
124
+ 32%|██████████▍ | 8.89G/27.9G [00:42<01:31, 223MB/s]
125
+
126
+ Overhead is low -- about 60ns per iteration (80ns with ``tqdm.gui``), and is
127
+ unit tested against performance regression.
128
+ By comparison, the well-established
129
+ `ProgressBar <https://github.com/niltonvolpato/python-progressbar>`__ has
130
+ an 800ns/iter overhead.
131
+
132
+ In addition to its low overhead, ``tqdm`` uses smart algorithms to predict
133
+ the remaining time and to skip unnecessary iteration displays, which allows
134
+ for a negligible overhead in most cases.
135
+
136
+ ``tqdm`` works on any platform
137
+ (Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS),
138
+ in any console or in a GUI, and is also friendly with IPython/Jupyter notebooks.
139
+
140
+ ``tqdm`` does not require any dependencies (not even ``curses``!), just
141
+ Python and an environment supporting ``carriage return \r`` and
142
+ ``line feed \n`` control characters.
143
+
144
+ ------------------------------------------
145
+
146
+ .. contents:: Table of contents
147
+ :backlinks: top
148
+ :local:
149
+
150
+
151
+ Installation
152
+ ------------
153
+
154
+ Latest PyPI stable release
155
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
156
+
157
+ |Versions| |PyPI-Downloads| |Libraries-Dependents|
158
+
159
+ .. code:: sh
160
+
161
+ pip install tqdm
162
+
163
+ Latest development release on GitHub
164
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165
+
166
+ |GitHub-Status| |GitHub-Stars| |GitHub-Commits| |GitHub-Forks| |GitHub-Updated|
167
+
168
+ Pull and install pre-release ``devel`` branch:
169
+
170
+ .. code:: sh
171
+
172
+ pip install "git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm"
173
+
174
+ Latest Conda release
175
+ ~~~~~~~~~~~~~~~~~~~~
176
+
177
+ |Conda-Forge-Status|
178
+
179
+ .. code:: sh
180
+
181
+ conda install -c conda-forge tqdm
182
+
183
+ Latest Snapcraft release
184
+ ~~~~~~~~~~~~~~~~~~~~~~~~
185
+
186
+ |Snapcraft|
187
+
188
+ There are 3 channels to choose from:
189
+
190
+ .. code:: sh
191
+
192
+ snap install tqdm # implies --stable, i.e. latest tagged release
193
+ snap install tqdm --candidate # master branch
194
+ snap install tqdm --edge # devel branch
195
+
196
+ Note that ``snap`` binaries are purely for CLI use (not ``import``-able), and
197
+ automatically set up ``bash`` tab-completion.
198
+
199
+ Latest Docker release
200
+ ~~~~~~~~~~~~~~~~~~~~~
201
+
202
+ |Docker|
203
+
204
+ .. code:: sh
205
+
206
+ docker pull tqdm/tqdm
207
+ docker run -i --rm tqdm/tqdm --help
208
+
209
+ Other
210
+ ~~~~~
211
+
212
+ There are other (unofficial) places where ``tqdm`` may be downloaded, particularly for CLI use:
213
+
214
+ |Repology|
215
+
216
+ .. |Repology| image:: https://repology.org/badge/tiny-repos/python:tqdm.svg
217
+ :target: https://repology.org/project/python:tqdm/versions
218
+
219
+ Changelog
220
+ ---------
221
+
222
+ The list of all changes is available either on GitHub's Releases:
223
+ |GitHub-Status|, on the
224
+ `wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, or on the
225
+ `website <https://tqdm.github.io/releases>`__.
226
+
227
+
228
+ Usage
229
+ -----
230
+
231
+ ``tqdm`` is very versatile and can be used in a number of ways.
232
+ The three main ones are given below.
233
+
234
+ Iterable-based
235
+ ~~~~~~~~~~~~~~
236
+
237
+ Wrap ``tqdm()`` around any iterable:
238
+
239
+ .. code:: python
240
+
241
+ from tqdm import tqdm
242
+ from time import sleep
243
+
244
+ text = ""
245
+ for char in tqdm(["a", "b", "c", "d"]):
246
+ sleep(0.25)
247
+ text = text + char
248
+
249
+ ``trange(i)`` is a special optimised instance of ``tqdm(range(i))``:
250
+
251
+ .. code:: python
252
+
253
+ from tqdm import trange
254
+
255
+ for i in trange(100):
256
+ sleep(0.01)
257
+
258
+ Instantiation outside of the loop allows for manual control over ``tqdm()``:
259
+
260
+ .. code:: python
261
+
262
+ pbar = tqdm(["a", "b", "c", "d"])
263
+ for char in pbar:
264
+ sleep(0.25)
265
+ pbar.set_description("Processing %s" % char)
266
+
267
+ Manual
268
+ ~~~~~~
269
+
270
+ Manual control of ``tqdm()`` updates using a ``with`` statement:
271
+
272
+ .. code:: python
273
+
274
+ with tqdm(total=100) as pbar:
275
+ for i in range(10):
276
+ sleep(0.1)
277
+ pbar.update(10)
278
+
279
+ If the optional variable ``total`` (or an iterable with ``len()``) is
280
+ provided, predictive stats are displayed.
281
+
282
+ ``with`` is also optional (you can just assign ``tqdm()`` to a variable,
283
+ but in this case don't forget to ``del`` or ``close()`` at the end:
284
+
285
+ .. code:: python
286
+
287
+ pbar = tqdm(total=100)
288
+ for i in range(10):
289
+ sleep(0.1)
290
+ pbar.update(10)
291
+ pbar.close()
292
+
293
+ Module
294
+ ~~~~~~
295
+
296
+ Perhaps the most wonderful use of ``tqdm`` is in a script or on the command
297
+ line. Simply inserting ``tqdm`` (or ``python -m tqdm``) between pipes will pass
298
+ through all ``stdin`` to ``stdout`` while printing progress to ``stderr``.
299
+
300
+ The example below demonstrate counting the number of lines in all Python files
301
+ in the current directory, with timing information included.
302
+
303
+ .. code:: sh
304
+
305
+ $ time find . -name '*.py' -type f -exec cat \{} \; | wc -l
306
+ 857365
307
+
308
+ real 0m3.458s
309
+ user 0m0.274s
310
+ sys 0m3.325s
311
+
312
+ $ time find . -name '*.py' -type f -exec cat \{} \; | tqdm | wc -l
313
+ 857366it [00:03, 246471.31it/s]
314
+ 857365
315
+
316
+ real 0m3.585s
317
+ user 0m0.862s
318
+ sys 0m3.358s
319
+
320
+ Note that the usual arguments for ``tqdm`` can also be specified.
321
+
322
+ .. code:: sh
323
+
324
+ $ find . -name '*.py' -type f -exec cat \{} \; |
325
+ tqdm --unit loc --unit_scale --total 857366 >> /dev/null
326
+ 100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s]
327
+
328
+ Backing up a large directory?
329
+
330
+ .. code:: sh
331
+
332
+ $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
333
+ > backup.tgz
334
+ 44%|██████████████▊ | 153M/352M [00:14<00:18, 11.0MB/s]
335
+
336
+ This can be beautified further:
337
+
338
+ .. code:: sh
339
+
340
+ $ BYTES=$(du -sb docs/ | cut -f1)
341
+ $ tar -cf - docs/ \
342
+ | tqdm --bytes --total "$BYTES" --desc Processing | gzip \
343
+ | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \
344
+ > ~/backup.tgz
345
+ Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s]
346
+ Compressed: 42%|█████████▎ | 148M/352M [00:14<00:19, 10.9MB/s]
347
+
348
+ Or done on a file level using 7-zip:
349
+
350
+ .. code:: sh
351
+
352
+ $ 7z a -bd -r backup.7z docs/ | grep Compressing \
353
+ | tqdm --total $(find docs/ -type f | wc -l) --unit files \
354
+ | grep -v Compressing
355
+ 100%|██████████████████████████▉| 15327/15327 [01:00<00:00, 712.96files/s]
356
+
357
+ Pre-existing CLI programs already outputting basic progress information will
358
+ benefit from ``tqdm``'s ``--update`` and ``--update_to`` flags:
359
+
360
+ .. code:: sh
361
+
362
+ $ seq 3 0.1 5 | tqdm --total 5 --update_to --null
363
+ 100%|████████████████████████████████████| 5.0/5 [00:00<00:00, 9673.21it/s]
364
+ $ seq 10 | tqdm --update --null # 1 + 2 + ... + 10 = 55 iterations
365
+ 55it [00:00, 90006.52it/s]
366
+
367
+ FAQ and Known Issues
368
+ --------------------
369
+
370
+ |GitHub-Issues|
371
+
372
+ The most common issues relate to excessive output on multiple lines, instead
373
+ of a neat one-line progress bar.
374
+
375
+ - Consoles in general: require support for carriage return (``CR``, ``\r``).
376
+
377
+ * Some cloud logging consoles which don't support ``\r`` properly
378
+ (`cloudwatch <https://github.com/tqdm/tqdm/issues/966>`__,
379
+ `K8s <https://github.com/tqdm/tqdm/issues/1319>`__) may benefit from
380
+ ``export TQDM_POSITION=-1``.
381
+
382
+ - Nested progress bars:
383
+
384
+ * Consoles in general: require support for moving cursors up to the
385
+ previous line. For example,
386
+ `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__,
387
+ `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and
388
+ `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also
389
+ `here <https://github.com/tqdm/tqdm/issues/208>`__,
390
+ `here <https://github.com/tqdm/tqdm/issues/307>`__, and
391
+ `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__)
392
+ lack full support.
393
+ * Windows: additionally may require the Python module ``colorama``
394
+ to ensure nested bars stay within their respective lines.
395
+
396
+ - Unicode:
397
+
398
+ * Environments which report that they support unicode will have solid smooth
399
+ progressbars. The fallback is an ``ascii``-only bar.
400
+ * Windows consoles often only partially support unicode and thus
401
+ `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__
402
+ (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to
403
+ either normal-width unicode characters being incorrectly displayed as
404
+ "wide", or some unicode characters not rendering.
405
+
406
+ - Wrapping generators:
407
+
408
+ * Generator wrapper functions tend to hide the length of iterables.
409
+ ``tqdm`` does not.
410
+ * Replace ``tqdm(enumerate(...))`` with ``enumerate(tqdm(...))`` or
411
+ ``tqdm(enumerate(x), total=len(x), ...)``.
412
+ The same applies to ``numpy.ndenumerate``.
413
+ * Replace ``tqdm(zip(a, b))`` with ``zip(tqdm(a), b)`` or even
414
+ ``zip(tqdm(a), tqdm(b))``.
415
+ * The same applies to ``itertools``.
416
+ * Some useful convenience functions can be found under ``tqdm.contrib``.
417
+
418
+ - `No intermediate output in docker-compose <https://github.com/tqdm/tqdm/issues/771>`__:
419
+ use ``docker-compose run`` instead of ``docker-compose up`` and ``tty: true``.
420
+
421
+ - Overriding defaults via environment variables:
422
+ e.g. in CI/cloud jobs, ``export TQDM_MININTERVAL=5`` to avoid log spam.
423
+ This override logic is handled by the ``tqdm.utils.envwrap`` decorator
424
+ (useful independent of ``tqdm``).
425
+
426
+ If you come across any other difficulties, browse and file |GitHub-Issues|.
427
+
428
+ Documentation
429
+ -------------
430
+
431
+ |Py-Versions| |README-Hits| (Since 19 May 2016)
432
+
433
+ .. code:: python
434
+
435
+ class tqdm():
436
+ """
437
+ Decorate an iterable object, returning an iterator which acts exactly
438
+ like the original iterable, but prints a dynamically updating
439
+ progressbar every time a value is requested.
440
+ """
441
+
442
+ @envwrap("TQDM_") # override defaults via env vars
443
+ def __init__(self, iterable=None, desc=None, total=None, leave=True,
444
+ file=None, ncols=None, mininterval=0.1,
445
+ maxinterval=10.0, miniters=None, ascii=None, disable=False,
446
+ unit='it', unit_scale=False, dynamic_ncols=False,
447
+ smoothing=0.3, bar_format=None, initial=0, position=None,
448
+ postfix=None, unit_divisor=1000, write_bytes=False,
449
+ lock_args=None, nrows=None, colour=None, delay=0):
450
+
451
+ Parameters
452
+ ~~~~~~~~~~
453
+
454
+ * iterable : iterable, optional
455
+ Iterable to decorate with a progressbar.
456
+ Leave blank to manually manage the updates.
457
+ * desc : str, optional
458
+ Prefix for the progressbar.
459
+ * total : int or float, optional
460
+ The number of expected iterations. If unspecified,
461
+ len(iterable) is used if possible. If float("inf") or as a last
462
+ resort, only basic progress statistics are displayed
463
+ (no ETA, no progressbar).
464
+ If ``gui`` is True and this parameter needs subsequent updating,
465
+ specify an initial arbitrary large positive number,
466
+ e.g. 9e9.
467
+ * leave : bool, optional
468
+ If [default: True], keeps all traces of the progressbar
469
+ upon termination of iteration.
470
+ If ``None``, will leave only if ``position`` is ``0``.
471
+ * file : ``io.TextIOWrapper`` or ``io.StringIO``, optional
472
+ Specifies where to output the progress messages
473
+ (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()``
474
+ methods. For encoding, see ``write_bytes``.
475
+ * ncols : int, optional
476
+ The width of the entire output message. If specified,
477
+ dynamically resizes the progressbar to stay within this bound.
478
+ If unspecified, attempts to use environment width. The
479
+ fallback is a meter width of 10 and no limit for the counter and
480
+ statistics. If 0, will not print any meter (only stats).
481
+ * mininterval : float, optional
482
+ Minimum progress display update interval [default: 0.1] seconds.
483
+ * maxinterval : float, optional
484
+ Maximum progress display update interval [default: 10] seconds.
485
+ Automatically adjusts ``miniters`` to correspond to ``mininterval``
486
+ after long display update lag. Only works if ``dynamic_miniters``
487
+ or monitor thread is enabled.
488
+ * miniters : int or float, optional
489
+ Minimum progress display update interval, in iterations.
490
+ If 0 and ``dynamic_miniters``, will automatically adjust to equal
491
+ ``mininterval`` (more CPU efficient, good for tight loops).
492
+ If > 0, will skip display of specified number of iterations.
493
+ Tweak this and ``mininterval`` to get very efficient loops.
494
+ If your progress is erratic with both fast and slow iterations
495
+ (network, skipping items, etc) you should set miniters=1.
496
+ * ascii : bool or str, optional
497
+ If unspecified or False, use unicode (smooth blocks) to fill
498
+ the meter. The fallback is to use ASCII characters " 123456789#".
499
+ * disable : bool, optional
500
+ Whether to disable the entire progressbar wrapper
501
+ [default: False]. If set to None, disable on non-TTY.
502
+ * unit : str, optional
503
+ String that will be used to define the unit of each iteration
504
+ [default: it].
505
+ * unit_scale : bool or int or float, optional
506
+ If 1 or True, the number of iterations will be reduced/scaled
507
+ automatically and a metric prefix following the
508
+ International System of Units standard will be added
509
+ (kilo, mega, etc.) [default: False]. If any other non-zero
510
+ number, will scale ``total`` and ``n``.
511
+ * dynamic_ncols : bool, optional
512
+ If set, constantly alters ``ncols`` and ``nrows`` to the
513
+ environment (allowing for window resizes) [default: False].
514
+ * smoothing : float, optional
515
+ Exponential moving average smoothing factor for speed estimates
516
+ (ignored in GUI mode). Ranges from 0 (average speed) to 1
517
+ (current/instantaneous speed) [default: 0.3].
518
+ * bar_format : str, optional
519
+ Specify a custom bar string formatting. May impact performance.
520
+ [default: '{l_bar}{bar}{r_bar}'], where
521
+ l_bar='{desc}: {percentage:3.0f}%|' and
522
+ r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
523
+ '{rate_fmt}{postfix}]'
524
+ Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
525
+ percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,
526
+ rate, rate_fmt, rate_noinv, rate_noinv_fmt,
527
+ rate_inv, rate_inv_fmt, postfix, unit_divisor,
528
+ remaining, remaining_s, eta.
529
+ Note that a trailing ": " is automatically removed after {desc}
530
+ if the latter is empty.
531
+ * initial : int or float, optional
532
+ The initial counter value. Useful when restarting a progress
533
+ bar [default: 0]. If using float, consider specifying ``{n:.3f}``
534
+ or similar in ``bar_format``, or specifying ``unit_scale``.
535
+ * position : int, optional
536
+ Specify the line offset to print this bar (starting from 0)
537
+ Automatic if unspecified.
538
+ Useful to manage multiple bars at once (eg, from threads).
539
+ * postfix : dict or ``*``, optional
540
+ Specify additional stats to display at the end of the bar.
541
+ Calls ``set_postfix(**postfix)`` if possible (dict).
542
+ * unit_divisor : float, optional
543
+ [default: 1000], ignored unless ``unit_scale`` is True.
544
+ * write_bytes : bool, optional
545
+ Whether to write bytes. If (default: False) will write unicode.
546
+ * lock_args : tuple, optional
547
+ Passed to ``refresh`` for intermediate output
548
+ (initialisation, iterating, and updating).
549
+ * nrows : int, optional
550
+ The screen height. If specified, hides nested bars outside this
551
+ bound. If unspecified, attempts to use environment height.
552
+ The fallback is 20.
553
+ * colour : str, optional
554
+ Bar colour (e.g. 'green', '#00ff00').
555
+ * delay : float, optional
556
+ Don't display until [default: 0] seconds have elapsed.
557
+
558
+ Extra CLI Options
559
+ ~~~~~~~~~~~~~~~~~
560
+
561
+ * delim : chr, optional
562
+ Delimiting character [default: '\n']. Use '\0' for null.
563
+ N.B.: on Windows systems, Python converts '\n' to '\r\n'.
564
+ * buf_size : int, optional
565
+ String buffer size in bytes [default: 256]
566
+ used when ``delim`` is specified.
567
+ * bytes : bool, optional
568
+ If true, will count bytes, ignore ``delim``, and default
569
+ ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'.
570
+ * tee : bool, optional
571
+ If true, passes ``stdin`` to both ``stderr`` and ``stdout``.
572
+ * update : bool, optional
573
+ If true, will treat input as newly elapsed iterations,
574
+ i.e. numbers to pass to ``update()``. Note that this is slow
575
+ (~2e5 it/s) since every input must be decoded as a number.
576
+ * update_to : bool, optional
577
+ If true, will treat input as total elapsed iterations,
578
+ i.e. numbers to assign to ``self.n``. Note that this is slow
579
+ (~2e5 it/s) since every input must be decoded as a number.
580
+ * null : bool, optional
581
+ If true, will discard input (no stdout).
582
+ * manpath : str, optional
583
+ Directory in which to install tqdm man pages.
584
+ * comppath : str, optional
585
+ Directory in which to place tqdm completion.
586
+ * log : str, optional
587
+ CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
588
+
589
+ Returns
590
+ ~~~~~~~
591
+
592
+ * out : decorated iterator.
593
+
594
+ .. code:: python
595
+
596
+ class tqdm():
597
+ def update(self, n=1):
598
+ """
599
+ Manually update the progress bar, useful for streams
600
+ such as reading files.
601
+ E.g.:
602
+ >>> t = tqdm(total=filesize) # Initialise
603
+ >>> for current_buffer in stream:
604
+ ... ...
605
+ ... t.update(len(current_buffer))
606
+ >>> t.close()
607
+ The last line is highly recommended, but possibly not necessary if
608
+ ``t.update()`` will be called in such a way that ``filesize`` will be
609
+ exactly reached and printed.
610
+
611
+ Parameters
612
+ ----------
613
+ n : int or float, optional
614
+ Increment to add to the internal counter of iterations
615
+ [default: 1]. If using float, consider specifying ``{n:.3f}``
616
+ or similar in ``bar_format``, or specifying ``unit_scale``.
617
+
618
+ Returns
619
+ -------
620
+ out : bool or None
621
+ True if a ``display()`` was triggered.
622
+ """
623
+
624
+ def close(self):
625
+ """Cleanup and (if leave=False) close the progressbar."""
626
+
627
+ def clear(self, nomove=False):
628
+ """Clear current bar display."""
629
+
630
+ def refresh(self):
631
+ """
632
+ Force refresh the display of this bar.
633
+
634
+ Parameters
635
+ ----------
636
+ nolock : bool, optional
637
+ If ``True``, does not lock.
638
+ If [default: ``False``]: calls ``acquire()`` on internal lock.
639
+ lock_args : tuple, optional
640
+ Passed to internal lock's ``acquire()``.
641
+ If specified, will only ``display()`` if ``acquire()`` returns ``True``.
642
+ """
643
+
644
+ def unpause(self):
645
+ """Restart tqdm timer from last print time."""
646
+
647
+ def reset(self, total=None):
648
+ """
649
+ Resets to 0 iterations for repeated use.
650
+
651
+ Consider combining with ``leave=True``.
652
+
653
+ Parameters
654
+ ----------
655
+ total : int or float, optional. Total to use for the new bar.
656
+ """
657
+
658
+ def set_description(self, desc=None, refresh=True):
659
+ """
660
+ Set/modify description of the progress bar.
661
+
662
+ Parameters
663
+ ----------
664
+ desc : str, optional
665
+ refresh : bool, optional
666
+ Forces refresh [default: True].
667
+ """
668
+
669
+ def set_postfix(self, ordered_dict=None, refresh=True, **tqdm_kwargs):
670
+ """
671
+ Set/modify postfix (additional stats)
672
+ with automatic formatting based on datatype.
673
+
674
+ Parameters
675
+ ----------
676
+ ordered_dict : dict or OrderedDict, optional
677
+ refresh : bool, optional
678
+ Forces refresh [default: True].
679
+ kwargs : dict, optional
680
+ """
681
+
682
+ @classmethod
683
+ def write(cls, s, file=sys.stdout, end="\n"):
684
+ """Print a message via tqdm (without overlap with bars)."""
685
+
686
+ @property
687
+ def format_dict(self):
688
+ """Public API for read-only member access."""
689
+
690
+ def display(self, msg=None, pos=None):
691
+ """
692
+ Use ``self.sp`` to display ``msg`` in the specified ``pos``.
693
+
694
+ Consider overloading this function when inheriting to use e.g.:
695
+ ``self.some_frontend(**self.format_dict)`` instead of ``self.sp``.
696
+
697
+ Parameters
698
+ ----------
699
+ msg : str, optional. What to display (default: ``repr(self)``).
700
+ pos : int, optional. Position to ``moveto``
701
+ (default: ``abs(self.pos)``).
702
+ """
703
+
704
+ @classmethod
705
+ @contextmanager
706
+ def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs):
707
+ """
708
+ stream : file-like object.
709
+ method : str, "read" or "write". The result of ``read()`` and
710
+ the first argument of ``write()`` should have a ``len()``.
711
+
712
+ >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj:
713
+ ... while True:
714
+ ... chunk = fobj.read(chunk_size)
715
+ ... if not chunk:
716
+ ... break
717
+ """
718
+
719
+ @classmethod
720
+ def pandas(cls, *targs, **tqdm_kwargs):
721
+ """Registers the current `tqdm` class with `pandas`."""
722
+
723
+ def trange(*args, **tqdm_kwargs):
724
+ """Shortcut for `tqdm(range(*args), **tqdm_kwargs)`."""
725
+
726
+ Convenience Functions
727
+ ~~~~~~~~~~~~~~~~~~~~~
728
+
729
+ .. code:: python
730
+
731
+ def tqdm.contrib.tenumerate(iterable, start=0, total=None,
732
+ tqdm_class=tqdm.auto.tqdm, **tqdm_kwargs):
733
+ """Equivalent of `numpy.ndenumerate` or builtin `enumerate`."""
734
+
735
+ def tqdm.contrib.tzip(iter1, *iter2plus, **tqdm_kwargs):
736
+ """Equivalent of builtin `zip`."""
737
+
738
+ def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):
739
+ """Equivalent of builtin `map`."""
740
+
741
+ Submodules
742
+ ~~~~~~~~~~
743
+
744
+ .. code:: python
745
+
746
+ class tqdm.notebook.tqdm(tqdm.tqdm):
747
+ """IPython/Jupyter Notebook widget."""
748
+
749
+ class tqdm.auto.tqdm(tqdm.tqdm):
750
+ """Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`."""
751
+
752
+ class tqdm.asyncio.tqdm(tqdm.tqdm):
753
+ """Asynchronous version."""
754
+ @classmethod
755
+ def as_completed(cls, fs, *, loop=None, timeout=None, total=None,
756
+ **tqdm_kwargs):
757
+ """Wrapper for `asyncio.as_completed`."""
758
+
759
+ class tqdm.gui.tqdm(tqdm.tqdm):
760
+ """Matplotlib GUI version."""
761
+
762
+ class tqdm.tk.tqdm(tqdm.tqdm):
763
+ """Tkinter GUI version."""
764
+
765
+ class tqdm.rich.tqdm(tqdm.tqdm):
766
+ """`rich.progress` version."""
767
+
768
+ class tqdm.keras.TqdmCallback(keras.callbacks.Callback):
769
+ """Keras callback for epoch and batch progress."""
770
+
771
+ class tqdm.dask.TqdmCallback(dask.callbacks.Callback):
772
+ """Dask callback for task progress."""
773
+
774
+
775
+ ``contrib``
776
+ +++++++++++
777
+
778
+ The ``tqdm.contrib`` package also contains experimental modules:
779
+
780
+ - ``tqdm.contrib.itertools``: Thin wrappers around ``itertools``
781
+ - ``tqdm.contrib.concurrent``: Thin wrappers around ``concurrent.futures``
782
+ - ``tqdm.contrib.slack``: Posts to `Slack <https://slack.com>`__ bots
783
+ - ``tqdm.contrib.discord``: Posts to `Discord <https://discord.com>`__ bots
784
+ - ``tqdm.contrib.telegram``: Posts to `Telegram <https://telegram.org>`__ bots
785
+ - ``tqdm.contrib.bells``: Automagically enables all optional features
786
+
787
+ * ``auto``, ``pandas``, ``slack``, ``discord``, ``telegram``
788
+
789
+ Examples and Advanced Usage
790
+ ---------------------------
791
+
792
+ - See the `examples <https://github.com/tqdm/tqdm/tree/master/examples>`__
793
+ folder;
794
+ - import the module and run ``help()``;
795
+ - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__;
796
+
797
+ * this has an
798
+ `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__
799
+ on how to make a **great** progressbar;
800
+
801
+ - check out the `slides from PyData London <https://tqdm.github.io/PyData2019/slides.html>`__, or
802
+ - run the |binder-demo|.
803
+
804
+ Description and additional stats
805
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
806
+
807
+ Custom information can be displayed and updated dynamically on ``tqdm`` bars
808
+ with the ``desc`` and ``postfix`` arguments:
809
+
810
+ .. code:: python
811
+
812
+ from tqdm import tqdm, trange
813
+ from random import random, randint
814
+ from time import sleep
815
+
816
+ with trange(10) as t:
817
+ for i in t:
818
+ # Description will be displayed on the left
819
+ t.set_description('GEN %i' % i)
820
+ # Postfix will be displayed on the right,
821
+ # formatted automatically based on argument's datatype
822
+ t.set_postfix(loss=random(), gen=randint(1,999), str='h',
823
+ lst=[1, 2])
824
+ sleep(0.1)
825
+
826
+ with tqdm(total=10, bar_format="{postfix[0]} {postfix[1][value]:>8.2g}",
827
+ postfix=["Batch", {"value": 0}]) as t:
828
+ for i in range(10):
829
+ sleep(0.1)
830
+ t.postfix[1]["value"] = i / 2
831
+ t.update()
832
+
833
+ Points to remember when using ``{postfix[...]}`` in the ``bar_format`` string:
834
+
835
+ - ``postfix`` also needs to be passed as an initial argument in a compatible
836
+ format, and
837
+ - ``postfix`` will be auto-converted to a string if it is a ``dict``-like
838
+ object. To prevent this behaviour, insert an extra item into the dictionary
839
+ where the key is not a string.
840
+
841
+ Additional ``bar_format`` parameters may also be defined by overriding
842
+ ``format_dict``, and the bar itself may be modified using ``ascii``:
843
+
844
+ .. code:: python
845
+
846
+ from tqdm import tqdm
847
+ class TqdmExtraFormat(tqdm):
848
+ """Provides a `total_time` format parameter"""
849
+ @property
850
+ def format_dict(self):
851
+ d = super().format_dict
852
+ total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
853
+ d.update(total_time=self.format_interval(total_time) + " in total")
854
+ return d
855
+
856
+ for i in TqdmExtraFormat(
857
+ range(9), ascii=" .oO0",
858
+ bar_format="{total_time}: {percentage:.0f}%|{bar}{r_bar}"):
859
+ if i == 4:
860
+ break
861
+
862
+ .. code::
863
+
864
+ 00:00 in total: 44%|0000. | 4/9 [00:00<00:00, 962.93it/s]
865
+
866
+ Note that ``{bar}`` also supports a format specifier ``[width][type]``.
867
+
868
+ - ``width``
869
+
870
+ * unspecified (default): automatic to fill ``ncols``
871
+ * ``int >= 0``: fixed width overriding ``ncols`` logic
872
+ * ``int < 0``: subtract from the automatic default
873
+
874
+ - ``type``
875
+
876
+ * ``a``: ascii (``ascii=True`` override)
877
+ * ``u``: unicode (``ascii=False`` override)
878
+ * ``b``: blank (``ascii=" "`` override)
879
+
880
+ This means a fixed bar with right-justified text may be created by using:
881
+ ``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"``
882
+
883
+ Nested progress bars
884
+ ~~~~~~~~~~~~~~~~~~~~
885
+
886
+ ``tqdm`` supports nested progress bars. Here's an example:
887
+
888
+ .. code:: python
889
+
890
+ from tqdm.auto import trange
891
+ from time import sleep
892
+
893
+ for i in trange(4, desc='1st loop'):
894
+ for j in trange(5, desc='2nd loop'):
895
+ for k in trange(50, desc='3rd loop', leave=False):
896
+ sleep(0.01)
897
+
898
+ For manual control over positioning (e.g. for multi-processing use),
899
+ you may specify ``position=n`` where ``n=0`` for the outermost bar,
900
+ ``n=1`` for the next, and so on.
901
+ However, it's best to check if ``tqdm`` can work without manual ``position``
902
+ first.
903
+
904
+ .. code:: python
905
+
906
+ from time import sleep
907
+ from tqdm import trange, tqdm
908
+ from multiprocessing import Pool, RLock, freeze_support
909
+
910
+ L = list(range(9))
911
+
912
+ def progresser(n):
913
+ interval = 0.001 / (n + 2)
914
+ total = 5000
915
+ text = f"#{n}, est. {interval * total:<04.2}s"
916
+ for _ in trange(total, desc=text, position=n):
917
+ sleep(interval)
918
+
919
+ if __name__ == '__main__':
920
+ freeze_support() # for Windows support
921
+ tqdm.set_lock(RLock()) # for managing output contention
922
+ p = Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),))
923
+ p.map(progresser, L)
924
+
925
+ Note that in Python 3, ``tqdm.write`` is thread-safe:
926
+
927
+ .. code:: python
928
+
929
+ from time import sleep
930
+ from tqdm import tqdm, trange
931
+ from concurrent.futures import ThreadPoolExecutor
932
+
933
+ L = list(range(9))
934
+
935
+ def progresser(n):
936
+ interval = 0.001 / (n + 2)
937
+ total = 5000
938
+ text = f"#{n}, est. {interval * total:<04.2}s"
939
+ for _ in trange(total, desc=text):
940
+ sleep(interval)
941
+ if n == 6:
942
+ tqdm.write("n == 6 completed.")
943
+ tqdm.write("`tqdm.write()` is thread-safe in py3!")
944
+
945
+ if __name__ == '__main__':
946
+ with ThreadPoolExecutor() as p:
947
+ p.map(progresser, L)
948
+
949
+ Hooks and callbacks
950
+ ~~~~~~~~~~~~~~~~~~~
951
+
952
+ ``tqdm`` can easily support callbacks/hooks and manual updates.
953
+ Here's an example with ``urllib``:
954
+
955
+ **``urllib.urlretrieve`` documentation**
956
+
957
+ | [...]
958
+ | If present, the hook function will be called once
959
+ | on establishment of the network connection and once after each block read
960
+ | thereafter. The hook will be passed three arguments; a count of blocks
961
+ | transferred so far, a block size in bytes, and the total size of the file.
962
+ | [...]
963
+
964
+ .. code:: python
965
+
966
+ import urllib, os
967
+ from tqdm import tqdm
968
+ urllib = getattr(urllib, 'request', urllib)
969
+
970
+ class TqdmUpTo(tqdm):
971
+ """Provides `update_to(n)` which uses `tqdm.update(delta_n)`."""
972
+ def update_to(self, b=1, bsize=1, tsize=None):
973
+ """
974
+ b : int, optional
975
+ Number of blocks transferred so far [default: 1].
976
+ bsize : int, optional
977
+ Size of each block (in tqdm units) [default: 1].
978
+ tsize : int, optional
979
+ Total size (in tqdm units). If [default: None] remains unchanged.
980
+ """
981
+ if tsize is not None:
982
+ self.total = tsize
983
+ return self.update(b * bsize - self.n) # also sets self.n = b * bsize
984
+
985
+ eg_link = "https://caspersci.uk.to/matryoshka.zip"
986
+ with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
987
+ desc=eg_link.split('/')[-1]) as t: # all optional kwargs
988
+ urllib.urlretrieve(eg_link, filename=os.devnull,
989
+ reporthook=t.update_to, data=None)
990
+ t.total = t.n
991
+
992
+ Inspired by `twine#242 <https://github.com/pypa/twine/pull/242>`__.
993
+ Functional alternative in
994
+ `examples/tqdm_wget.py <https://github.com/tqdm/tqdm/blob/master/examples/tqdm_wget.py>`__.
995
+
996
+ It is recommend to use ``miniters=1`` whenever there is potentially
997
+ large differences in iteration speed (e.g. downloading a file over
998
+ a patchy connection).
999
+
1000
+ **Wrapping read/write methods**
1001
+
1002
+ To measure throughput through a file-like object's ``read`` or ``write``
1003
+ methods, use ``CallbackIOWrapper``:
1004
+
1005
+ .. code:: python
1006
+
1007
+ from tqdm.auto import tqdm
1008
+ from tqdm.utils import CallbackIOWrapper
1009
+
1010
+ with tqdm(total=file_obj.size,
1011
+ unit='B', unit_scale=True, unit_divisor=1024) as t:
1012
+ fobj = CallbackIOWrapper(t.update, file_obj, "read")
1013
+ while True:
1014
+ chunk = fobj.read(chunk_size)
1015
+ if not chunk:
1016
+ break
1017
+ t.reset()
1018
+ # ... continue to use `t` for something else
1019
+
1020
+ Alternatively, use the even simpler ``wrapattr`` convenience function,
1021
+ which would condense both the ``urllib`` and ``CallbackIOWrapper`` examples
1022
+ down to:
1023
+
1024
+ .. code:: python
1025
+
1026
+ import urllib, os
1027
+ from tqdm import tqdm
1028
+
1029
+ eg_link = "https://caspersci.uk.to/matryoshka.zip"
1030
+ response = getattr(urllib, 'request', urllib).urlopen(eg_link)
1031
+ with tqdm.wrapattr(open(os.devnull, "wb"), "write",
1032
+ miniters=1, desc=eg_link.split('/')[-1],
1033
+ total=getattr(response, 'length', None)) as fout:
1034
+ for chunk in response:
1035
+ fout.write(chunk)
1036
+
1037
+ The ``requests`` equivalent is nearly identical:
1038
+
1039
+ .. code:: python
1040
+
1041
+ import requests, os
1042
+ from tqdm import tqdm
1043
+
1044
+ eg_link = "https://caspersci.uk.to/matryoshka.zip"
1045
+ response = requests.get(eg_link, stream=True)
1046
+ with tqdm.wrapattr(open(os.devnull, "wb"), "write",
1047
+ miniters=1, desc=eg_link.split('/')[-1],
1048
+ total=int(response.headers.get('content-length', 0))) as fout:
1049
+ for chunk in response.iter_content(chunk_size=4096):
1050
+ fout.write(chunk)
1051
+
1052
+ **Custom callback**
1053
+
1054
+ ``tqdm`` is known for intelligently skipping unnecessary displays. To make a
1055
+ custom callback take advantage of this, simply use the return value of
1056
+ ``update()``. This is set to ``True`` if a ``display()`` was triggered.
1057
+
1058
+ .. code:: python
1059
+
1060
+ from tqdm.auto import tqdm as std_tqdm
1061
+
1062
+ def external_callback(*args, **kwargs):
1063
+ ...
1064
+
1065
+ class TqdmExt(std_tqdm):
1066
+ def update(self, n=1):
1067
+ displayed = super().update(n)
1068
+ if displayed:
1069
+ external_callback(**self.format_dict)
1070
+ return displayed
1071
+
1072
+ ``asyncio``
1073
+ ~~~~~~~~~~~
1074
+
1075
+ Note that ``break`` isn't currently caught by asynchronous iterators.
1076
+ This means that ``tqdm`` cannot clean up after itself in this case:
1077
+
1078
+ .. code:: python
1079
+
1080
+ from tqdm.asyncio import tqdm
1081
+
1082
+ async for i in tqdm(range(9)):
1083
+ if i == 2:
1084
+ break
1085
+
1086
+ Instead, either call ``pbar.close()`` manually or use the context manager syntax:
1087
+
1088
+ .. code:: python
1089
+
1090
+ from tqdm.asyncio import tqdm
1091
+
1092
+ with tqdm(range(9)) as pbar:
1093
+ async for i in pbar:
1094
+ if i == 2:
1095
+ break
1096
+
1097
+ Pandas Integration
1098
+ ~~~~~~~~~~~~~~~~~~
1099
+
1100
+ Due to popular demand we've added support for ``pandas`` -- here's an example
1101
+ for ``DataFrame.progress_apply`` and ``DataFrameGroupBy.progress_apply``:
1102
+
1103
+ .. code:: python
1104
+
1105
+ import pandas as pd
1106
+ import numpy as np
1107
+ from tqdm import tqdm
1108
+
1109
+ df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))
1110
+
1111
+ # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm`
1112
+ # (can use `tqdm.gui.tqdm`, `tqdm.notebook.tqdm`, optional kwargs, etc.)
1113
+ tqdm.pandas(desc="my bar!")
1114
+
1115
+ # Now you can use `progress_apply` instead of `apply`
1116
+ # and `progress_map` instead of `map`
1117
+ df.progress_apply(lambda x: x**2)
1118
+ # can also groupby:
1119
+ # df.groupby(0).progress_apply(lambda x: x**2)
1120
+
1121
+ In case you're interested in how this works (and how to modify it for your
1122
+ own callbacks), see the
1123
+ `examples <https://github.com/tqdm/tqdm/tree/master/examples>`__
1124
+ folder or import the module and run ``help()``.
1125
+
1126
+ Keras Integration
1127
+ ~~~~~~~~~~~~~~~~~
1128
+
1129
+ A ``keras`` callback is also available:
1130
+
1131
+ .. code:: python
1132
+
1133
+ from tqdm.keras import TqdmCallback
1134
+
1135
+ ...
1136
+
1137
+ model.fit(..., verbose=0, callbacks=[TqdmCallback()])
1138
+
1139
+ Dask Integration
1140
+ ~~~~~~~~~~~~~~~~
1141
+
1142
+ A ``dask`` callback is also available:
1143
+
1144
+ .. code:: python
1145
+
1146
+ from tqdm.dask import TqdmCallback
1147
+
1148
+ with TqdmCallback(desc="compute"):
1149
+ ...
1150
+ arr.compute()
1151
+
1152
+ # or use callback globally
1153
+ cb = TqdmCallback(desc="global")
1154
+ cb.register()
1155
+ arr.compute()
1156
+
1157
+ IPython/Jupyter Integration
1158
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1159
+
1160
+ IPython/Jupyter is supported via the ``tqdm.notebook`` submodule:
1161
+
1162
+ .. code:: python
1163
+
1164
+ from tqdm.notebook import trange, tqdm
1165
+ from time import sleep
1166
+
1167
+ for i in trange(3, desc='1st loop'):
1168
+ for j in tqdm(range(100), desc='2nd loop'):
1169
+ sleep(0.01)
1170
+
1171
+ In addition to ``tqdm`` features, the submodule provides a native Jupyter
1172
+ widget (compatible with IPython v1-v4 and Jupyter), fully working nested bars
1173
+ and colour hints (blue: normal, green: completed, red: error/interrupt,
1174
+ light blue: no ETA); as demonstrated below.
1175
+
1176
+ |Screenshot-Jupyter1|
1177
+ |Screenshot-Jupyter2|
1178
+ |Screenshot-Jupyter3|
1179
+
1180
+ The ``notebook`` version supports percentage or pixels for overall width
1181
+ (e.g.: ``ncols='100%'`` or ``ncols='480px'``).
1182
+
1183
+ It is also possible to let ``tqdm`` automatically choose between
1184
+ console or notebook versions by using the ``autonotebook`` submodule:
1185
+
1186
+ .. code:: python
1187
+
1188
+ from tqdm.autonotebook import tqdm
1189
+ tqdm.pandas()
1190
+
1191
+ Note that this will issue a ``TqdmExperimentalWarning`` if run in a notebook
1192
+ since it is not meant to be possible to distinguish between ``jupyter notebook``
1193
+ and ``jupyter console``. Use ``auto`` instead of ``autonotebook`` to suppress
1194
+ this warning.
1195
+
1196
+ Note that notebooks will display the bar in the cell where it was created.
1197
+ This may be a different cell from the one where it is used.
1198
+ If this is not desired, either
1199
+
1200
+ - delay the creation of the bar to the cell where it must be displayed, or
1201
+ - create the bar with ``display=False``, and in a later cell call
1202
+ ``display(bar.container)``:
1203
+
1204
+ .. code:: python
1205
+
1206
+ from tqdm.notebook import tqdm
1207
+ pbar = tqdm(..., display=False)
1208
+
1209
+ .. code:: python
1210
+
1211
+ # different cell
1212
+ display(pbar.container)
1213
+
1214
+ The ``keras`` callback has a ``display()`` method which can be used likewise:
1215
+
1216
+ .. code:: python
1217
+
1218
+ from tqdm.keras import TqdmCallback
1219
+ cbk = TqdmCallback(display=False)
1220
+
1221
+ .. code:: python
1222
+
1223
+ # different cell
1224
+ cbk.display()
1225
+ model.fit(..., verbose=0, callbacks=[cbk])
1226
+
1227
+ Another possibility is to have a single bar (near the top of the notebook)
1228
+ which is constantly re-used (using ``reset()`` rather than ``close()``).
1229
+ For this reason, the notebook version (unlike the CLI version) does not
1230
+ automatically call ``close()`` upon ``Exception``.
1231
+
1232
+ .. code:: python
1233
+
1234
+ from tqdm.notebook import tqdm
1235
+ pbar = tqdm()
1236
+
1237
+ .. code:: python
1238
+
1239
+ # different cell
1240
+ iterable = range(100)
1241
+ pbar.reset(total=len(iterable)) # initialise with new `total`
1242
+ for i in iterable:
1243
+ pbar.update()
1244
+ pbar.refresh() # force print final status but don't `close()`
1245
+
1246
+ Custom Integration
1247
+ ~~~~~~~~~~~~~~~~~~
1248
+
1249
+ To change the default arguments (such as making ``dynamic_ncols=True``),
1250
+ simply use built-in Python magic:
1251
+
1252
+ .. code:: python
1253
+
1254
+ from functools import partial
1255
+ from tqdm import tqdm as std_tqdm
1256
+ tqdm = partial(std_tqdm, dynamic_ncols=True)
1257
+
1258
+ For further customisation,
1259
+ ``tqdm`` may be inherited from to create custom callbacks (as with the
1260
+ ``TqdmUpTo`` example `above <#hooks-and-callbacks>`__) or for custom frontends
1261
+ (e.g. GUIs such as notebook or plotting packages). In the latter case:
1262
+
1263
+ 1. ``def __init__()`` to call ``super().__init__(..., gui=True)`` to disable
1264
+ terminal ``status_printer`` creation.
1265
+ 2. Redefine: ``close()``, ``clear()``, ``display()``.
1266
+
1267
+ Consider overloading ``display()`` to use e.g.
1268
+ ``self.frontend(**self.format_dict)`` instead of ``self.sp(repr(self))``.
1269
+
1270
+ Some submodule examples of inheritance:
1271
+
1272
+ - `tqdm/notebook.py <https://github.com/tqdm/tqdm/blob/master/tqdm/notebook.py>`__
1273
+ - `tqdm/gui.py <https://github.com/tqdm/tqdm/blob/master/tqdm/gui.py>`__
1274
+ - `tqdm/tk.py <https://github.com/tqdm/tqdm/blob/master/tqdm/tk.py>`__
1275
+ - `tqdm/contrib/slack.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/slack.py>`__
1276
+ - `tqdm/contrib/discord.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/discord.py>`__
1277
+ - `tqdm/contrib/telegram.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/telegram.py>`__
1278
+
1279
+ Dynamic Monitor/Meter
1280
+ ~~~~~~~~~~~~~~~~~~~~~
1281
+
1282
+ You can use a ``tqdm`` as a meter which is not monotonically increasing.
1283
+ This could be because ``n`` decreases (e.g. a CPU usage monitor) or ``total``
1284
+ changes.
1285
+
1286
+ One example would be recursively searching for files. The ``total`` is the
1287
+ number of objects found so far, while ``n`` is the number of those objects which
1288
+ are files (rather than folders):
1289
+
1290
+ .. code:: python
1291
+
1292
+ from tqdm import tqdm
1293
+ import os.path
1294
+
1295
+ def find_files_recursively(path, show_progress=True):
1296
+ files = []
1297
+ # total=1 assumes `path` is a file
1298
+ t = tqdm(total=1, unit="file", disable=not show_progress)
1299
+ if not os.path.exists(path):
1300
+ raise IOError("Cannot find:" + path)
1301
+
1302
+ def append_found_file(f):
1303
+ files.append(f)
1304
+ t.update()
1305
+
1306
+ def list_found_dir(path):
1307
+ """returns os.listdir(path) assuming os.path.isdir(path)"""
1308
+ listing = os.listdir(path)
1309
+ # subtract 1 since a "file" we found was actually this directory
1310
+ t.total += len(listing) - 1
1311
+ # fancy way to give info without forcing a refresh
1312
+ t.set_postfix(dir=path[-10:], refresh=False)
1313
+ t.update(0) # may trigger a refresh
1314
+ return listing
1315
+
1316
+ def recursively_search(path):
1317
+ if os.path.isdir(path):
1318
+ for f in list_found_dir(path):
1319
+ recursively_search(os.path.join(path, f))
1320
+ else:
1321
+ append_found_file(path)
1322
+
1323
+ recursively_search(path)
1324
+ t.set_postfix(dir=path)
1325
+ t.close()
1326
+ return files
1327
+
1328
+ Using ``update(0)`` is a handy way to let ``tqdm`` decide when to trigger a
1329
+ display refresh to avoid console spamming.
1330
+
1331
+ Writing messages
1332
+ ~~~~~~~~~~~~~~~~
1333
+
1334
+ This is a work in progress (see
1335
+ `#737 <https://github.com/tqdm/tqdm/issues/737>`__).
1336
+
1337
+ Since ``tqdm`` uses a simple printing mechanism to display progress bars,
1338
+ you should not write any message in the terminal using ``print()`` while
1339
+ a progressbar is open.
1340
+
1341
+ To write messages in the terminal without any collision with ``tqdm`` bar
1342
+ display, a ``.write()`` method is provided:
1343
+
1344
+ .. code:: python
1345
+
1346
+ from tqdm.auto import tqdm, trange
1347
+ from time import sleep
1348
+
1349
+ bar = trange(10)
1350
+ for i in bar:
1351
+ # Print using tqdm class method .write()
1352
+ sleep(0.1)
1353
+ if not (i % 3):
1354
+ tqdm.write("Done task %i" % i)
1355
+ # Can also use bar.write()
1356
+
1357
+ By default, this will print to standard output ``sys.stdout``. but you can
1358
+ specify any file-like object using the ``file`` argument. For example, this
1359
+ can be used to redirect the messages writing to a log file or class.
1360
+
1361
+ Redirecting writing
1362
+ ~~~~~~~~~~~~~~~~~~~
1363
+
1364
+ If using a library that can print messages to the console, editing the library
1365
+ by replacing ``print()`` with ``tqdm.write()`` may not be desirable.
1366
+ In that case, redirecting ``sys.stdout`` to ``tqdm.write()`` is an option.
1367
+
1368
+ To redirect ``sys.stdout``, create a file-like class that will write
1369
+ any input string to ``tqdm.write()``, and supply the arguments
1370
+ ``file=sys.stdout, dynamic_ncols=True``.
1371
+
1372
+ A reusable canonical example is given below:
1373
+
1374
+ .. code:: python
1375
+
1376
+ from time import sleep
1377
+ import contextlib
1378
+ import sys
1379
+ from tqdm import tqdm
1380
+ from tqdm.contrib import DummyTqdmFile
1381
+
1382
+
1383
+ @contextlib.contextmanager
1384
+ def std_out_err_redirect_tqdm():
1385
+ orig_out_err = sys.stdout, sys.stderr
1386
+ try:
1387
+ sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err)
1388
+ yield orig_out_err[0]
1389
+ # Relay exceptions
1390
+ except Exception as exc:
1391
+ raise exc
1392
+ # Always restore sys.stdout/err if necessary
1393
+ finally:
1394
+ sys.stdout, sys.stderr = orig_out_err
1395
+
1396
+ def some_fun(i):
1397
+ print("Fee, fi, fo,".split()[i])
1398
+
1399
+ # Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)
1400
+ with std_out_err_redirect_tqdm() as orig_stdout:
1401
+ # tqdm needs the original stdout
1402
+ # and dynamic_ncols=True to autodetect console width
1403
+ for i in tqdm(range(3), file=orig_stdout, dynamic_ncols=True):
1404
+ sleep(.5)
1405
+ some_fun(i)
1406
+
1407
+ # After the `with`, printing is restored
1408
+ print("Done!")
1409
+
1410
+ Redirecting ``logging``
1411
+ ~~~~~~~~~~~~~~~~~~~~~~~
1412
+
1413
+ Similar to ``sys.stdout``/``sys.stderr`` as detailed above, console ``logging``
1414
+ may also be redirected to ``tqdm.write()``.
1415
+
1416
+ Warning: if also redirecting ``sys.stdout``/``sys.stderr``, make sure to
1417
+ redirect ``logging`` first if needed.
1418
+
1419
+ Helper methods are available in ``tqdm.contrib.logging``. For example:
1420
+
1421
+ .. code:: python
1422
+
1423
+ import logging
1424
+ from tqdm import trange
1425
+ from tqdm.contrib.logging import logging_redirect_tqdm
1426
+
1427
+ LOG = logging.getLogger(__name__)
1428
+
1429
+ if __name__ == '__main__':
1430
+ logging.basicConfig(level=logging.INFO)
1431
+ with logging_redirect_tqdm():
1432
+ for i in trange(9):
1433
+ if i == 4:
1434
+ LOG.info("console logging redirected to `tqdm.write()`")
1435
+ # logging restored
1436
+
1437
+ Monitoring thread, intervals and miniters
1438
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1439
+
1440
+ ``tqdm`` implements a few tricks to increase efficiency and reduce overhead.
1441
+
1442
+ - Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long
1443
+ to wait between each refresh. ``tqdm`` always gets updated in the background,
1444
+ but it will display only every ``mininterval``.
1445
+ - Reduce number of calls to check system clock/time.
1446
+ - ``mininterval`` is more intuitive to configure than ``miniters``.
1447
+ A clever adjustment system ``dynamic_miniters`` will automatically adjust
1448
+ ``miniters`` to the amount of iterations that fit into time ``mininterval``.
1449
+ Essentially, ``tqdm`` will check if it's time to print without actually
1450
+ checking time. This behaviour can be still be bypassed by manually setting
1451
+ ``miniters``.
1452
+
1453
+ However, consider a case with a combination of fast and slow iterations.
1454
+ After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a
1455
+ large number. When iteration rate subsequently slows, ``miniters`` will
1456
+ remain large and thus reduce display update frequency. To address this:
1457
+
1458
+ - ``maxinterval`` defines the maximum time between display refreshes.
1459
+ A concurrent monitoring thread checks for overdue updates and forces one
1460
+ where necessary.
1461
+
1462
+ The monitoring thread should not have a noticeable overhead, and guarantees
1463
+ updates at least every 10 seconds by default.
1464
+ This value can be directly changed by setting the ``monitor_interval`` of
1465
+ any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).
1466
+ The monitor thread may be disabled application-wide by setting
1467
+ ``tqdm.tqdm.monitor_interval = 0`` before instantiation of any ``tqdm`` bar.
1468
+
1469
+
1470
+ Merch
1471
+ -----
1472
+
1473
+ You can buy `tqdm branded merch <https://tqdm.github.io/merch>`__ now!
1474
+
1475
+ Contributions
1476
+ -------------
1477
+
1478
+ |GitHub-Commits| |GitHub-Issues| |GitHub-PRs| |OpenHub-Status| |GitHub-Contributions| |CII Best Practices|
1479
+
1480
+ All source code is hosted on `GitHub <https://github.com/tqdm/tqdm>`__.
1481
+ Contributions are welcome.
1482
+
1483
+ See the
1484
+ `CONTRIBUTING <https://github.com/tqdm/tqdm/blob/master/CONTRIBUTING.md>`__
1485
+ file for more information.
1486
+
1487
+ Developers who have made significant contributions, ranked by *SLoC*
1488
+ (surviving lines of code,
1489
+ `git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC --excl '\.(png|gif|jpg)$'``),
1490
+ are:
1491
+
1492
+ ==================== ======================================================== ==== ================================
1493
+ Name ID SLoC Notes
1494
+ ==================== ======================================================== ==== ================================
1495
+ Casper da Costa-Luis `casperdcl <https://github.com/casperdcl>`__ ~80% primary maintainer |Gift-Casper|
1496
+ Stephen Larroque `lrq3000 <https://github.com/lrq3000>`__ ~9% team member
1497
+ Martin Zugnoni `martinzugnoni <https://github.com/martinzugnoni>`__ ~3%
1498
+ Daniel Ecer `de-code <https://github.com/de-code>`__ ~2%
1499
+ Richard Sheridan `richardsheridan <https://github.com/richardsheridan>`__ ~1%
1500
+ Guangshuo Chen `chengs <https://github.com/chengs>`__ ~1%
1501
+ Helio Machado `0x2b3bfa0 <https://github.com/0x2b3bfa0>`__ ~1%
1502
+ Kyle Altendorf `altendky <https://github.com/altendky>`__ <1%
1503
+ Noam Yorav-Raphael `noamraph <https://github.com/noamraph>`__ <1% original author
1504
+ Matthew Stevens `mjstevens777 <https://github.com/mjstevens777>`__ <1%
1505
+ Hadrien Mary `hadim <https://github.com/hadim>`__ <1% team member
1506
+ Mikhail Korobov `kmike <https://github.com/kmike>`__ <1% team member
1507
+ ==================== ======================================================== ==== ================================
1508
+
1509
+ Ports to Other Languages
1510
+ ~~~~~~~~~~~~~~~~~~~~~~~~
1511
+
1512
+ A list is available on
1513
+ `this wiki page <https://github.com/tqdm/tqdm/wiki/tqdm-ports>`__.
1514
+
1515
+
1516
+ LICENCE
1517
+ -------
1518
+
1519
+ Open Source (OSI approved): |LICENCE|
1520
+
1521
+ Citation information: |DOI|
1522
+
1523
+ |README-Hits| (Since 19 May 2016)
1524
+
1525
+ .. |Logo| image:: https://tqdm.github.io/img/logo.gif
1526
+ .. |Screenshot| image:: https://tqdm.github.io/img/tqdm.gif
1527
+ .. |Video| image:: https://tqdm.github.io/img/video.jpg
1528
+ :target: https://tqdm.github.io/video
1529
+ .. |Slides| image:: https://tqdm.github.io/img/slides.jpg
1530
+ :target: https://tqdm.github.io/PyData2019/slides.html
1531
+ .. |Merch| image:: https://tqdm.github.io/img/merch.jpg
1532
+ :target: https://tqdm.github.io/merch
1533
+ .. |Build-Status| image:: https://img.shields.io/github/actions/workflow/status/tqdm/tqdm/test.yml?branch=master&label=tqdm&logo=GitHub
1534
+ :target: https://github.com/tqdm/tqdm/actions/workflows/test.yml
1535
+ .. |Coverage-Status| image:: https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls
1536
+ :target: https://coveralls.io/github/tqdm/tqdm
1537
+ .. |Branch-Coverage-Status| image:: https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg
1538
+ :target: https://codecov.io/gh/tqdm/tqdm
1539
+ .. |Codacy-Grade| image:: https://app.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177
1540
+ :target: https://www.codacy.com/gh/tqdm/tqdm/dashboard
1541
+ .. |CII Best Practices| image:: https://bestpractices.coreinfrastructure.org/projects/3264/badge
1542
+ :target: https://bestpractices.coreinfrastructure.org/projects/3264
1543
+ .. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=86400&logo=github&logoColor=white
1544
+ :target: https://github.com/tqdm/tqdm/releases
1545
+ .. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg?logo=github&logoColor=white
1546
+ :target: https://github.com/tqdm/tqdm/network
1547
+ .. |GitHub-Stars| image:: https://img.shields.io/github/stars/tqdm/tqdm.svg?logo=github&logoColor=white
1548
+ :target: https://github.com/tqdm/tqdm/stargazers
1549
+ .. |GitHub-Commits| image:: https://img.shields.io/github/commit-activity/y/tqdm/tqdm.svg?logo=git&logoColor=white
1550
+ :target: https://github.com/tqdm/tqdm/graphs/commit-activity
1551
+ .. |GitHub-Issues| image:: https://img.shields.io/github/issues-closed/tqdm/tqdm.svg?logo=github&logoColor=white
1552
+ :target: https://github.com/tqdm/tqdm/issues?q=
1553
+ .. |GitHub-PRs| image:: https://img.shields.io/github/issues-pr-closed/tqdm/tqdm.svg?logo=github&logoColor=white
1554
+ :target: https://github.com/tqdm/tqdm/pulls
1555
+ .. |GitHub-Contributions| image:: https://img.shields.io/github/contributors/tqdm/tqdm.svg?logo=github&logoColor=white
1556
+ :target: https://github.com/tqdm/tqdm/graphs/contributors
1557
+ .. |GitHub-Updated| image:: https://img.shields.io/github/last-commit/tqdm/tqdm/master.svg?logo=github&logoColor=white&label=pushed
1558
+ :target: https://github.com/tqdm/tqdm/pulse
1559
+ .. |Gift-Casper| image:: https://img.shields.io/badge/dynamic/json.svg?color=ff69b4&label=gifts%20received&prefix=%C2%A3&query=%24..sum&url=https%3A%2F%2Fcaspersci.uk.to%2Fgifts.json
1560
+ :target: https://cdcl.ml/sponsor
1561
+ .. |Versions| image:: https://img.shields.io/pypi/v/tqdm.svg
1562
+ :target: https://tqdm.github.io/releases
1563
+ .. |PyPI-Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white
1564
+ :target: https://pepy.tech/project/tqdm
1565
+ .. |Py-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg?logo=python&logoColor=white
1566
+ :target: https://pypi.org/project/tqdm
1567
+ .. |Conda-Forge-Status| image:: https://img.shields.io/conda/v/conda-forge/tqdm.svg?label=conda-forge&logo=conda-forge
1568
+ :target: https://anaconda.org/conda-forge/tqdm
1569
+ .. |Snapcraft| image:: https://img.shields.io/badge/snap-install-82BEA0.svg?logo=snapcraft
1570
+ :target: https://snapcraft.io/tqdm
1571
+ .. |Docker| image:: https://img.shields.io/badge/docker-pull-blue.svg?logo=docker&logoColor=white
1572
+ :target: https://hub.docker.com/r/tqdm/tqdm
1573
+ .. |Libraries-Rank| image:: https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white
1574
+ :target: https://libraries.io/pypi/tqdm
1575
+ .. |Libraries-Dependents| image:: https://img.shields.io/librariesio/dependent-repos/pypi/tqdm.svg?logo=koding&logoColor=white
1576
+ :target: https://github.com/tqdm/tqdm/network/dependents
1577
+ .. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif
1578
+ :target: https://www.openhub.net/p/tqdm?ref=Thin+badge
1579
+ .. |awesome-python| image:: https://awesome.re/mentioned-badge.svg
1580
+ :target: https://github.com/vinta/awesome-python
1581
+ .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg
1582
+ :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE
1583
+ .. |DOI| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.595120-blue.svg
1584
+ :target: https://doi.org/10.5281/zenodo.595120
1585
+ .. |binder-demo| image:: https://mybinder.org/badge_logo.svg
1586
+ :target: https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb
1587
+ .. |Screenshot-Jupyter1| image:: https://tqdm.github.io/img/jupyter-1.gif
1588
+ .. |Screenshot-Jupyter2| image:: https://tqdm.github.io/img/jupyter-2.gif
1589
+ .. |Screenshot-Jupyter3| image:: https://tqdm.github.io/img/jupyter-3.gif
1590
+ .. |README-Hits| image:: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif
1591
+ :target: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social
.cache/pip/http-v2/f/c/a/5/b/fca5b18fd877930924e4c3ed44a7de4862861d131c1248697b107213 ADDED
Binary file (1.16 kB). View file
 
.cache/pip/http-v2/f/c/a/5/b/fca5b18fd877930924e4c3ed44a7de4862861d131c1248697b107213.body ADDED
@@ -0,0 +1,420 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: frozenlist
3
+ Version: 1.4.1
4
+ Summary: A list-like structure which implements collections.abc.MutableSequence
5
+ Home-page: https://github.com/aio-libs/frozenlist
6
+ Maintainer: aiohttp team <[email protected]>
7
+ Maintainer-email: [email protected]
8
+ License: Apache 2
9
+ Project-URL: Chat: Matrix, https://matrix.to/#/#aio-libs:matrix.org
10
+ Project-URL: Chat: Matrix Space, https://matrix.to/#/#aio-libs-space:matrix.org
11
+ Project-URL: CI: Github Actions, https://github.com/aio-libs/frozenlist/actions
12
+ Project-URL: Code of Conduct, https://github.com/aio-libs/.github/blob/master/CODE_OF_CONDUCT.md
13
+ Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/frozenlist
14
+ Project-URL: Docs: Changelog, https://github.com/aio-libs/frozenlist/blob/master/CHANGES.rst#changelog
15
+ Project-URL: Docs: RTD, https://frozenlist.aio-libs.org
16
+ Project-URL: GitHub: issues, https://github.com/aio-libs/frozenlist/issues
17
+ Project-URL: GitHub: repo, https://github.com/aio-libs/frozenlist
18
+ Classifier: Development Status :: 5 - Production/Stable
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: License :: OSI Approved :: Apache Software License
21
+ Classifier: Operating System :: POSIX
22
+ Classifier: Operating System :: MacOS :: MacOS X
23
+ Classifier: Operating System :: Microsoft :: Windows
24
+ Classifier: Programming Language :: Cython
25
+ Classifier: Programming Language :: Python
26
+ Classifier: Programming Language :: Python :: 3
27
+ Classifier: Programming Language :: Python :: 3.8
28
+ Classifier: Programming Language :: Python :: 3.9
29
+ Classifier: Programming Language :: Python :: 3.10
30
+ Classifier: Programming Language :: Python :: 3.11
31
+ Classifier: Programming Language :: Python :: 3.12
32
+ Classifier: Programming Language :: Python :: Implementation :: CPython
33
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
34
+ Requires-Python: >=3.8
35
+ Description-Content-Type: text/x-rst
36
+ License-File: LICENSE
37
+
38
+ frozenlist
39
+ ==========
40
+
41
+ .. image:: https://github.com/aio-libs/frozenlist/workflows/CI/badge.svg
42
+ :target: https://github.com/aio-libs/frozenlist/actions
43
+ :alt: GitHub status for master branch
44
+
45
+ .. image:: https://codecov.io/gh/aio-libs/frozenlist/branch/master/graph/badge.svg
46
+ :target: https://codecov.io/gh/aio-libs/frozenlist
47
+ :alt: codecov.io status for master branch
48
+
49
+ .. image:: https://img.shields.io/pypi/v/frozenlist.svg?logo=Python&logoColor=white
50
+ :target: https://pypi.org/project/frozenlist
51
+ :alt: frozenlist @ PyPI
52
+
53
+ .. image:: https://readthedocs.org/projects/frozenlist/badge/?version=latest
54
+ :target: https://frozenlist.aio-libs.org
55
+ :alt: Read The Docs build status badge
56
+
57
+ .. image:: https://img.shields.io/matrix/aio-libs:matrix.org?label=Discuss%20on%20Matrix%20at%20%23aio-libs%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat
58
+ :target: https://matrix.to/#/%23aio-libs:matrix.org
59
+ :alt: Matrix Room — #aio-libs:matrix.org
60
+
61
+ .. image:: https://img.shields.io/matrix/aio-libs-space:matrix.org?label=Discuss%20on%20Matrix%20at%20%23aio-libs-space%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat
62
+ :target: https://matrix.to/#/%23aio-libs-space:matrix.org
63
+ :alt: Matrix Space — #aio-libs-space:matrix.org
64
+
65
+ Introduction
66
+ ------------
67
+
68
+ ``frozenlist.FrozenList`` is a list-like structure which implements
69
+ ``collections.abc.MutableSequence``. The list is *mutable* until ``FrozenList.freeze``
70
+ is called, after which list modifications raise ``RuntimeError``:
71
+
72
+
73
+ >>> from frozenlist import FrozenList
74
+ >>> fl = FrozenList([17, 42])
75
+ >>> fl.append('spam')
76
+ >>> fl.append('Vikings')
77
+ >>> fl
78
+ <FrozenList(frozen=False, [17, 42, 'spam', 'Vikings'])>
79
+ >>> fl.freeze()
80
+ >>> fl
81
+ <FrozenList(frozen=True, [17, 42, 'spam', 'Vikings'])>
82
+ >>> fl.frozen
83
+ True
84
+ >>> fl.append("Monty")
85
+ Traceback (most recent call last):
86
+ File "<stdin>", line 1, in <module>
87
+ File "frozenlist/_frozenlist.pyx", line 97, in frozenlist._frozenlist.FrozenList.append
88
+ self._check_frozen()
89
+ File "frozenlist/_frozenlist.pyx", line 19, in frozenlist._frozenlist.FrozenList._check_frozen
90
+ raise RuntimeError("Cannot modify frozen list.")
91
+ RuntimeError: Cannot modify frozen list.
92
+
93
+
94
+ FrozenList is also hashable, but only when frozen. Otherwise it also throws a RuntimeError:
95
+
96
+
97
+ >>> fl = FrozenList([17, 42, 'spam'])
98
+ >>> hash(fl)
99
+ Traceback (most recent call last):
100
+ File "<stdin>", line 1, in <module>
101
+ File "frozenlist/_frozenlist.pyx", line 111, in frozenlist._frozenlist.FrozenList.__hash__
102
+ raise RuntimeError("Cannot hash unfrozen list.")
103
+ RuntimeError: Cannot hash unfrozen list.
104
+ >>> fl.freeze()
105
+ >>> hash(fl)
106
+ 3713081631934410656
107
+ >>> dictionary = {fl: 'Vikings'} # frozen fl can be a dict key
108
+ >>> dictionary
109
+ {<FrozenList(frozen=True, [1, 2])>: 'Vikings'}
110
+
111
+
112
+ Installation
113
+ ------------
114
+
115
+ ::
116
+
117
+ $ pip install frozenlist
118
+
119
+ The library requires Python 3.8 or newer.
120
+
121
+
122
+ Documentation
123
+ -------------
124
+
125
+ https://frozenlist.aio-libs.org
126
+
127
+ Communication channels
128
+ ----------------------
129
+
130
+ We have a *Matrix Space* `#aio-libs-space:matrix.org
131
+ <https://matrix.to/#/%23aio-libs-space:matrix.org>`_ which is
132
+ also accessible via Gitter.
133
+
134
+ Requirements
135
+ ------------
136
+
137
+ - Python >= 3.8
138
+
139
+ License
140
+ -------
141
+
142
+ ``frozenlist`` is offered under the Apache 2 license.
143
+
144
+ Source code
145
+ -----------
146
+
147
+ The project is hosted on GitHub_
148
+
149
+ Please file an issue in the `bug tracker
150
+ <https://github.com/aio-libs/frozenlist/issues>`_ if you have found a bug
151
+ or have some suggestions to improve the library.
152
+
153
+ .. _GitHub: https://github.com/aio-libs/frozenlist
154
+
155
+ =========
156
+ Changelog
157
+ =========
158
+
159
+ ..
160
+ You should *NOT* be adding new change log entries to this file, this
161
+ file is managed by towncrier. You *may* edit previous change logs to
162
+ fix problems like typo corrections or such.
163
+ To add a new change log entry, please see
164
+ https://pip.pypa.io/en/latest/development/contributing/#news-entries
165
+ we named the news folder "changes".
166
+
167
+ WARNING: Don't drop the next directive!
168
+
169
+ .. towncrier release notes start
170
+
171
+ 1.4.1 (2023-12-15)
172
+ ==================
173
+
174
+ Packaging updates and notes for downstreams
175
+ -------------------------------------------
176
+
177
+ - Declared Python 3.12 and PyPy 3.8-3.10 supported officially
178
+ in the distribution package metadata.
179
+
180
+
181
+ *Related issues and pull requests on GitHub:*
182
+ `#553 <https://github.com/aio-libs/yarl/issues/553>`__.
183
+
184
+ - Replaced the packaging is replaced from an old-fashioned ``setup.py`` to an
185
+ in-tree `PEP 517 <https://peps.python.org/pep-517>`__ build backend -- by `@webknjaz <https://github.com/sponsors/webknjaz>`__.
186
+
187
+ Whenever the end-users or downstream packagers need to build ``frozenlist``
188
+ from source (a Git checkout or an sdist), they may pass a ``config_settings``
189
+ flag ``pure-python``. If this flag is not set, a C-extension will be built
190
+ and included into the distribution.
191
+
192
+ Here is how this can be done with ``pip``:
193
+
194
+ .. code-block:: console
195
+
196
+ $ python3 -m pip install . --config-settings=pure-python=
197
+
198
+ This will also work with ``-e | --editable``.
199
+
200
+ The same can be achieved via ``pypa/build``:
201
+
202
+ .. code-block:: console
203
+
204
+ $ python3 -m build --config-setting=pure-python=
205
+
206
+ Adding ``-w | --wheel`` can force ``pypa/build`` produce a wheel from source
207
+ directly, as opposed to building an ``sdist`` and then building from it.
208
+
209
+
210
+ *Related issues and pull requests on GitHub:*
211
+ `#560 <https://github.com/aio-libs/yarl/issues/560>`__.
212
+
213
+
214
+ Contributor-facing changes
215
+ --------------------------
216
+
217
+ - It is now possible to request line tracing in Cython builds using the
218
+ ``with-cython-tracing`` `PEP 517 <https://peps.python.org/pep-517>`__ config setting
219
+ -- `@webknjaz <https://github.com/sponsors/webknjaz>`__.
220
+
221
+ This can be used in CI and development environment to measure coverage
222
+ on Cython modules, but is not normally useful to the end-users or
223
+ downstream packagers.
224
+
225
+ Here's a usage example:
226
+
227
+ .. code-block:: console
228
+
229
+ $ python3 -Im pip install . --config-settings=with-cython-tracing=true
230
+
231
+ For editable installs, this setting is on by default. Otherwise, it's
232
+ off unless requested explicitly.
233
+
234
+ The following produces C-files required for the Cython coverage
235
+ plugin to map the measurements back to the PYX-files:
236
+
237
+ .. code-block:: console
238
+
239
+ $ python -Im pip install -e .
240
+
241
+ Alternatively, the ``FROZENLIST_CYTHON_TRACING=1`` environment variable
242
+ can be set to do the same as the `PEP 517 <https://peps.python.org/pep-517>`__ config setting.
243
+
244
+
245
+ *Related issues and pull requests on GitHub:*
246
+ `#560 <https://github.com/aio-libs/yarl/issues/560>`__.
247
+
248
+ - Coverage collection has been implemented for the Cython modules
249
+ -- by `@webknjaz <https://github.com/sponsors/webknjaz>`__.
250
+
251
+ It will also be reported to Codecov from any non-release CI jobs.
252
+
253
+
254
+ *Related issues and pull requests on GitHub:*
255
+ `#561 <https://github.com/aio-libs/yarl/issues/561>`__.
256
+
257
+ - A step-by-step ``Release Guide`` guide has
258
+ been added, describing how to release *frozenlist* -- by `@webknjaz <https://github.com/sponsors/webknjaz>`__.
259
+
260
+ This is primarily targeting the maintainers.
261
+
262
+
263
+ *Related issues and pull requests on GitHub:*
264
+ `#563 <https://github.com/aio-libs/yarl/issues/563>`__.
265
+
266
+ - Detailed ``Contributing Guidelines`` on
267
+ authoring the changelog fragments have been published in the
268
+ documentation -- by `@webknjaz <https://github.com/sponsors/webknjaz>`__.
269
+
270
+
271
+ *Related issues and pull requests on GitHub:*
272
+ `#564 <https://github.com/aio-libs/yarl/issues/564>`__.
273
+
274
+
275
+ ----
276
+
277
+
278
+ 1.4.0 (2023-07-12)
279
+ ==================
280
+
281
+ The published source distribution package became buildable
282
+ under Python 3.12.
283
+
284
+
285
+ ----
286
+
287
+
288
+ Bugfixes
289
+ --------
290
+
291
+ - Removed an unused ``typing.Tuple`` import
292
+ `#411 <https://github.com/aio-libs/frozenlist/issues/411>`_
293
+
294
+
295
+ Deprecations and Removals
296
+ -------------------------
297
+
298
+ - Dropped Python 3.7 support.
299
+ `#413 <https://github.com/aio-libs/frozenlist/issues/413>`_
300
+
301
+
302
+ Misc
303
+ ----
304
+
305
+ - `#410 <https://github.com/aio-libs/frozenlist/issues/410>`_, `#433 <https://github.com/aio-libs/frozenlist/issues/433>`_
306
+
307
+
308
+ ----
309
+
310
+
311
+ 1.3.3 (2022-11-08)
312
+ ==================
313
+
314
+ - Fixed CI runs when creating a new release, where new towncrier versions
315
+ fail when the current version section is already present.
316
+
317
+
318
+ ----
319
+
320
+
321
+ 1.3.2 (2022-11-08)
322
+ ==================
323
+
324
+ Misc
325
+ ----
326
+
327
+ - Updated the CI runs to better check for test results and to avoid deprecated syntax. `#327 <https://github.com/aio-libs/frozenlist/issues/327>`_
328
+
329
+
330
+ ----
331
+
332
+
333
+ 1.3.1 (2022-08-02)
334
+ ==================
335
+
336
+ The published source distribution package became buildable
337
+ under Python 3.11.
338
+
339
+
340
+ ----
341
+
342
+
343
+ 1.3.0 (2022-01-18)
344
+ ==================
345
+
346
+ Bugfixes
347
+ --------
348
+
349
+ - Do not install C sources with binary distributions.
350
+ `#250 <https://github.com/aio-libs/frozenlist/issues/250>`_
351
+
352
+
353
+ Deprecations and Removals
354
+ -------------------------
355
+
356
+ - Dropped Python 3.6 support
357
+ `#274 <https://github.com/aio-libs/frozenlist/issues/274>`_
358
+
359
+
360
+ ----
361
+
362
+
363
+ 1.2.0 (2021-10-16)
364
+ ==================
365
+
366
+ Features
367
+ --------
368
+
369
+ - ``FrozenList`` now supports being used as a generic type as per PEP 585, e.g. ``frozen_int_list: FrozenList[int]`` (requires Python 3.9 or newer).
370
+ `#172 <https://github.com/aio-libs/frozenlist/issues/172>`_
371
+ - Added support for Python 3.10.
372
+ `#227 <https://github.com/aio-libs/frozenlist/issues/227>`_
373
+ - Started shipping platform-specific wheels with the ``musl`` tag targeting typical Alpine Linux runtimes.
374
+ `#227 <https://github.com/aio-libs/frozenlist/issues/227>`_
375
+ - Started shipping platform-specific arm64 wheels for Apple Silicon.
376
+ `#227 <https://github.com/aio-libs/frozenlist/issues/227>`_
377
+
378
+
379
+ ----
380
+
381
+
382
+ 1.1.1 (2020-11-14)
383
+ ==================
384
+
385
+ Bugfixes
386
+ --------
387
+
388
+ - Provide x86 Windows wheels.
389
+ `#169 <https://github.com/aio-libs/frozenlist/issues/169>`_
390
+
391
+
392
+ ----
393
+
394
+
395
+ 1.1.0 (2020-10-13)
396
+ ==================
397
+
398
+ Features
399
+ --------
400
+
401
+ - Add support for hashing of a frozen list.
402
+ `#136 <https://github.com/aio-libs/frozenlist/issues/136>`_
403
+
404
+ - Support Python 3.8 and 3.9.
405
+
406
+ - Provide wheels for ``aarch64``, ``i686``, ``ppc64le``, ``s390x`` architectures on
407
+ Linux as well as ``x86_64``.
408
+
409
+
410
+ ----
411
+
412
+
413
+ 1.0.0 (2019-11-09)
414
+ ==================
415
+
416
+ Deprecations and Removals
417
+ -------------------------
418
+
419
+ - Dropped support for Python 3.5; only 3.6, 3.7 and 3.8 are supported going forward.
420
+ `#24 <https://github.com/aio-libs/frozenlist/issues/24>`_
.cache/wandb/logs/core-debug-20240926_055222.log ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"time":"2024-09-26T05:52:22.315197362Z","level":"INFO","msg":"started logging, with flags","port-filename":"/tmp/tmp0irn9n95/port-986.txt","pid":986,"debug":false,"disable-analytics":false}
2
+ {"time":"2024-09-26T05:52:22.315233622Z","level":"INFO","msg":"FeatureState","shutdownOnParentExitEnabled":false}
3
+ {"time":"2024-09-26T05:52:22.316073319Z","level":"INFO","msg":"Will exit if parent process dies.","ppid":986}
4
+ {"time":"2024-09-26T05:52:22.316064076Z","level":"INFO","msg":"server is running","addr":{"IP":"127.0.0.1","Port":41193,"Zone":""}}
5
+ {"time":"2024-09-26T05:52:22.505125081Z","level":"INFO","msg":"created new connection","id":"127.0.0.1:42070"}
6
+ {"time":"2024-09-26T05:52:22.951875072Z","level":"INFO","msg":"connection init received","streamId":"14kj2390","id":"127.0.0.1:42070"}
7
+ {"time":"2024-09-26T05:52:22.952304043Z","level":"ERROR","msg":"error creating symlink","error":"symlink /root/.cache/wandb/logs/core-debug-20240926_055222.log /root/wandb/run-20240926_055222-14kj2390/logs/debug-core.log: file exists"}
8
+ {"time":"2024-09-26T05:52:22.955991404Z","level":"INFO","msg":"connection init completed","streamId":"14kj2390","id":"127.0.0.1:42070"}
9
+ {"time":"2024-09-26T12:39:40.244212691Z","level":"INFO","msg":"handle finish received","streamId":"14kj2390","id":"127.0.0.1:42070"}
10
+ {"time":"2024-09-26T12:39:41.460220703Z","level":"INFO","msg":"connection: teardown","id":"127.0.0.1:42070"}
11
+ {"time":"2024-09-26T12:39:41.460275234Z","level":"INFO","msg":"server is shutting down"}
12
+ {"time":"2024-09-26T12:39:41.460350917Z","level":"INFO","msg":"closed connection","id":"127.0.0.1:42070"}
13
+ {"time":"2024-09-26T12:39:41.460369816Z","level":"INFO","msg":"connection closed","id":"127.0.0.1:42070"}
14
+ {"time":"2024-09-26T12:39:41.460376796Z","level":"INFO","msg":"server is closed"}
.cache/wandb/logs/core-debug-20240926_192831.log ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"time":"2024-09-26T19:28:31.323728841Z","level":"INFO","msg":"started logging, with flags","port-filename":"/tmp/tmp9l51n5u0/port-7447.txt","pid":7447,"debug":false,"disable-analytics":false}
2
+ {"time":"2024-09-26T19:28:31.324125995Z","level":"INFO","msg":"FeatureState","shutdownOnParentExitEnabled":false}
3
+ {"time":"2024-09-26T19:28:31.324781916Z","level":"INFO","msg":"Will exit if parent process dies.","ppid":7447}
4
+ {"time":"2024-09-26T19:28:31.324772272Z","level":"INFO","msg":"server is running","addr":{"IP":"127.0.0.1","Port":44021,"Zone":""}}
5
+ {"time":"2024-09-26T19:28:31.519883511Z","level":"INFO","msg":"created new connection","id":"127.0.0.1:49154"}
6
+ {"time":"2024-09-26T19:28:31.945023432Z","level":"INFO","msg":"connection init received","streamId":"378lr5yg","id":"127.0.0.1:49154"}
7
+ {"time":"2024-09-26T19:28:31.945242119Z","level":"ERROR","msg":"error creating symlink","error":"symlink /root/.cache/wandb/logs/core-debug-20240926_192831.log /root/wandb/run-20240926_192831-378lr5yg/logs/debug-core.log: file exists"}
8
+ {"time":"2024-09-26T19:28:31.947286776Z","level":"INFO","msg":"connection init completed","streamId":"378lr5yg","id":"127.0.0.1:49154"}
9
+ {"time":"2024-09-27T02:14:23.053318256Z","level":"INFO","msg":"handle finish received","streamId":"378lr5yg","id":"127.0.0.1:49154"}
10
+ {"time":"2024-09-27T02:14:23.674128558Z","level":"INFO","msg":"connection init received","streamId":"clesd0p8","id":"127.0.0.1:49154"}
11
+ {"time":"2024-09-27T02:14:23.674521506Z","level":"ERROR","msg":"error creating symlink","error":"symlink /root/.cache/wandb/logs/core-debug-20240926_192831.log /root/wandb/run-20240927_021423-clesd0p8/logs/debug-core.log: file exists"}
12
+ {"time":"2024-09-27T02:14:23.677325569Z","level":"INFO","msg":"connection init completed","streamId":"clesd0p8","id":"127.0.0.1:49154"}
.jupyter/jupyter_nbconvert_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 1,
3
+ "Exporter": {
4
+ "extra_template_paths": [
5
+ ".",
6
+ "/usr/local/lib/python3.10/dist-packages/jupyter_contrib_nbextensions/templates"
7
+ ],
8
+ "preprocessors": [
9
+ "jupyter_contrib_nbextensions.nbconvert_support.CodeFoldingPreprocessor",
10
+ "jupyter_contrib_nbextensions.nbconvert_support.PyMarkdownPreprocessor"
11
+ ]
12
+ }
13
+ }
.jupyter/jupyter_notebook_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "NotebookApp": {
3
+ "nbserver_extensions": {
4
+ "jupyter_nbextensions_configurator": true
5
+ }
6
+ }
7
+ }
.jupyter/lab/workspaces/default-37a8.jupyterlab-workspace ADDED
@@ -0,0 +1 @@
 
 
1
+ {"data":{"layout-restorer:data":{"main":{"dock":{"type":"tab-area","currentIndex":0,"widgets":["terminal:1","editor:train.py","editor:model.py","terminal:3"]},"current":"terminal:1"},"down":{"size":0,"widgets":[]},"left":{"collapsed":false,"visible":true,"current":"filebrowser","widgets":["filebrowser","running-sessions","@jupyterlab/toc:plugin","extensionmanager.main-view"],"widgetStates":{"jp-running-sessions":{"sizes":[0.25,0.25,0.25,0.25],"expansionStates":[false,false,false,false]},"extensionmanager.main-view":{"sizes":[0.3333333333333333,0.3333333333333333,0.3333333333333333],"expansionStates":[false,false,false]}}},"right":{"collapsed":true,"visible":true,"widgets":["jp-property-inspector","debugger-sidebar"],"widgetStates":{"jp-debugger-sidebar":{"sizes":[0.2,0.2,0.2,0.2,0.2],"expansionStates":[false,false,false,false,false]}}},"relativeSizes":[0.2099370188943317,0.7900629811056683,0],"top":{"simpleVisibility":true}},"terminal:1":{"data":{"name":"1"}},"terminal:3":{"data":{"name":"3"}},"file-browser-filebrowser:cwd":{"path":""},"editor:train.py":{"data":{"path":"train.py","factory":"Editor"}},"editor:model.py":{"data":{"path":"model.py","factory":"Editor"}}},"metadata":{"id":"default"}}
.jupyter/migrated ADDED
@@ -0,0 +1 @@
 
 
1
+ 2024-09-26T05:25:08.359004+00:00
.jupyter/nbconfig/notebook.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "load_extensions": {
3
+ "nbextensions_configurator/config_menu/main": true,
4
+ "contrib_nbextensions_help_item/main": true,
5
+ "jupyter-js-widgets/extension": true
6
+ }
7
+ }
.jupyter/nbconfig/tree.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "load_extensions": {
3
+ "nbextensions_configurator/tree_tab/main": true,
4
+ "nbzip/tree": true
5
+ }
6
+ }
.local/share/jupyter/nbextensions/addbefore/addbefore.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ Type: IPython Notebook Extension
2
+ Name: AddBefore
3
+ Description: This extension enables the Add Cell before button (from iPython 1)
4
+ Link: readme.md
5
+ Icon: icon.png
6
+ Main: main.js
7
+ Compatibility: 4.x
.local/share/jupyter/nbextensions/addbefore/main.js ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ define([
2
+ 'base/js/namespace',
3
+ 'jquery',
4
+ 'require',
5
+ 'base/js/events',
6
+ 'base/js/utils',
7
+ ], function(Jupyter, $, requirejs, events, configmod, utils) {
8
+ "use strict";
9
+
10
+ var load_extension = function() {
11
+ Jupyter.toolbar.add_buttons_group([
12
+ Jupyter.keyboard_manager.actions.register ({
13
+ 'help' : 'Insert Cell Above',
14
+ 'icon' : 'fa-arrow-circle-o-up',
15
+ 'handler': function () {
16
+ Jupyter.notebook.insert_cell_above('code');
17
+ Jupyter.notebook.select_prev();
18
+ Jupyter.notebook.focus_cell();
19
+ }
20
+ }, 'insert-cell-above', 'addbefore'),
21
+ Jupyter.keyboard_manager.actions.register ({
22
+ 'help' : 'Insert Cell Below',
23
+ 'icon' : 'fa-arrow-circle-o-down',
24
+ 'handler': function () {
25
+ Jupyter.notebook.insert_cell_below('code');
26
+ Jupyter.notebook.select_next();
27
+ Jupyter.notebook.focus_cell();
28
+ }
29
+ }, 'insert-cell-below', 'addbefore'),
30
+ ]);
31
+ $('#insert_above_below').remove()
32
+
33
+ };
34
+
35
+
36
+
37
+ var extension = {
38
+ load_jupyter_extension : load_extension,
39
+ load_ipython_extension : load_extension
40
+ };
41
+ return extension;
42
+ });
.local/share/jupyter/nbextensions/autosavetime/README.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ autosavetime
2
+ ============
3
+
4
+
5
+ Description
6
+ -----------
7
+
8
+ Optionally set the notebook autosave interval, and/or add a selector to the
9
+ toolbar to set it.
10
+
11
+
12
+ Parameters
13
+ ----------
14
+
15
+ * `autosavetime_set_starting_interval` -
16
+ Set an autosave interval on notebook load. If false, the default is unchanged.
17
+ * `autosavetime_starting_interval` -
18
+ Autosave interval (in minutes) which would be set on notebook load.
19
+ * `autosavetime_show_selector` -
20
+ Add a selector to the toolbar to change the autosave interval
.local/share/jupyter/nbextensions/autosavetime/autosavetime.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Type: IPython Notebook Extension
2
+ Compatibility: 3.x, 4.x, 5.x
3
+ Name: AutoSaveTime
4
+ Main: main.js
5
+ Icon: icon.png
6
+ Link: README.md
7
+ Description: Optionally set the notebook autosave interval, and/or add a selector to the toolbar to set it
8
+ Parameters:
9
+ - name: autosavetime_set_starting_interval
10
+ description: Set an autosave interval on notebook load. If false, the default is unchanged.
11
+ input_type: checkbox
12
+ default: false
13
+ - name: autosavetime_starting_interval
14
+ description: Autosave interval (in minutes) which would be set on notebook load.
15
+ input_type: number
16
+ min: 0
17
+ step: 1
18
+ default: 2
19
+ - name: autosavetime_show_selector
20
+ description: add a selector to the toolbar to change the autosave interval
21
+ input_type: checkbox
22
+ default: true
.local/share/jupyter/nbextensions/autosavetime/icon.png ADDED
.local/share/jupyter/nbextensions/autoscroll/autoscroll.yaml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Type: IPython Notebook Extension
2
+ Compatibility: 3.x, 4.x
3
+ Name: Autoscroll
4
+ Main: main.js
5
+ Icon: icon.png
6
+ Link: README.md
7
+ Description: Optionally set the output autoscroll threshold, and/or add a selector to the toolbar to set it, and/or add a toolbar button to enable/disable it
8
+ Parameters:
9
+ - name: autoscroll_set_on_load
10
+ description: Set an autoscroll threshold on notebook load. If false, the default is unchanged.
11
+ input_type: checkbox
12
+ default: false
13
+ - name: autoscroll_starting_threshold
14
+ description: Autoscroll threshold which would be set on notebook load. -1 disables autoscrolling.
15
+ input_type: number
16
+ min: -1
17
+ step: 1
18
+ default: 100
19
+ - name: autoscroll_show_selector
20
+ description: add a selector to the toolbar to change the autoscroll threshold
21
+ input_type: checkbox
22
+ default: true
23
+ - name: autoscroll_show_button
24
+ description: add a button to the toolbar to disable/enable autoscrolling
25
+ input_type: checkbox
26
+ default: false
.local/share/jupyter/nbextensions/autoscroll/main.js ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ define([
2
+ 'jquery',
3
+ 'base/js/namespace',
4
+ 'base/js/events',
5
+ 'notebook/js/outputarea',
6
+ 'notebook/js/codecell'
7
+ ], function (
8
+ $,
9
+ IPython,
10
+ events,
11
+ oa,
12
+ codecell
13
+ ) {
14
+ "use strict";
15
+
16
+ var prev_threshold = 0;
17
+ var action_full_name; // will be set when registering the action
18
+
19
+ // define default values for config parameters
20
+ var params = {
21
+ autoscroll_set_on_load : false,
22
+ autoscroll_starting_threshold : 100,
23
+ autoscroll_show_selector : true,
24
+ autoscroll_show_button : false
25
+ };
26
+
27
+ // update params with any specified in the server's config file
28
+ var update_params = function() {
29
+ var config = IPython.notebook.config;
30
+ for (var key in params) {
31
+ if (config.data.hasOwnProperty(key))
32
+ params[key] = config.data[key];
33
+ }
34
+ };
35
+
36
+ var initAutoScroll = function() {
37
+ if (IPython.notebook === undefined) return;
38
+ var cells = IPython.notebook.get_cells();
39
+ var ncells = IPython.notebook.ncells();
40
+ for (var i=0; i<ncells; i++) {
41
+ var cell = cells[i];
42
+ if ((cell instanceof codecell.CodeCell)) {
43
+ cell.scroll_output()
44
+ }
45
+ }
46
+
47
+ };
48
+
49
+ var toggle_output_autoscroll = function() {
50
+ if (oa.OutputArea.auto_scroll_threshold > 0) {
51
+ prev_threshold = oa.OutputArea.auto_scroll_threshold;
52
+ oa.OutputArea.auto_scroll_threshold = -1;
53
+ }
54
+ else {
55
+ var new_thr = prev_threshold <= 0 ? 1 : prev_threshold;
56
+ prev_threshold = oa.OutputArea.auto_scroll_threshold;
57
+ oa.OutputArea.auto_scroll_threshold = new_thr;
58
+ }
59
+
60
+ $('#autoscroll_selector').val(oa.OutputArea.auto_scroll_threshold);
61
+
62
+ $('.btn[data-jupyter-action="' + action_full_name + '"]')
63
+ .toggleClass('active', oa.OutputArea.auto_scroll_threshold <= 0)
64
+ .blur();
65
+ initAutoScroll();
66
+ };
67
+
68
+ var initialize = function() {
69
+ update_params();
70
+
71
+ var thresholds = [-1, 1, 10, 20, 50, 100, 200, 500, 1000];
72
+
73
+ if (params.autoscroll_set_on_load) {
74
+ var st = params.autoscroll_starting_threshold;
75
+ oa.OutputArea.auto_scroll_threshold = st;
76
+ if (thresholds.includes(st) === false) thresholds.push(st);
77
+ }
78
+
79
+ thresholds.sort(function(a, b){ return a-b; });
80
+
81
+ if (params.autoscroll_show_selector) {
82
+ var select = $('<select id="autoscroll_selector"/>')
83
+ .addClass("form-control select-xs");
84
+ select.change(function() {
85
+ oa.OutputArea.auto_scroll_threshold = parseInt($(this).val(), 10);
86
+ $('.btn[data-jupyter-action="' + action_full_name + '"]')
87
+ .toggleClass('active', oa.OutputArea.auto_scroll_threshold <= 0);
88
+ $(this).blur();
89
+ });
90
+ for (var i in thresholds) {
91
+ var thr = thresholds[i];
92
+ select.append($('<option/>').attr('value', thr).text(thr));
93
+ }
94
+ select.find('option[value="100"]').text('100 (default)');
95
+ select.find('option[value="-1"]').text('no-scroll');
96
+ IPython.toolbar.element.append(
97
+ $('<label class="navbar-text"/>').text('auto-scroll threshold:')
98
+ ).append(select);
99
+ select.val(oa.OutputArea.auto_scroll_threshold);
100
+ }
101
+
102
+ if (params.autoscroll_show_button) {
103
+ IPython.toolbar.add_buttons_group([action_full_name]);
104
+ }
105
+ initAutoScroll();
106
+ };
107
+
108
+ var load_ipython_extension = function () {
109
+ var prefix = 'auto';
110
+ var action_name = 'toggle-output-autoscroll';
111
+ var action = {
112
+ icon: 'fa-close',
113
+ help: 'Toggle output auto-scrolling',
114
+ help_index : 'zz',
115
+ handler : toggle_output_autoscroll
116
+ };
117
+
118
+ action_full_name = IPython.keyboard_manager.actions.register(action, action_name, prefix);
119
+
120
+ IPython.notebook.config.loaded.then(initialize);
121
+ events.on("notebook_loaded.Notebook", function(){
122
+ initAutoScroll();
123
+ });
124
+
125
+ };
126
+
127
+ return {
128
+ load_ipython_extension : load_ipython_extension
129
+ };
130
+ });
.local/share/jupyter/nbextensions/cell_filter/cell_filter.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * cell_filter.js
3
+ * An extension that allows you to filter cells by tags. Keywords entered into the search bar separated by spaces joins them with logical AND.
4
+ *
5
+ *
6
+ * @version 0.1.0
7
+ * @author Benjamin Ellenberger, https://github.com/benelot
8
+ * @updated 2018-02-16
9
+ *
10
+ *
11
+ */
12
+ define([
13
+ 'require',
14
+ 'jqueryui',
15
+ 'base/js/namespace',
16
+ 'base/js/utils',
17
+ 'services/config'
18
+ ], function (
19
+ requirejs,
20
+ $,
21
+ Jupyter,
22
+ utils
23
+ ) {
24
+ 'use strict';
25
+
26
+ function filterRows (filterText, caseSensitive, useRegex) {
27
+ var input = $('#filterkeyword');
28
+ var btnRegex = $('#filterisreg');
29
+
30
+ filterText = filterText !== undefined ? filterText : input.val();
31
+ useRegex = useRegex !== undefined ? useRegex : btnRegex.attr('aria-pressed') === 'true';
32
+ caseSensitive = caseSensitive !== undefined ? caseSensitive : $('#filtercase').attr('aria-pressed') === 'true';
33
+
34
+ if (!useRegex) {
35
+ // escape any regex special chars
36
+ filterText = filterText.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
37
+ var keywords = filterText.split(' '); // get all space separated keywords
38
+ filterText = '.*'; // catch all stuff before the keywords
39
+ keywords.forEach(function(keyword){ // find all keywords we are looking for with regex (?=.*keyword)
40
+ filterText += '(?=.*' + keyword + ')';
41
+ });
42
+ filterText += '.*'; // catch all stuff after the keywords
43
+ }
44
+ var matchExpr;
45
+ try {
46
+ matchExpr = new RegExp(filterText, caseSensitive ? '' : 'i'); // prepare regex
47
+ }
48
+ catch (err) {
49
+ // do nothing, error is handled based on undefined matchExpr
50
+ }
51
+
52
+ var invalidRegex = matchExpr === undefined; // indicate invalid regex
53
+ btnRegex.toggleClass('btn-danger', invalidRegex);
54
+ btnRegex.toggleClass('btn-default', !invalidRegex);
55
+ btnRegex.closest('.form-group').toggleClass('has-error has-feedback', invalidRegex);
56
+
57
+ Jupyter.notebook.get_cells().forEach(function (cell, idx, cells) { // toggle visibility of cells depending on their tags
58
+ var tags = cell.metadata.tags || [];
59
+ tags = tags.join(' ');
60
+ if(filterText === ".*(?=.*).*" || filterText === "" || tags.search(matchExpr) !== -1 && tags.length > 0){ // empty filter or match expression on non-zero tags
61
+ cell.element.show(); // cell.element.style.display = '';
62
+ //cell.element.find("div.inner_cell").show();
63
+ }
64
+ else{
65
+ cell.element.hide(); // cell.element.style.display = 'none';
66
+ //cell.element.find("div.inner_cell").hide();
67
+ }
68
+ });
69
+ }
70
+
71
+ function filterRowsDefaultParams () {
72
+ return filterRows();
73
+ }
74
+
75
+ function load_ipython_extension () {
76
+
77
+ var form_tgrp = $('<div/>')
78
+ .addClass('btn-group') // insert a top form-group to make the form appear next to the buttons
79
+ .appendTo('#maintoolbar-container');
80
+
81
+ var frm_grp = $('<div/>')
82
+ .addClass('form-group') // insert a form-group
83
+ .css('margin-bottom', 0)
84
+ .appendTo(form_tgrp);
85
+
86
+ var grp = $('<div/>')
87
+ .addClass('input-group') // insert an input-group
88
+ .appendTo(frm_grp);
89
+
90
+ $('<input/>') // insert search bar
91
+ .attr('type', 'text')
92
+ .addClass('form-control input-sm')
93
+ .attr('title', 'Keyword for filtering cells by tags')
94
+ .attr('id', 'filterkeyword')
95
+ .attr('placeholder', 'Cell Tag Filter')
96
+ .css('font-weight', 'bold')
97
+ .css('width', '70%')
98
+ .css('height', '24px')
99
+ .on('focus', function (evt) { Jupyter.notebook.keyboard_manager.disable();})
100
+ .on('blur', function (evt) { Jupyter.notebook.keyboard_manager.enable();})
101
+ .appendTo(grp);
102
+
103
+ $('<button/>')
104
+ .attr('type', 'button') // insert regex button
105
+ .attr('id', 'filterisreg')
106
+ .addClass('btn btn-default btn-sm')
107
+ .attr('data-toggle', 'button')
108
+ .css('font-weight', 'bold')
109
+ .attr('title', 'Use regex (JavaScript regex syntax)')
110
+ .text('.*')
111
+ .on('click', function (evt) { setTimeout(filterRowsDefaultParams); })
112
+ .appendTo(grp);
113
+
114
+ $('<button/>') // insert case sensitive button
115
+ .attr('type', 'button')
116
+ .attr('id', 'filtercase')
117
+ .addClass('btn btn-default btn-sm')
118
+ .attr('data-toggle', 'button')
119
+ .attr('tabindex', '0')
120
+ .attr('title', 'Match case')
121
+ .css('font-weight', 'bold')
122
+ .text('Aa')
123
+ .on('click', function (evt) { setTimeout(filterRowsDefaultParams); })
124
+ .appendTo(grp);
125
+
126
+ $('#filterkeyword').on('keyup', filterRowsDefaultParams); // trigger filtering right with typing
127
+ }
128
+
129
+ return {
130
+ load_ipython_extension : load_ipython_extension
131
+ };
132
+
133
+ });
.local/share/jupyter/nbextensions/code_font_size/README.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Code Font Size
2
+ ==============
3
+
4
+ Adds toolbar buttons to increase and decrease code's font size. This is useful, for example, when projecting the notebook.
.local/share/jupyter/nbextensions/code_font_size/code_font_size.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Increase/decrease code font size
2
+
3
+
4
+ define([
5
+ 'base/js/namespace',
6
+ 'base/js/events'
7
+ ], function(Jupyter, events) {
8
+ var code_change_fontsize = function(doIncrease) {
9
+ var pre_css = null;
10
+ var pre_style = null;
11
+ for(i = 0; i < document.styleSheets.length; i++){
12
+ //if style sheet is custom.css
13
+ if(/.*\/custom\/custom\.css/.test(document.styleSheets[i].href)){
14
+ //pre_css now contains the style sheet custom.css
15
+ pre_css = document.styleSheets[i];
16
+ break;
17
+ }
18
+ }
19
+
20
+ for(i = 0; i < pre_css.cssRules.length; i++){
21
+ if(/\.CodeMirror pre/.test(pre_css.cssRules[i].selectorText)){
22
+ pre_style = pre_css.cssRules[i].style;
23
+ break;
24
+ }
25
+ }
26
+
27
+ if(pre_style == null){
28
+ pre_css.insertRule(".CodeMirror pre { font-size: \"14px\"; padding-bottom: \"0px\"; }", 0);
29
+ pre_style = pre_css.cssRules[0];
30
+ }
31
+
32
+ var font_size = pre_style.fontSize || "";
33
+ if(font_size == "")
34
+ font_size = 14;
35
+ else
36
+ font_size = +/\d+/.exec(font_size)[0];
37
+ font_size += (doIncrease ? +3 : -3);
38
+ font_size = (font_size < 8 ? 8 : font_size);
39
+ var padding_size = (font_size <= 14 ? 0 : (font_size - 14));
40
+
41
+ pre_style.paddingBottom = padding_size + "px";
42
+ pre_style.fontSize = font_size + "px";
43
+ };
44
+
45
+ var load_ipython_extension = function () {
46
+ Jupyter.toolbar.add_buttons_group([
47
+ /*
48
+ * Buttons to increase/decrease code font size
49
+ */
50
+ Jupyter.keyboard_manager.actions.register ({
51
+ 'help' : 'Increase code font size',
52
+ 'icon' : 'fa-search-plus',
53
+ 'handler': function () {
54
+ $( document ).ready(code_change_fontsize(true));
55
+ }
56
+ }, 'increase-code-font-size', 'code_font_size'),
57
+ Jupyter.keyboard_manager.actions.register ({
58
+ 'help' : 'Decrease code font size',
59
+ 'icon' : 'fa-search-minus',
60
+ 'handler': function () {
61
+ $( document ).ready(code_change_fontsize(false));
62
+ }
63
+ }, 'decrease-code-font-size', 'code_font_size'),
64
+
65
+ ]);
66
+ };
67
+ return {
68
+ load_ipython_extension : load_ipython_extension
69
+ };
70
+ });
.local/share/jupyter/nbextensions/code_font_size/code_font_size.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ Type: IPython Notebook Extension
2
+ Name: Code Font Size
3
+ Link: README.md
4
+ Description: Adds toolbar buttons to increase and decrease code's font size.
5
+ This is useful, for example, when projecting the notebook.
6
+ Main: code_font_size.js
7
+ Compatibility: 4.x, 5.x
.local/share/jupyter/nbextensions/code_prettify/2to3.yaml ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Type: Jupyter Notebook Extension
2
+ Name: 2to3 Converter
3
+ Description: Converts python2 code in a notebook's code cell to python3 code
4
+ Link: README_2to3.md
5
+ Main: 2to3.js
6
+ Compatibility: Jupyter 4.x, 5.x
7
+ Parameters:
8
+
9
+ - name: 2to3.add_toolbar_button
10
+ description: Add a toolbar button to convert the selected cell(s)
11
+ input_type: checkbox
12
+ default: true
13
+
14
+ - name: 2to3.button_icon
15
+ description: |
16
+ Toolbar button icon: a font-awesome class defining the icon used for the
17
+ toolbar button. See https://fontawesome.com/icons for available icons.
18
+ input_type: text
19
+ default: 'fa-space-shuttle'
20
+
21
+ - name: 2to3.button_label
22
+ description: Toolbar button label text
23
+ input_type: text
24
+ default: 'Code converter'
25
+
26
+ - name: 2to3.register_hotkey
27
+ description: Register a hotkey to convert the selected cell(s)
28
+ input_type: checkbox
29
+ default: true
30
+
31
+ - name: 2to3.hotkeys.process_selected
32
+ description: Hotkey to convert the selected cell(s) from python2 to python3
33
+ input_type: hotkey
34
+ default: 'Ctrl-M'
35
+
36
+ - name: 2to3.hotkeys.process_all
37
+ description: Hotkey to convert the whole notebook
38
+ input_type: hotkey
39
+ default: 'Ctrl-Shift-M'
40
+
41
+ - name: 2to3.show_alerts_for_not_supported_kernel
42
+ description: Show alerts if the kernel is not supported
43
+ input_type: checkbox
44
+ default: false
45
+
46
+ - name: 2to3.show_alerts_for_errors
47
+ description: Show alerts for errors in the kernel converting calls
48
+ input_type: checkbox
49
+ default: true
50
+
51
+ - name: 2to3.kernel_config_map_json
52
+ description: |
53
+ kernel_config_map_json:
54
+ json defining library calls required to load the kernel-specific
55
+ converting modules, and the prefix & postfix for the json-format string
56
+ required to make the converting call.
57
+ input_type: textarea
58
+ default: |
59
+ {
60
+ "python": {
61
+ "library": "import lib2to3.refactor, json\n_2to3_refactoring_tool = lib2to3.refactor.RefactoringTool(\n set(lib2to3.refactor.get_fixers_from_package('lib2to3.fixes')))\ndef _2to3_refactor_cell(src):\n try:\n tree = _2to3_refactoring_tool.refactor_string(src+'\\n', '<dummy_name>')\n except (lib2to3.pgen2.parse.ParseError, lib2to3.pgen2.tokenize.TokenError):\n return src \n else:\n return str(tree)[:-1]",
62
+ "prefix": "print(json.dumps(refactor_cell(u",
63
+ "postfix": ")))"
64
+ }
65
+ }
.local/share/jupyter/nbextensions/code_prettify/README.md ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ KernelExecOnCells library and nbextensions
2
+ ==========================================
3
+
4
+ The KernelExecOnCells library is a shared library for creating Jupyter
5
+ nbextensions which transform code cell text using calls to the active kernel.
6
+
7
+ This scheme has been applied to create several nbextensions which are also
8
+ included in the repository.
9
+ For instance, to prettify code, see the [code-prettify] nbextension, or to
10
+ refactor python 2 code for python 3, see the [2to3] extension.
11
+ These nbextensions are defined as simple plugins of the main KernelExecOnCells
12
+ library. Defining such a plugin, [jupyter-autopep8], is described in the last section below.
13
+
14
+
15
+ Compatible Kernels
16
+ ------------------
17
+
18
+ The library is kernel-language agnostic, as described in the [internals]
19
+ section below. Essentially any kernel capable of interpreting and creating
20
+ json-formatted strings, and sending them to the stream output (where print
21
+ statements in most languages go) should be easy to integrate.
22
+ Hopefully, that covers pretty much all languages!
23
+
24
+
25
+ Options
26
+ -------
27
+
28
+ The library uses a series of options, describing the configuration of the
29
+ plugin. Default values for these options are specified as an object in the
30
+ plugin source file, and can be overriden by values loaded from config.
31
+ There are a few nbextension-wide options, configurable using the
32
+ [jupyter_nbextensions_configurator] or by editing the `notebook` section config
33
+ file directly.
34
+ If `mod_name` is the name of the plugin module (e.g. `code_prettify`, `2to3`,
35
+ ...) and `LANG` the lowercased kernel language (eg julia, python, r ...), then
36
+ the options are as follows:
37
+
38
+ - `mod_name.add_toolbar_button`:
39
+ Whether to add a toolbar button to transform the selected cell(s).
40
+ Defaults to `true`.
41
+
42
+ - `mod_name.button_icon`:
43
+ A font-awesome class defining the icon used for the toolbar button and
44
+ actions. See [fontawesome] for available icon classes.
45
+ Defaults to `fa-legal`.
46
+
47
+ - `mod_name.button_label`:
48
+ Toolbar button label text. Also used in the actions' help text.
49
+ Defaults to `mod_name`.
50
+
51
+ - `mod_name.register_hotkey`:
52
+ Whether to register hotkeys to transform the selected cell(s)/whole notebook.
53
+ Defaults to `true`.
54
+
55
+ - `mod_name.hotkeys.process_all`:
56
+ Hotkey to use to transform all the code cells in the notebook.
57
+ Defaults to `Ctrl-Shift-L`.
58
+
59
+ - `mod_name.hotkeys.process_selected`:
60
+ Hotkey to use to transform the selected cell(s).
61
+ Defaults to `Ctrl-L`.
62
+
63
+ - `mod_name.show_alerts_for_errors`:
64
+ Whether to show alerts for errors in the kernel calls.
65
+ Defaults to `true`.
66
+
67
+ - `mod_name.kernel_config_map_json`:
68
+ The value of this key is a string which can be parsed into a json object
69
+ giving the config for each kernel language.
70
+
71
+ The following give the per-kernel options of the parsed json, using the
72
+ language key `LANG`, to be replaced as appropriate:
73
+
74
+ * `mod_name.kernel_config_map_json.LANG.library`:
75
+ String to execute in the kernel in order to load any necessary kernel
76
+ libraries.
77
+
78
+ * `mod_name.kernel_config_map_json.LANG.replacements_json_to_kernel`:
79
+ a list of pairs of strings, used as arguments to javascript's
80
+ `String.replace(from, to)` to translate from a json string into a valid
81
+ representation of the same string in the kernel language. Since json
82
+ strings are particularly simple, this can often (as with the python
83
+ language) be left as the default, an empty list.
84
+
85
+ * `mod_name.kernel_config_map_json.LANG.prefix` and
86
+ `mod_name.kernel_config_map_json.LANG.postfix`:
87
+ strings added as bookends to the kernel string (translated from the json
88
+ string using the replacements above) to make up the kernel prettifier call
89
+ kernel's prettifier libraries.
90
+
91
+ * `mod_name.kernel_config_map_json.LANG.trim_formatted_text`:
92
+ Whether to trim whitespace from the transformed cell text. Since jupyter
93
+ cells don't usually have leading or trailing whitespace, the default
94
+ behaviour is to trim the transformed text, in order to prevent the
95
+ transform adding extra newlines at the end (a common behaviour for source
96
+ files, where having a trailing newline is often considered good practice).
97
+
98
+
99
+ Internals
100
+ ---------
101
+
102
+ The model is essentially:
103
+
104
+ 1. The cell text is grabbed by client-side javascript, then turned into a json
105
+ string using javascript `JSON.stringify`. Since json-compatible strings are
106
+ a particularly simple string format, which is compatible with many other
107
+ programming languages without much modification (e.g. a valid json string
108
+ is also a valid string in python 3, and also in python 2 when prefixed with
109
+ a `u`), and easily converted for use in others (because of its simplicity).
110
+
111
+ 2. Optional regex replacements are used to translate the json-format string
112
+ into a valid kernel string. Python, R and javascript don't require this
113
+ step, but other languages may do, so it's implemented for flexibility
114
+ using the per-kernel config key `replacements_json_to_kernel`, which is a
115
+ list of pairs of arguments to javascript `String.replace`.
116
+
117
+ 3. The kernel-specific prettifier call is then composed from
118
+ `kernel_config.prefix` + `kernel_text_string` + `kernel_config.postfix` and
119
+ sent to the kernel for execution. This kernel call is expected to get the
120
+ formatted cell text _printed_ as a json-compatible string. Since most
121
+ kernel languages have json packages, this should hopefully be easy to
122
+ arrange. The reason for the printing text rather than simply displaying it,
123
+ is that it prevents us having to translate from a kernel string
124
+ representing a json string.
125
+
126
+ 4. The callback for the kernel execution in client-side javascript parses the
127
+ printed json-format string, optionally trims trailing whitespace according
128
+ to the `trim_formatted_text` key (which defaults to `true`) in the
129
+ per-kernel config, and then sets the cell text using the result.
130
+
131
+ The process is probably best illustrated using an example for the python
132
+ implementation in `code_prettify`:
133
+
134
+ 1. **At nbextension load**, the `code_prettify.kernel_config_map_json` config
135
+ option is parsed to give the json object
136
+
137
+ ```json
138
+ {
139
+ "python": {
140
+ "library": "import json\nimport yapf.yapflib.yapf_api",
141
+ "prefix": "print(json.dumps(yapf.yapflib.yapf_api.FormatCode(u",
142
+ "postfix": ")[0]))"
143
+ }
144
+ }
145
+ ```
146
+
147
+ (other kernel languages are omitted for clarity).
148
+
149
+ 2. **On kernel becoming ready**, the nbextension looks up the config for the
150
+ kernel's language (in our example, this is the `python` key of the kernel
151
+ config json object above). It then sends the kernel config's `library`
152
+ string to the kernel for execution. Thus the python implementation above
153
+ executes
154
+
155
+ ```python
156
+ import json
157
+ import yapf.yapflib.yapf_api
158
+ ```
159
+
160
+ 3. **On requesting a cell be prettified** which can happen by clicking the
161
+ toolbar, or with a (configurable) hotkey, the following happens:
162
+
163
+ Say the cell to be formatted contains the following ugly python code:
164
+
165
+ ```python
166
+ msg= 'hello '+"world"
167
+ print (
168
+ msg )
169
+ ```
170
+
171
+ Then the result of the `JSON.stringify` call will be a string containing
172
+
173
+ ```json
174
+ "msg= 'hello '+\"world\"\nprint (\n msg )"
175
+ ```
176
+
177
+ (note the opening and closing quotes). Concatenating this with the prefix &
178
+ postfix strings from the python kernel config above, gives us the kernel
179
+ code to execute. The call sent to the python kernel is therefore
180
+
181
+ ```python
182
+ print(json.dumps(yapf.yapflib.yapf_api.FormatCode(u"msg= 'hello '+\"world\"\nprint (\n msg )")[0]))
183
+ ```
184
+
185
+ 4. What gets 'printed' by the kernel (i.e. returned to the javascript stream
186
+ callback) is the following json-format string:
187
+
188
+ ```json
189
+ "msg = 'hello ' + \"world\"\nprint(msg)\n"
190
+ ```
191
+
192
+ The default is to trim whitepace from the returned prettified text, which
193
+ results in the final prettified python code for the cell:
194
+
195
+ ```python
196
+ msg = 'hello ' + "world"
197
+ print(msg)
198
+ ```
199
+
200
+
201
+ Defining a new plugin
202
+ ---------------------
203
+
204
+ As an example, we will add a new plugin which reformats code using the
205
+ [autopep8] module in python, rather than the [yapf] library used by
206
+ `code_prettify`. Such a plugin, [jupyter-autopep8] was developed by [@kenkoooo]
207
+ as a fork of an old version of `code_prettify`. Redefining it here has the
208
+ advantage of using the updated and more-robust architecture, in addition to
209
+ making it possible to reformat the whole notebook in one go.
210
+
211
+ For this new nbextension, we just have to run `import autopep8` as the kernel
212
+ library code, and then call the `autopep8.fix_code` function on cells' text.
213
+ Hence what we have to do is:
214
+
215
+ - copy `code_prettify.js` to `autopep8.js`
216
+
217
+ - update `mod_name`, `hotkeys`, `button_icon` default config values in the new
218
+ `autopep8.js`. Also update the `cfg.kernel_config_map` value to use the
219
+ correct kernel code:
220
+ ```javascript
221
+ cfg.kernel_config_map = { // map of options for supported kernels
222
+ "python": {
223
+ "library": "import json\nimport autopep8",
224
+ "prefix": "print(json.dumps(autopep8.fix_code(u",
225
+ "postfix": ")))"
226
+ }
227
+ };
228
+ ```
229
+
230
+ - copy `code_prettify.yaml` to `autopep8.yaml`, and update its values (name,
231
+ require, readme, plus the new defaults for hotkeys, icon, and
232
+ kernel_config_map
233
+
234
+ - that's all :-)
235
+
236
+ Of course, for this simple case, one could equally have just updated the
237
+ configuration of `code_prettify` using the [jupyter_nbextensions_configurator]
238
+ to use [autopep8] instead of [yapf] to reformat the python code.
239
+ But, if you want two alternative prettifiers available for the same kernel
240
+ language, we need to define separate plugins.
241
+
242
+ Custom Yapf Styles
243
+ ------------------
244
+
245
+ Using the default `yapf` engine, one may define a custom formatting style according to the [package documentation](https://github.com/google/yapf#formatting-style).
246
+
247
+ The `code_prettify` extension is configured to follow the default `yapf` ordering (minus the command line option) and will search for the formatting style in the following manner:
248
+
249
+ > 1. In the [style] section of a .style.yapf file in either the current directory or one of its parent directories.
250
+ > 2. In the [yapf] section of a setup.cfg file in either the current directory or one of its parent directories.
251
+ > 3. In the ~/.config/yapf/style file in your home directory.
252
+ >
253
+ > If none of those files are found, the default style is used (PEP8).
254
+
255
+ This means that one can set up a globa custom yapf style using `~/.config/yapf/style` or a project-specific one using the project directory.
256
+
257
+ History
258
+ -------
259
+
260
+ - [@jfbercher], august 14, 2016, first version, named `yapf_ext`
261
+ - [@jfbercher], august 19, 2016, second version `code_prettify`
262
+ - introduced support for R and javascript.
263
+ - changed extension name from `yapf_ext` to `code_prettify`
264
+ - [@jcb91], december 2016
265
+ - made addition of toolbar button & hotkey configurable
266
+ - reworked to avoid regex replacements for conversion to/from kernel string
267
+ formats, in favour of json-string interchange
268
+ - made kernel-specific prettifier calls configurable, allowing support for
269
+ different prettifiers & arbitrary kernels
270
+ - improved documentation
271
+ - [@jfbercher], december 2016-january 2017
272
+ - added a configurable shortkey to reflow the whole notebook
273
+ - extracted most of the code to build a general library of functions,
274
+ `kernel_exec_on_cell.js`, which can be used for all nbextensions which
275
+ needs to exec some code (via the current kernel) on the text from cells.
276
+ - added 2to3 as a plugin to the shared library
277
+ - [@jcb91], january 2017
278
+ - library: Use actions to avoid problems with auto-generated actions
279
+ generated by keyboard_manager, which were overwriting each other.
280
+ Also fix toolbar button removal.
281
+ - [@jfbercher], january 2017
282
+ - updated documentation
283
+ - added autopep8 nbextension as a plugin using the shared library
284
+ - [@artificialsoph], Jan 2018
285
+ - updated documentation
286
+ - changed default behavior to load custom yapf styles
287
+ - [@jfbercher], April 2019
288
+ - corrected an issue in configs merge
289
+ - added an option for displaying an alert if kernel is not supported and turned it off by default (instead issue a warning in the js console).
290
+
291
+ [2to3]: README_2to3.md
292
+ [@jcb91]: https://github.com/jcb91
293
+ [@jfbercher]: https://github.com/jfbercher
294
+ [@kenkoooo]: https://github.com/kenkoooo
295
+ [autopep8]: https://github.com/hhatto/autopep8
296
+ [code-prettify]: README_code_prettify.md
297
+ [jupyter-autopep8]: README_autopep8.md
298
+ [fontawesome]: https://fontawesome.com/icons
299
+ [internals]: #Internals
300
+ [jupyter-autopep8]: https://github.com/kenkoooo/jupyter-autopep8
301
+ [jupyter_nbextensions_configurator]: https://github.com/Jupyter-contrib/jupyter_nbextensions_configurator
302
+ [yapf]: https://github.com/google/yapf
.local/share/jupyter/nbextensions/code_prettify/README_autopep8.md ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jupyter-autopep8
2
+ ================
3
+
4
+ This nbextension reformats/prettifies code in notebook python code cells.
5
+
6
+ Under the hood, it uses a call to the current notebook kernel to reformat the
7
+ code.
8
+ The conversion run by the kernel uses the python [autopep8] package, and thus is compatible only with python kernels.
9
+
10
+ The nbextension provides
11
+
12
+ - a toolbar button (configurable to be added or not)
13
+
14
+ - a keyboard shortcut for reformatting the current code-cell (default shortcut
15
+ is `Alt-A`, can also be configured not to add the keyboard shortcut).
16
+
17
+ - a keyboard shortcut for reformatting the whole notebook (default shortcut
18
+ is `Alt-Shift-A`, can also be configured not to add the keyboard shortcut).
19
+
20
+ Syntax needs to be correct, but the nbextension may be able to point out basic
21
+ syntax errors.
22
+
23
+
24
+ Prerequisites
25
+ -------------
26
+
27
+ Of course, you must have the necessary kernel-specific package installed for
28
+ the prettifier call to work:
29
+
30
+ pip install autopep8
31
+
32
+
33
+ Options
34
+ -------
35
+
36
+ All options are provided by the [KerneExecOnCells library] - see the
37
+ [internals] section below for details.
38
+ There are a few nbextension-wide options, configurable using the
39
+ [jupyter_nbextensions_configurator] or by editing the `notebook` section config
40
+ file directly.
41
+ The options are as follows:
42
+
43
+ - `autopep8.add_toolbar_button`:
44
+ Whether to add a toolbar button to transform the selected cell(s).
45
+ Defaults to `true`.
46
+
47
+ - `autopep8.button_icon`:
48
+ A font-awesome class defining the icon used for the toolbar button and actions.
49
+ See [fontawesome] for available icon classes.
50
+ Defaults to `fa-cog`.
51
+
52
+ - `autopep8.button_label`:
53
+ Toolbar button label text. Also used in the actions' help text.
54
+ Defaults to `Prettify (using autopep8)`.
55
+
56
+ - `autopep8.register_hotkey`:
57
+ Whether to register hotkeys to transform the selected cell(s)/whole notebook.
58
+ Defaults to `true`.
59
+
60
+ - `autopep8.hotkeys.process_all`:
61
+ Hotkey to use to transform all the code cells in the notebook.
62
+ Defaults to `Alt-Shift-A`.
63
+
64
+ - `autopep8.hotkeys.process_selected`:
65
+ Hotkey to use to transform the selected cell(s).
66
+ Defaults to `Alt-A`.
67
+
68
+ - `autopep8.show_alerts_for_not_supported_kernel`:
69
+ Whether to show alerts if the kernel is not supported.
70
+ Defaults to `false`.
71
+
72
+ - `autopep8.show_alerts_for_errors`:
73
+ Whether to show alerts for errors in the kernel calls.
74
+ Defaults to `true`.
75
+
76
+ - `autopep8.kernel_config_map_json`:
77
+ The value of this key is a string which can be parsed into a json object
78
+ giving the config for each kernel language.
79
+
80
+ The following give the per-kernel options of the parsed json, using the
81
+ language key `python `:
82
+
83
+ * `autopep8.kernel_config_map_json.python.library`:
84
+ String to execute in the kernel in order to load any necessary kernel
85
+ libraries.
86
+
87
+ * `autopep8.kernel_config_map_json.python.replacements_json_to_kernel`:
88
+ a list of pairs of strings, used as arguments to javascript's
89
+ `String.replace(from, to)` to translate from a json string into a valid
90
+ representation of the same string in the kernel language. Since json
91
+ strings are particularly simple, this can often (as with the python
92
+ language) be left as the default, an empty list.
93
+
94
+ * `autopep8.kernel_config_map_json.python.prefix` and
95
+ `autopep8.kernel_config_map_json.python.postfix`:
96
+ Strings added as bookends to the kernel string (translated from the json
97
+ string using the replacements above) to make up the kernel prettifier call
98
+ kernel's prettifier libraries.
99
+
100
+ * `autopep8.kernel_config_map_json.python.trim_formatted_text`:
101
+ Whether to trim whitespace from the transformed cell text. Since jupyter
102
+ cells don't usually have leading or trailing whitespace, the default
103
+ behaviour is to trim the transformed text, in order to prevent the
104
+ transform adding extra newlines at the end (a common behaviour for source
105
+ files, where having a trailing newline is often considered good practice).
106
+
107
+
108
+ Internals
109
+ ---------
110
+
111
+ Under the hood, this nbextension uses the [KerneExecOnCells library], a shared
112
+ library for creating Jupyter nbextensions which transform code cell text using
113
+ calls to the active kernel.
114
+
115
+ See the [shared README] for the internal model used by the nbextension.
116
+
117
+
118
+ History
119
+ -------
120
+
121
+ The project was forked by [@kenkoooo] from [@jfbercher]'s [code_prettify],
122
+ retaining most of the code.
123
+
124
+ It has since been altered to use the [KerneExecOnCells library], a shared
125
+ library for creating Jupyter nbextensions which transform code cell text using
126
+ calls to the active kernel.
127
+
128
+ [@jfbercher]: https://github.com/jfbercher
129
+ [@kenkoooo]: https://github.com/kenkoooo
130
+ [autopep8]: https://github.com/hhatto/autopep8
131
+ [code_prettify]: https://github.com/jfbercher/code_prettify
132
+ [fontawesome]: https://fontawesome.com/icons
133
+ [internals]: #Internals
134
+ [jupyter_nbextensions_configurator]: https://github.com/Jupyter-contrib/jupyter_nbextensions_configurator
135
+ [KerneExecOnCells library]: README.md
136
+ [shared README]: README.md
.local/share/jupyter/nbextensions/code_prettify/README_isort.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Sort imports using isort
2
+
3
+ This nbextension sorts imports in notebook code cells.
4
+
5
+ Under the hood, it uses a call to the current notebook kernel to reformat the code. The conversion run by the kernel uses Python's package [isort](https://github.com/timothycrosley/isort) by [Timothy Edmund Crosley](https://github.com/timothycrosley).
6
+
7
+ The nbextension provides
8
+
9
+ - a toolbar button (configurable to be added or not)
10
+
11
+ **pre-requisites:** of course, you must have the corresponding package installed:
12
+
13
+ ```
14
+ pip install isort [--user]
15
+ ```
16
+
17
+ ## Options
18
+
19
+ All options are provided by the [KerneExecOnCells library](kernel_exec_on_cell.js). There are a few nbextension-wide options, configurable using the [jupyter_nbextensions_configurator](https://github.com/Jupyter-contrib/jupyter_nbextensions_configurator) or by editing the `notebook` section config file directly. The options are as follows:
20
+
21
+ - `isort.add_toolbar_button`: Whether to add a toolbar button to transform the selected cell(s). Defaults to `true`.
22
+
23
+ - `isort.button_icon`:
24
+ A font-awesome class defining the icon used for the toolbar button and actions.
25
+ See [fontawesome] for available icon classes.
26
+ Defaults to `fa-sort`.
27
+
28
+ - `isort.show_alerts_for_not_supported_kernel`:
29
+ Whether to show alerts if the kernel is not supported.
30
+ Defaults to `false`.
31
+
32
+ - `isort.show_alerts_for_errors`: Whether to show alerts for errors in the kernel calls. Defaults to `false`.
33
+
34
+ - `isort.button_label`: Toolbar button label text. Also used in the actions' help text. Defaults to `Sort imports with isort`.
35
+
36
+ - `isort.kernel_config_map_json`: The value of this key is a string which can be parsed into a json object giving the config for each kernel language.
37
+
38
+ ## Internals
39
+
40
+ Under the hood, this nbextension uses the [kerneexeconcells library](kernel_exec_on_cell.js), a shared library for creating Jupyter nbextensions which transform code cell text using calls to the active kernel.
41
+
42
+ See the [shared README](README.md) and [kerneexeconcells library](kernel_exec_on_cell.js) for the internal model used by the nbextension.
43
+
44
+ [fontawesome]: https://fontawesome.com/icons
.local/share/jupyter/nbextensions/code_prettify/autopep8.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) Jupyter-Contrib Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+ // Authors: @kenkoooo, @jfbercher and @jcb91
4
+
5
+ define(['./kernel_exec_on_cell'], function(kernel_exec_on_cell) {
6
+ 'use strict';
7
+
8
+ var mod_name = 'autopep8';
9
+
10
+ // gives default settings
11
+ var cfg = {
12
+ add_toolbar_button: true,
13
+ hotkeys: {
14
+ process_selected: 'Alt-A',
15
+ process_all: 'Alt-Shift-A',
16
+ },
17
+ register_hotkey: true,
18
+ show_alerts_for_errors: true,
19
+ button_icon: 'fa-cog',
20
+ button_label: 'Prettify (using autopep8)',
21
+ kbd_shortcut_text: 'Prettify' // ' current cell(s)'
22
+ };
23
+
24
+ cfg.kernel_config_map = { // map of parameters for supported kernels
25
+ "python": {
26
+ "library": "import json\nimport autopep8",
27
+ "prefix": "print(json.dumps(autopep8.fix_code(u",
28
+ "postfix": ")))"
29
+ }
30
+ };
31
+
32
+ var prettifier = new kernel_exec_on_cell.define_plugin(mod_name, cfg);
33
+ prettifier.load_ipython_extension = prettifier.initialize_plugin;
34
+ return prettifier;
35
+
36
+ });
.local/share/jupyter/nbextensions/code_prettify/autopep8.yaml ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Type: Jupyter Notebook Extension
2
+ Name: Autopep8
3
+ Description: Use kernel-specific code to reformat/prettify the contents of code cells
4
+ Link: README_autopep8.md
5
+ Main: autopep8.js
6
+ Compatibility: Jupyter 4.x, 5.x
7
+ Parameters:
8
+
9
+ - name: autopep8.add_toolbar_button
10
+ description: Add a toolbar button to prettify the selected cell(s)
11
+ input_type: checkbox
12
+ default: true
13
+
14
+ - name: autopep8.button_icon
15
+ description: |
16
+ Toolbar button icon: a font-awesome class defining the icon used for the
17
+ toolbar button and actions.
18
+ See https://fontawesome.com/icons for available icons.
19
+ input_type: text
20
+ default: 'fa-cog'
21
+
22
+ - name: autopep8.button_label
23
+ description: Toolbar button label text
24
+ input_type: text
25
+ default: 'Code prettify'
26
+
27
+ - name: autopep8.register_hotkey
28
+ description: |
29
+ Register hotkeys to prettify the selected code cell(s), or all code cells
30
+ in the notebook
31
+ input_type: checkbox
32
+ default: true
33
+
34
+ - name: autopep8.hotkeys.process_selected
35
+ description: Hotkey to use to prettify the selected cell(s)
36
+ input_type: hotkey
37
+ default: 'Alt-A'
38
+
39
+ - name: autopep8.hotkeys.process_all
40
+ description: Hotkey to use to prettify the whole notebook
41
+ input_type: hotkey
42
+ default: 'Alt-Shift-A'
43
+
44
+ - name: autopep8.show_alerts_for_not_supported_kernel
45
+ description: Show alerts if the kernel is not supported
46
+ input_type: checkbox
47
+ default: false
48
+
49
+ - name: autopep8.show_alerts_for_errors
50
+ description: Show alerts for errors in the kernel prettifying calls
51
+ input_type: checkbox
52
+ default: true
53
+
54
+ - name: autopep8.kernel_config_map_json
55
+ description: |
56
+ json defining library calls required to load the kernel-specific
57
+ prettifying modules, and the prefix & postfix for the json-format string
58
+ required to make the prettifying call.
59
+ input_type: textarea
60
+ default: |
61
+ {
62
+ "python": {
63
+ "library": "import json\nimport autopep8",
64
+ "prefix": "print(json.dumps(autopep8.fix_code(u",
65
+ "postfix": ")))"
66
+ }
67
+ }
.local/share/jupyter/nbextensions/code_prettify/code_prettify.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) Jupyter-Contrib Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+ // Authors: @jfbercher and @jcb91
4
+
5
+ define(['./kernel_exec_on_cell'], function(kernel_exec_on_cell) {
6
+ 'use strict';
7
+
8
+ var mod_name = 'code_prettify';
9
+
10
+ // gives default settings
11
+ var cfg = {
12
+ add_toolbar_button: true,
13
+ hotkeys: {
14
+ process_selected: 'Ctrl-L',
15
+ process_all: 'Ctrl-Shift-L',
16
+ },
17
+ register_hotkey: true,
18
+ show_alerts_for_errors: true,
19
+ button_label: 'Code prettify',
20
+ button_icon: 'fa-legal',
21
+ kbd_shortcut_text: 'Code prettify',
22
+ };
23
+
24
+ cfg.kernel_config_map = { // map of parameters for supported kernels
25
+ "python": {
26
+ "library": ["import json",
27
+ "def yapf_reformat(cell_text):",
28
+ " import yapf.yapflib.yapf_api",
29
+ " from yapf import file_resources",
30
+ " import os",
31
+ " import re",
32
+ " style_config = file_resources.GetDefaultStyleForDir(os.getcwd())",
33
+ " cell_text = re.sub('^%', '#%#', cell_text, flags=re.M)",
34
+ " reformated_text = yapf.yapflib.yapf_api.FormatCode(cell_text, style_config=style_config)[0]",
35
+ " return re.sub('^#%#', '%', reformated_text, flags=re.M)"].join("\n"),
36
+ "prefix": "print(json.dumps(yapf_reformat(u",
37
+ "postfix": ")))"
38
+ },
39
+ "r": {
40
+ "library": "library(formatR)\nlibrary(jsonlite)",
41
+ "prefix": "cat(toJSON(paste(tidy_source(text=",
42
+ "postfix": ", output=FALSE)[['text.tidy']], collapse='\n')))"
43
+ },
44
+ "javascript": {
45
+ "library": "jsbeautify = require(" + "'js-beautify')",
46
+ // we do this + trick to prevent require.js attempting to load js-beautify when processing the AMI-style load for this module
47
+ "prefix": "console.log(JSON.stringify(jsbeautify.js_beautify(",
48
+ "postfix": ")));"
49
+ }
50
+ };
51
+
52
+
53
+ var prettifier = new kernel_exec_on_cell.define_plugin(mod_name, cfg);
54
+ prettifier.load_ipython_extension = prettifier.initialize_plugin;
55
+ return prettifier;
56
+ });
.local/share/jupyter/nbextensions/code_prettify/code_prettify.yaml ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Type: Jupyter Notebook Extension
2
+ Name: Code prettify
3
+ Description: Use kernel-specific code to reformat/prettify the contents of code cells
4
+ Link: README_code_prettify.md
5
+ Main: code_prettify.js
6
+ Compatibility: Jupyter 4.x, 5.x
7
+ Parameters:
8
+
9
+ - name: code_prettify.add_toolbar_button
10
+ description: Add a toolbar button to prettify the selected cell(s)
11
+ input_type: checkbox
12
+ default: true
13
+
14
+ - name: code_prettify.button_icon
15
+ description: |
16
+ Toolbar button icon: a font-awesome class defining the icon used for the
17
+ toolbar button and actions.
18
+ See https://fontawesome.com/icons for available icons.
19
+ input_type: text
20
+ default: 'fa-legal'
21
+
22
+ - name: code_prettify.button_label
23
+ description: Toolbar button label text
24
+ input_type: text
25
+ default: 'Code prettify'
26
+
27
+ - name: code_prettify.register_hotkey
28
+ description: |
29
+ Register hotkeys to prettify the selected code cell(s), or all code cells
30
+ in the notebook
31
+ input_type: checkbox
32
+ default: true
33
+
34
+ - name: code_prettify.hotkeys.process_selected
35
+ description: Hotkey to use to prettify the selected cell(s)
36
+ input_type: hotkey
37
+ default: 'Ctrl-L'
38
+
39
+ - name: code_prettify.hotkeys.process_all
40
+ description: Hotkey to use to prettify the whole notebook
41
+ input_type: hotkey
42
+ default: 'Ctrl-Shift-L'
43
+
44
+ - name: code_prettify.show_alerts_for_not_supported_kernel
45
+ description: Show alerts if the kernel is not supported
46
+ input_type: checkbox
47
+ default: false
48
+
49
+ - name: code_prettify.show_alerts_for_errors
50
+ description: Show alerts for errors in the kernel prettifying calls
51
+ input_type: checkbox
52
+ default: true
53
+
54
+ - name: code_prettify.kernel_config_map_json
55
+ description: |
56
+ json defining library calls required to load the kernel-specific
57
+ prettifying modules, and the prefix & postfix for the json-format string
58
+ required to make the prettifying call.
59
+ input_type: textarea
60
+ default: |
61
+ {
62
+ "python": {
63
+ "library": "import json\ndef yapf_reformat(cell_text):\n import yapf.yapflib.yapf_api\n import re\n cell_text = re.sub('^%', '#%#', cell_text, flags=re.M)\n reformated_text = yapf.yapflib.yapf_api.FormatCode(cell_text)[0]\n return re.sub('^#%#', '%', reformated_text, flags=re.M)",
64
+ "prefix": "print(json.dumps(yapf_reformat(u",
65
+ "postfix": ")))"
66
+ },
67
+ "r": {
68
+ "library": "library(formatR)\nlibrary(jsonlite)",
69
+ "prefix": "cat(toJSON(paste(tidy_source(text=",
70
+ "postfix": ", output=FALSE)[['text.tidy']], collapse='\n')))"
71
+ },
72
+ "javascript": {
73
+ "library": "jsbeautify = require('js-beautify')",
74
+ "prefix": "console.log(JSON.stringify(jsbeautify.js_beautify(",
75
+ "postfix": ")));"
76
+ }
77
+ }
.local/share/jupyter/nbextensions/code_prettify/demo-R.gif ADDED
.local/share/jupyter/nbextensions/code_prettify/demo-jv.gif ADDED
.local/share/jupyter/nbextensions/code_prettify/demo_2to3.gif ADDED
.local/share/jupyter/nbextensions/code_prettify/isort.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) Jupyter-Contrib Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+ // Authors: @benjaminabel
4
+ // Based on: code_prettify extension
5
+
6
+ define(['./kernel_exec_on_cell'], function(kernel_exec_on_cell) {
7
+ 'use strict';
8
+
9
+ var mod_name = 'isort';
10
+
11
+ // gives default settings
12
+ var cfg = {
13
+ add_toolbar_button: true,
14
+ register_hotkey: false,
15
+ show_alerts_for_errors: false,
16
+ button_icon: 'fa-sort',
17
+ button_label: 'Sort imports with isort',
18
+ kbd_shortcut_text: 'Sort imports in' // ' current cell(s)'
19
+ };
20
+
21
+ cfg.kernel_config_map = { // map of parameters for supported kernels
22
+ "python": {
23
+ "library": [
24
+ "import isort",
25
+ "import json",
26
+ "def _isort_refactor_cell(src):",
27
+ " try:",
28
+ " tree = isort.SortImports(file_contents=src).output",
29
+ " except Exception:",
30
+ " return src ",
31
+ " else:",
32
+ " return str(tree)[:-1]",
33
+ ].join('\n'),
34
+ "prefix": "print(json.dumps(_isort_refactor_cell(u",
35
+ "postfix": ")))"
36
+ }
37
+ };
38
+
39
+ var converter = new kernel_exec_on_cell.define_plugin(mod_name, cfg);
40
+ converter.load_ipython_extension = converter.initialize_plugin;
41
+ return converter;
42
+
43
+ });
.local/share/jupyter/nbextensions/code_prettify/isort.yaml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Type: Jupyter Notebook Extension
2
+ Name: isort formatter
3
+ Description: Sort imports in python files using isort
4
+ Link: README_isort.md
5
+ Main: isort.js
6
+ Compatibility: Jupyter 4.x, 5.x
7
+ Parameters:
8
+
9
+ - name: isort.add_toolbar_button
10
+ description: Add a toolbar button to convert the selected cell(s)
11
+ input_type: checkbox
12
+ default: true
13
+
14
+ - name: isort.button_icon
15
+ description: |
16
+ Toolbar button icon: a font-awesome class defining the icon used for the
17
+ toolbar button. See https://fontawesome.com/icons for available icons.
18
+ input_type: text
19
+ default: 'fa-sort'
20
+
21
+ - name: isort.button_label
22
+ description: Toolbar button label text
23
+ input_type: text
24
+ default: 'Sort imports with isort'
25
+
26
+ - name: isort.kernel_config_map_json
27
+ description: |
28
+ kernel_config_map_json:
29
+ json defining library calls required to load the kernel-specific
30
+ converting modules, and the prefix & postfix for the json-format string
31
+ required to make the converting call.
32
+ input_type: textarea
33
+ default: |
34
+ {
35
+ "python": {
36
+ "library": "import json, isort\ndef _isort_refactor_cell(src):\n try:\n tree = isort.SortImports(file_contents=src).output\n except Exception:\n return src \n else:\n return str(tree)[:-1]",
37
+ "prefix": "print(json.dumps(_isort_refactor_cell(u",
38
+ "postfix": ")))"
39
+ }
40
+ }
.local/share/jupyter/nbextensions/code_prettify/kernel_exec_on_cell.js ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) Jupyter-Contrib Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+
4
+ define([
5
+ 'jquery',
6
+ 'base/js/namespace',
7
+ 'base/js/events',
8
+ 'notebook/js/codecell',
9
+ ], function(
10
+ $,
11
+ Jupyter,
12
+ events,
13
+ codecell
14
+ ) {
15
+ 'use strict';
16
+
17
+ var CodeCell = codecell.CodeCell;
18
+
19
+ // this wrapper function allows config & hotkeys to be per-plugin
20
+ function KernelExecOnCells(mod_name, cfg) {
21
+
22
+ this.mod_name = mod_name;
23
+ this.mod_log_prefix = '[' + this.mod_name + ']';
24
+ this.mod_edit_shortcuts = {};
25
+ this.mod_cmd_shortcuts = {};
26
+ this.default_kernel_config = {
27
+ library: '',
28
+ prefix: '',
29
+ postfix: '',
30
+ replacements_json_to_kernel: [],
31
+ trim_formatted_text: true
32
+ };
33
+ // gives default settings
34
+ var default_cfg = {
35
+ add_toolbar_button: true,
36
+ hotkeys: {
37
+ process_selected: 'Ctrl-L',
38
+ process_all: 'Ctrl-Shift-L',
39
+ },
40
+ register_hotkey: true,
41
+ show_alerts_for_errors: true,
42
+ show_alerts_for_not_supported_kernel: false,
43
+ button_icon: 'fa-legal',
44
+ button_label: mod_name,
45
+ kbd_shortcut_text: mod_name,
46
+ kernel_config_map: {},
47
+ actions: null, // to be filled by register_actions
48
+ };
49
+ // extend a new object, to avoid interference with other nbextensions
50
+ // derived from the same base class
51
+ this.cfg = $.extend(true, {}, default_cfg, cfg);
52
+ // set default json string, will later be updated from config
53
+ // before it is parsed into an object
54
+ this.cfg.kernel_config_map_json = JSON.stringify(this.cfg.kernel_config_map);
55
+
56
+ } // end per-plugin wrapper define_plugin_functions
57
+
58
+ // Prototypes
59
+ // ----------
60
+
61
+ /**
62
+ * return a Promise which will resolve/reject based on the kernel message
63
+ * type.
64
+ * The returned promise will be
65
+ * - resolved if the message was not an error
66
+ * - rejected using the message's error text if msg.msg_type is "error"
67
+ */
68
+ KernelExecOnCells.prototype.convert_error_msg_to_broken_promise = function(msg) {
69
+ var that = this;
70
+ return new Promise(function(resolve, reject) {
71
+ if (msg.msg_type == 'error') {
72
+ return reject(that.mod_log_prefix + '\n Error: ' + msg.content.ename + '\n' + msg.content.evalue);
73
+ }
74
+ return resolve(msg);
75
+ });
76
+ };
77
+
78
+ KernelExecOnCells.prototype.convert_loading_library_error_msg_to_broken_promise = function(msg) {
79
+ var that = this;
80
+ return new Promise(function(resolve, reject) {
81
+ if (msg.msg_type == 'error') {
82
+ return reject(that.mod_log_prefix + '\n Error loading library for ' +
83
+ Jupyter.notebook.metadata.kernelspec.language + ':\n' +
84
+ msg.content.ename + msg.content.evalue +
85
+ '\n\nCheck that the appropriate library/module is correctly installed (read ' +
86
+ that.mod_name + '\'s documentation for details)');
87
+ }
88
+ return resolve(msg);
89
+ });
90
+ };
91
+
92
+ KernelExecOnCells.prototype.get_kernel_config = function() {
93
+ var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase();
94
+ var kernel_config = this.cfg.kernel_config_map[kernelLanguage];
95
+ // true => deep
96
+ return $.extend(true, {}, this.default_kernel_config, kernel_config);
97
+ };
98
+
99
+ KernelExecOnCells.prototype.transform_json_string_to_kernel_string = function(str, kernel_config) {
100
+ for (var ii = 0; ii < kernel_config.replacements_json_to_kernel.length; ii++) {
101
+ var from = kernel_config.replacements_json_to_kernel[ii][0];
102
+ var to = kernel_config.replacements_json_to_kernel[ii][1];
103
+ str = str.replace(from, to);
104
+ }
105
+ return str;
106
+ };
107
+
108
+ /**
109
+ * construct functions as callbacks for the autoformat cell promise. This
110
+ * is necessary because javascript lacks loop scoping, so if we don't use
111
+ * this IIFE pattern, cell_index & cell are passed by reference, and every
112
+ * callback ends up using the same value
113
+ */
114
+ KernelExecOnCells.prototype.construct_cell_callbacks = function(cell_index, cell) {
115
+ var that = this;
116
+ var on_success = function(formatted_text) {
117
+ cell.set_text(formatted_text);
118
+ };
119
+ var on_failure = function(reason) {
120
+ console.warn(
121
+ that.mod_log_prefix,
122
+ 'error processing cell', cell_index + ':\n',
123
+ reason
124
+ );
125
+ if (that.cfg.show_alerts_for_errors) {
126
+ alert(reason);
127
+ }
128
+ };
129
+ return [on_success, on_failure];
130
+ };
131
+
132
+ KernelExecOnCells.prototype.autoformat_cells = function(indices) {
133
+
134
+ if (indices === undefined) {
135
+ indices = Jupyter.notebook.get_selected_cells_indices();
136
+ }
137
+ var kernel_config = this.get_kernel_config();
138
+ for (var ii = 0; ii < indices.length; ii++) {
139
+ var cell_index = indices[ii];
140
+ var cell = Jupyter.notebook.get_cell(cell_index);
141
+ if (!(cell instanceof CodeCell)) {
142
+ continue;
143
+ }
144
+ // IIFE because otherwise cell_index & cell are passed by reference
145
+ var callbacks = this.construct_cell_callbacks(cell_index, cell);
146
+ this.autoformat_text(cell.get_text(), kernel_config).then(callbacks[0], callbacks[1]);
147
+ }
148
+ };
149
+
150
+ KernelExecOnCells.prototype.autoformat_text = function(text, kernel_config) {
151
+ var that = this;
152
+ return new Promise(function(resolve, reject) {
153
+ kernel_config = kernel_config || that.get_kernel_config();
154
+ var kernel_str = that.transform_json_string_to_kernel_string(
155
+ JSON.stringify(text), kernel_config);
156
+ Jupyter.notebook.kernel.execute(
157
+ kernel_config.prefix + kernel_str + kernel_config.postfix, {
158
+ iopub: {
159
+ output: function(msg) {
160
+ return resolve(that.convert_error_msg_to_broken_promise(msg).then(
161
+ function on_success(msg) {
162
+ // print goes to stream text => msg.content.text
163
+ // but for some kernels (eg nodejs) can be called as result of exec
164
+ if (msg.content.text !== undefined) {
165
+ var formatted_text;
166
+ try {
167
+ formatted_text = String(JSON.parse(msg.content.text));
168
+ }
169
+ catch (err) {
170
+ return Promise.reject(err);
171
+ }
172
+ if (kernel_config.trim_formatted_text) {
173
+ formatted_text = formatted_text.trim();
174
+ }
175
+ return formatted_text;
176
+ }
177
+ }
178
+ ));
179
+ }
180
+ }
181
+ }, { silent: false }
182
+ );
183
+ });
184
+ };
185
+
186
+
187
+ KernelExecOnCells.prototype.add_toolbar_button = function() {
188
+ if ($('#' + this.mod_name + '_button').length < 1) {
189
+ var button_group_id = this.mod_name + '_button';
190
+ var that = this;
191
+ Jupyter.toolbar.add_buttons_group([{
192
+ label: ' ', //space otherwise add_buttons fails -- This label is inserted as a button description AND bubble help
193
+ icon: this.cfg.button_icon,
194
+ callback: function(evt) {
195
+ that.autoformat_cells(
196
+ evt.shiftKey ? Jupyter.notebook.get_cells().map(function (cell, idx) { return idx; }) : undefined
197
+ );
198
+ },
199
+ }], button_group_id);
200
+
201
+ // Correct add_buttons_group default
202
+ // Change title --> inserts bubble help
203
+ // redefine icon to remove spurious space
204
+ var w = $('#'+ button_group_id +' > .btn')[0];
205
+ w.title = this.cfg.kbd_shortcut_text + ' selected cell(s) (add shift for all cells)'
206
+ w.innerHTML = '<i class="' + this.cfg.button_icon + ' fa"></i>'
207
+ }
208
+ }
209
+
210
+
211
+
212
+ KernelExecOnCells.prototype.add_keyboard_shortcuts = function() {
213
+ var new_shortcuts = {};
214
+ new_shortcuts[this.cfg.hotkeys.process_selected] = this.cfg.actions.process_selected.name;
215
+ new_shortcuts[this.cfg.hotkeys.process_all] = this.cfg.actions.process_all.name;
216
+ Jupyter.keyboard_manager.edit_shortcuts.add_shortcuts(new_shortcuts);
217
+ Jupyter.keyboard_manager.command_shortcuts.add_shortcuts(new_shortcuts);
218
+ };
219
+
220
+ KernelExecOnCells.prototype.register_actions = function() {
221
+ /**
222
+ * it's important that the actions created by registering keyboard
223
+ * shortcuts get different names, as otherwise a default action is
224
+ * created, whose name is a string representation of the handler
225
+ * function.
226
+ * Since this library uses the same handler function for all plugins,
227
+ * just with different contexts (different values of cfg), their
228
+ * string representations are the same, and the last one to be
229
+ * registered overwrites all previous versions.
230
+ * This is essentially an issue with notebook, but it encourages us to
231
+ * use actions, which is where notebook is going anyway.
232
+ */
233
+ var actions = this.cfg.actions = {};
234
+ var that = this;
235
+ actions.process_selected = {
236
+ help: that.cfg.kbd_shortcut_text + ' selected cell(s)',
237
+ help_index: 'yf',
238
+ icon: that.cfg.button_icon,
239
+ handler: function(evt) { that.autoformat_cells(); },
240
+ };
241
+ actions.process_all = {
242
+ help: that.cfg.kbd_shortcut_text + " the whole notebook",
243
+ help_index: 'yf',
244
+ icon: that.cfg.button_icon,
245
+ handler: function(evt) {
246
+ that.autoformat_cells(Jupyter.notebook.get_cells().map(function (cell, idx) { return idx; }));
247
+ },
248
+ };
249
+
250
+ actions.process_selected.name = Jupyter.keyboard_manager.actions.register(
251
+ actions.process_selected, 'process_selected_cells', that.mod_name);
252
+ actions.process_all.name = Jupyter.keyboard_manager.actions.register(
253
+ actions.process_all, 'process_all_cells', that.mod_name);
254
+ };
255
+
256
+ KernelExecOnCells.prototype.setup_for_new_kernel = function() {
257
+ var that = this;
258
+ var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase();
259
+ var kernel_config = this.cfg.kernel_config_map[kernelLanguage];
260
+ if (kernel_config === undefined) {
261
+ $('#' + this.mod_name + '_button').remove();
262
+ var err = this.mod_log_prefix + " Sorry, can't use kernel language " + kernelLanguage + ".\n" +
263
+ "Configurations are currently only defined for the following languages:\n" +
264
+ Object.keys(this.cfg.kernel_config_map).join(', ') + "\n" +
265
+ "See readme for more details."
266
+ if (this.cfg.show_alerts_for_not_supported_kernel) {
267
+ alert(err);
268
+ }
269
+ else {
270
+ console.error(err);
271
+ }
272
+ // also remove keyboard shortcuts
273
+ if (this.cfg.register_hotkey) {
274
+ try {
275
+ Jupyter.keyboard_manager.edit_shortcuts.remove_shortcut(this.cfg.hotkeys.process_selected);
276
+ Jupyter.keyboard_manager.edit_shortcuts.remove_shortcut(this.cfg.hotkeys.process_all);
277
+ Jupyter.keyboard_manager.command_shortcuts.remove_shortcut(this.cfg.hotkeys.process_all);
278
+ } catch (err) {}
279
+ }
280
+
281
+ } else { // kernel language is supported
282
+ if (this.cfg.add_toolbar_button) {
283
+ this.add_toolbar_button();
284
+ }
285
+ if (this.cfg.register_hotkey) {
286
+ this.add_keyboard_shortcuts();
287
+ }
288
+ Jupyter.notebook.kernel.execute(
289
+ kernel_config.library, {
290
+ iopub: {
291
+ output: function(msg) {
292
+ return that.convert_loading_library_error_msg_to_broken_promise(msg)
293
+ .catch(
294
+ function on_failure(err) {
295
+ if (that.cfg.show_alerts_for_errors) {
296
+ alert(err);
297
+ }
298
+ else {
299
+ console.error(err);
300
+ }
301
+ }
302
+
303
+ );
304
+ }
305
+ }
306
+ }, { silent: false }
307
+ );
308
+
309
+ }
310
+ };
311
+
312
+ KernelExecOnCells.prototype.initialize_plugin = function() {
313
+ var that = this;
314
+ // first, load config
315
+ Jupyter.notebook.config.loaded
316
+ // now update default config with that loaded from server
317
+ .then(function on_success() {
318
+ $.extend(true, that.cfg, Jupyter.notebook.config.data[that.mod_name]);
319
+ }, function on_error(err) {
320
+ console.warn(that.mod_log_prefix, 'error loading config:', err);
321
+ })
322
+ // next parse json config values
323
+ .then(function on_success() {
324
+ var parsed_kernel_cfg = JSON.parse(that.cfg.kernel_config_map_json);
325
+ $.extend(that.cfg.kernel_config_map, parsed_kernel_cfg);
326
+ })
327
+ // if we failed to parse the json values in the config
328
+ // using catch pattern, we attempt to continue anyway using defaults
329
+ .catch(function on_error(err) {
330
+ console.warn(
331
+ that.mod_log_prefix, 'error parsing config variable',
332
+ that.mod_name + '.kernel_config_map_json to a json object:',
333
+ err
334
+ );
335
+ })
336
+ // now do things which required the config to be loaded
337
+ .then(function on_success() {
338
+ that.register_actions(); // register actions
339
+ // kernel may already have been loaded before we get here, in which
340
+ // case we've missed the kernel_ready.Kernel event, so try ctx
341
+ if (typeof Jupyter.notebook.kernel !== "undefined" && Jupyter.notebook.kernel !== null) {
342
+ that.setup_for_new_kernel();
343
+ }
344
+
345
+ // on kernel_ready.Kernel, a new kernel has been started
346
+ events.on("kernel_ready.Kernel", function(evt, data) {
347
+ console.log(that.mod_log_prefix, 'restarting for new kernel_ready.Kernel event');
348
+ that.setup_for_new_kernel();
349
+ });
350
+ }).catch(function on_error(err) {
351
+ console.error(that.mod_log_prefix, 'error loading:', err);
352
+ });
353
+ };
354
+
355
+ return {define_plugin: KernelExecOnCells};
356
+ });