coconut-develop 3.0.2.post0.dev3__tar.gz → 3.0.2.post0.dev5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/DOCS.md +159 -102
- coconut-develop-3.0.2.post0.dev5/PKG-INFO +140 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/__init__.pyi +11 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/cli.py +8 -2
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/command.py +14 -3
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/compiler.py +1 -1
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/header.py +49 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/templates/header.py_template +51 -12
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/constants.py +4 -2
- coconut-develop-3.0.2.post0.dev5/coconut/icoconut/coconut/kernel.json +11 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/root.py +1 -1
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/main_test.py +13 -10
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/primary.coco +1 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/specific.coco +2 -2
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_sys/target_sys_test.coco +72 -1
- coconut-develop-3.0.2.post0.dev3/PKG-INFO +0 -137
- coconut-develop-3.0.2.post0.dev3/coconut/icoconut/coconut/kernel.json +0 -11
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/CONTRIBUTING.md +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/FAQ.md +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/HELP.md +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/LICENSE.txt +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/MANIFEST.in +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/README.rst +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/py.typed +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/_coconut/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/_coconut/__init__.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/_coconut/py.typed +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__coconut__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__coconut__.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__init__.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__main__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/_pyparsing.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/api.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/api.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/__init__.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/command.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/mypy.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/resources/zcoconut.pth +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/util.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/watch.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/grammar.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/matching.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/util.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/convenience.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/convenience.pyi +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/exceptions.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/highlighter.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/__main__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/coconut_py/kernel.json +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/coconut_py2/kernel.json +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/coconut_py3/kernel.json +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/embed.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/root.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/integrations.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/main.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/py.typed +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/requirements.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/terminal.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/__init__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/__main__.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/constants_test.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/__init__.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/main.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/suite.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/tutorial.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/util.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/non_strict/non_strict_test.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_2/py2_test.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_3/py3_test.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_35/py35_test.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_36/py36_test.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_38/py38_test.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/extras.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/runnable.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/runner.coco +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/util.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut_develop.egg-info/SOURCES.txt +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/conf.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/pyproject.toml +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/setup.cfg +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/setup.py +0 -0
- {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/xontrib/coconut.py +0 -0
|
@@ -143,74 +143,77 @@ dest destination directory for compiled files (defaults to
|
|
|
143
143
|
##### Optional Arguments
|
|
144
144
|
|
|
145
145
|
```
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
146
|
+
-h, --help show this help message and exit
|
|
147
|
+
--and source [dest ...]
|
|
148
|
+
add an additional source/dest pair to compile (dest is optional)
|
|
149
|
+
-v, -V, --version print Coconut and Python version information
|
|
150
|
+
-t version, --target version
|
|
151
|
+
specify target Python version (defaults to universal)
|
|
152
|
+
-i, --interact force the interpreter to start (otherwise starts if no other command
|
|
153
|
+
is given) (implies --run)
|
|
154
|
+
-p, --package compile source as part of a package (defaults to only if source is a
|
|
155
|
+
directory)
|
|
156
|
+
-a, --standalone, --stand-alone
|
|
157
|
+
compile source as standalone files (defaults to only if source is a
|
|
158
|
+
single file)
|
|
159
|
+
-l, --line-numbers, --linenumbers
|
|
160
|
+
force enable line number comments (--line-numbers are enabled by
|
|
161
|
+
default unless --minify is passed)
|
|
162
|
+
--no-line-numbers, --nolinenumbers
|
|
163
|
+
disable line number comments (opposite of --line-numbers)
|
|
164
|
+
-k, --keep-lines, --keeplines
|
|
165
|
+
include source code in comments for ease of debugging
|
|
166
|
+
-w, --watch watch a directory and recompile on changes
|
|
167
|
+
-r, --run execute compiled Python
|
|
168
|
+
-n, --no-write, --nowrite
|
|
169
|
+
disable writing compiled Python
|
|
170
|
+
-d, --display print compiled Python
|
|
171
|
+
-q, --quiet suppress all informational output (combine with --display to write
|
|
172
|
+
runnable code to stdout)
|
|
173
|
+
-s, --strict enforce code cleanliness standards
|
|
174
|
+
--no-tco, --notco disable tail call optimization
|
|
175
|
+
--no-wrap-types, --nowraptypes
|
|
176
|
+
disable wrapping type annotations in strings and turn off 'from
|
|
177
|
+
__future__ import annotations' behavior
|
|
178
|
+
-c code, --code code run Coconut passed in as a string (can also be piped into stdin)
|
|
179
|
+
-j processes, --jobs processes
|
|
180
|
+
number of additional processes to use (defaults to 'sys') (0 is no
|
|
181
|
+
additional processes; 'sys' uses machine default)
|
|
182
|
+
-f, --force force re-compilation even when source code and compilation parameters
|
|
183
|
+
haven't changed
|
|
184
|
+
--minify reduce size of compiled Python
|
|
185
|
+
--jupyter ..., --ipython ...
|
|
186
|
+
run Jupyter/IPython with Coconut as the kernel (remaining args passed
|
|
187
|
+
to Jupyter)
|
|
188
|
+
--mypy ... run MyPy on compiled Python (remaining args passed to MyPy) (implies
|
|
189
|
+
--package --line-numbers)
|
|
190
|
+
--argv ..., --args ...
|
|
191
|
+
set sys.argv to source plus remaining args for use in the Coconut
|
|
192
|
+
script being run
|
|
193
|
+
--tutorial open Coconut's tutorial in the default web browser
|
|
194
|
+
--docs, --documentation
|
|
195
|
+
open Coconut's documentation in the default web browser
|
|
196
|
+
--style name set Pygments syntax highlighting style (or 'list' to list styles)
|
|
197
|
+
(defaults to COCONUT_STYLE environment variable if it exists,
|
|
198
|
+
otherwise 'default')
|
|
199
|
+
--history-file path set history file (or '' for no file) (can be modified by setting
|
|
200
|
+
COCONUT_HOME environment variable)
|
|
201
|
+
--vi-mode, --vimode enable vi mode in the interpreter (currently set to False) (can be
|
|
202
|
+
modified by setting COCONUT_VI_MODE environment variable)
|
|
203
|
+
--recursion-limit limit, --recursionlimit limit
|
|
204
|
+
set maximum recursion depth in compiler (defaults to 1920) (when
|
|
205
|
+
increasing --recursion-limit, you may also need to increase --stack-
|
|
206
|
+
size)
|
|
207
|
+
--stack-size kbs, --stacksize kbs
|
|
208
|
+
run the compiler in a separate thread with the given stack size in
|
|
209
|
+
kilobytes
|
|
210
|
+
--site-install, --siteinstall
|
|
211
|
+
set up coconut.api to be imported on Python start
|
|
212
|
+
--site-uninstall, --siteuninstall
|
|
213
|
+
revert the effects of --site-install
|
|
214
|
+
--verbose print verbose debug output
|
|
215
|
+
--trace print verbose parsing data (only available in coconut-develop)
|
|
216
|
+
--profile collect and print timing info (only available in coconut-develop)
|
|
214
217
|
```
|
|
215
218
|
|
|
216
219
|
#### Coconut Scripts
|
|
@@ -221,7 +224,7 @@ coconut-run <source> <args>
|
|
|
221
224
|
```
|
|
222
225
|
as an alias for
|
|
223
226
|
```
|
|
224
|
-
coconut --quiet --target sys --
|
|
227
|
+
coconut --quiet --target sys --keep-lines --run <source> --argv <args>
|
|
225
228
|
```
|
|
226
229
|
which will quietly compile and run `<source>`, passing any additional arguments to the script, mimicking how the `python` command works.
|
|
227
230
|
|
|
@@ -732,6 +735,8 @@ All function composition operators also have in-place versions (e.g. `..=`).
|
|
|
732
735
|
|
|
733
736
|
Since all forms of function composition always call the first function in the composition (`f` in `f ..> g` and `g` in `f <.. g`) with exactly the arguments passed into the composition, all forms of function composition will preserve all metadata attached to the first function in the composition, including the function's [signature](https://docs.python.org/3/library/inspect.html#inspect.signature) and any of that function's attributes.
|
|
734
737
|
|
|
738
|
+
_Note: for composing `async` functions, see [`and_then` and `and_then_await`](#and_then-and-and_then_await)._
|
|
739
|
+
|
|
735
740
|
##### Example
|
|
736
741
|
|
|
737
742
|
**Coconut:**
|
|
@@ -3341,6 +3346,54 @@ res, err = safe_call(-> 1 / 0) |> fmap$(.+1)
|
|
|
3341
3346
|
**Python:**
|
|
3342
3347
|
_Can't be done without a complex `Expected` definition. See the compiled code for the Python syntax._
|
|
3343
3348
|
|
|
3349
|
+
#### `ident`
|
|
3350
|
+
|
|
3351
|
+
**ident**(_x_, *, _side\_effect_=`None`)
|
|
3352
|
+
|
|
3353
|
+
Coconut's `ident` is the identity function, generally equivalent to `x -> x`.
|
|
3354
|
+
|
|
3355
|
+
`ident` also accepts one keyword-only argument, `side_effect`, which specifies a function to call on the argument before it is returned. Thus, `ident` is effectively equivalent to:
|
|
3356
|
+
```coconut
|
|
3357
|
+
def ident(x, *, side_effect=None):
|
|
3358
|
+
if side_effect is not None:
|
|
3359
|
+
side_effect(x)
|
|
3360
|
+
return x
|
|
3361
|
+
```
|
|
3362
|
+
|
|
3363
|
+
`ident` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)) or for debugging [pipes](#pipes) where `ident$(side_effect=print)` can let you see what is being piped.
|
|
3364
|
+
|
|
3365
|
+
#### `const`
|
|
3366
|
+
|
|
3367
|
+
**const**(_value_)
|
|
3368
|
+
|
|
3369
|
+
Coconut's `const` simply constructs a function that, whatever its arguments, just returns the given value. Thus, `const` is equivalent to a pickleable version of
|
|
3370
|
+
```coconut
|
|
3371
|
+
def const(value) = (*args, **kwargs) -> value
|
|
3372
|
+
```
|
|
3373
|
+
|
|
3374
|
+
`const` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)).
|
|
3375
|
+
|
|
3376
|
+
#### `flip`
|
|
3377
|
+
|
|
3378
|
+
**flip**(_func_, _nargs_=`None`)
|
|
3379
|
+
|
|
3380
|
+
Coconut's `flip(f, nargs=None)` is a higher-order function that, given a function `f`, returns a new function with reversed argument order. If `nargs` is passed, only the first `nargs` arguments are reversed.
|
|
3381
|
+
|
|
3382
|
+
For the binary case, `flip` works as
|
|
3383
|
+
```coconut
|
|
3384
|
+
flip(f, 2)(x, y) == f(y, x)
|
|
3385
|
+
```
|
|
3386
|
+
such that `flip$(?, 2)` implements the `C` combinator (`flip` in Haskell).
|
|
3387
|
+
|
|
3388
|
+
In the general case, `flip` is equivalent to a pickleable version of
|
|
3389
|
+
```coconut
|
|
3390
|
+
def flip(f, nargs=None) =
|
|
3391
|
+
(*args, **kwargs) -> (
|
|
3392
|
+
f(*args[::-1], **kwargs) if nargs is None
|
|
3393
|
+
else f(*(args[nargs-1::-1] + args[nargs:]), **kwargs)
|
|
3394
|
+
)
|
|
3395
|
+
```
|
|
3396
|
+
|
|
3344
3397
|
#### `lift`
|
|
3345
3398
|
|
|
3346
3399
|
**lift**(_func_)
|
|
@@ -3388,54 +3441,58 @@ def plus_and_times(x, y):
|
|
|
3388
3441
|
return x + y, x * y
|
|
3389
3442
|
```
|
|
3390
3443
|
|
|
3391
|
-
#### `
|
|
3444
|
+
#### `and_then` and `and_then_await`
|
|
3392
3445
|
|
|
3393
|
-
|
|
3446
|
+
Coconut provides the `and_then` and `and_then_await` built-ins for composing `async` functions. Specifically:
|
|
3447
|
+
* To forwards compose an async function `async_f` with a normal function `g` (such that `g` is called on the result of `await`ing `async_f`), write ``async_f `and_then` g``.
|
|
3448
|
+
* To forwards compose an async function `async_f` with another async function `async_g` (such that `async_g` is called on the result of `await`ing `async_f`, and then `async_g` is itself awaited), write ``async_f `and_then_await` async_g``.
|
|
3449
|
+
* To forwards compose a normal function `f` with an async function `async_g` (such that `async_g` is called on the result of `f`), just write `f ..> async_g`.
|
|
3394
3450
|
|
|
3395
|
-
|
|
3451
|
+
Note that all of the above will always result in the resulting composition being an `async` function.
|
|
3396
3452
|
|
|
3397
|
-
|
|
3453
|
+
The built-ins are effectively equivalent to:
|
|
3398
3454
|
```coconut
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3455
|
+
def and_then[**T, U, V](
|
|
3456
|
+
first_async_func: async (**T) -> U,
|
|
3457
|
+
second_func: U -> V,
|
|
3458
|
+
) -> async (**T) -> V =
|
|
3459
|
+
async def (*args, **kwargs) -> (
|
|
3460
|
+
first_async_func(*args, **kwargs)
|
|
3461
|
+
|> await
|
|
3462
|
+
|> second_func
|
|
3463
|
+
)
|
|
3402
3464
|
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3465
|
+
def and_then_await[**T, U, V](
|
|
3466
|
+
first_async_func: async (**T) -> U,
|
|
3467
|
+
second_async_func: async U -> V,
|
|
3468
|
+
) -> async (**T) -> V =
|
|
3469
|
+
async def (*args, **kwargs) -> (
|
|
3470
|
+
first_async_func(*args, **kwargs)
|
|
3471
|
+
|> await
|
|
3472
|
+
|> second_async_func
|
|
3473
|
+
|> await
|
|
3409
3474
|
)
|
|
3410
3475
|
```
|
|
3411
3476
|
|
|
3412
|
-
|
|
3477
|
+
Like normal [function composition](#function-composition), `and_then` and `and_then_await` will preserve all metadata attached to the first function in the composition.
|
|
3413
3478
|
|
|
3414
|
-
|
|
3479
|
+
##### Example
|
|
3415
3480
|
|
|
3416
|
-
Coconut
|
|
3481
|
+
**Coconut:**
|
|
3417
3482
|
```coconut
|
|
3418
|
-
|
|
3483
|
+
load_and_send_data = (
|
|
3484
|
+
load_data_async()
|
|
3485
|
+
`and_then` proc_data
|
|
3486
|
+
`and_then_await` send_data
|
|
3487
|
+
)
|
|
3419
3488
|
```
|
|
3420
3489
|
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
**ident**(_x_, *, _side\_effect_=`None`)
|
|
3426
|
-
|
|
3427
|
-
Coconut's `ident` is the identity function, generally equivalent to `x -> x`.
|
|
3428
|
-
|
|
3429
|
-
`ident` also accepts one keyword-only argument, `side_effect`, which specifies a function to call on the argument before it is returned. Thus, `ident` is effectively equivalent to:
|
|
3430
|
-
```coconut
|
|
3431
|
-
def ident(x, *, side_effect=None):
|
|
3432
|
-
if side_effect is not None:
|
|
3433
|
-
side_effect(x)
|
|
3434
|
-
return x
|
|
3490
|
+
**Python:**
|
|
3491
|
+
```coconut_python
|
|
3492
|
+
async def load_and_send_data():
|
|
3493
|
+
return await send_data(proc_data(await load_data_async()))
|
|
3435
3494
|
```
|
|
3436
3495
|
|
|
3437
|
-
`ident` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)) or for debugging [pipes](#pipes) where `ident$(side_effect=print)` can let you see what is being piped.
|
|
3438
|
-
|
|
3439
3496
|
### Built-Ins for Working with Iterators
|
|
3440
3497
|
|
|
3441
3498
|
```{contents}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: coconut-develop
|
|
3
|
+
Version: 3.0.2.post0.dev5
|
|
4
|
+
Summary: Simple, elegant, Pythonic functional programming.
|
|
5
|
+
Home-page: http://coconut-lang.org
|
|
6
|
+
Author: Evan Hubinger
|
|
7
|
+
Author-email: evanjhub@gmail.com
|
|
8
|
+
License: Apache 2.0
|
|
9
|
+
Keywords: functional,programming,language,compiler,pattern,pattern-matching,algebraic,data type,data types,lambda,lambdas,lazy,evaluation,lazy list,lazy lists,tail,recursion,call,recursive,infix,function,composition,compose,partial,application,currying,curry,pipeline,pipe,unicode,operator,operators,frozenset,literal,syntax,destructuring,assignment,fold,datamaker,prepattern,iterator,none,coalesce,coalescing,statement,lru_cache,memoization,backport,typing,embed,PEP 622,overrides,islice,itertools,functools,TYPE_CHECKING,Expected,breakpoint,help,reduce,takewhile,dropwhile,tee,count,makedata,consume,parallel_map,addpattern,recursive_iterator,concurrent_map,fmap,starmap,reiterable,scan,groupsof,memoize,zip_longest,override,flatten,ident,call,safe_call,flip,const,lift,all_equal,collectby,multi_enumerate,cartesian_product,multiset,cycle,windowsof,and_then,and_then_await,py_chr,py_dict,py_hex,py_input,py_int,py_map,py_object,py_oct,py_open,py_print,py_range,py_str,py_super,py_zip,py_filter,py_reversed,py_enumerate,py_raw_input,py_xrange,py_repr,py_breakpoint,_namedtuple_of,reveal_type,reveal_locals,MatchError,__fmap__,__iter_getitem__,data,match,case,cases,where,addpattern,then,operator,type,copyclosure,λ
|
|
10
|
+
Platform: UNKNOWN
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Software Development
|
|
15
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
16
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
17
|
+
Classifier: Topic :: Software Development :: Interpreters
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Classifier: Environment :: Console
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python
|
|
23
|
+
Classifier: Programming Language :: Python :: 2
|
|
24
|
+
Classifier: Programming Language :: Python :: 2.6
|
|
25
|
+
Classifier: Programming Language :: Python :: 2.7
|
|
26
|
+
Classifier: Programming Language :: Python :: 3
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.2
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.3
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.4
|
|
30
|
+
Classifier: Programming Language :: Python :: 3.5
|
|
31
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
37
|
+
Classifier: Programming Language :: Other
|
|
38
|
+
Classifier: Programming Language :: Other Scripting Engines
|
|
39
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
40
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
41
|
+
Classifier: Framework :: IPython
|
|
42
|
+
Classifier: Framework :: Jupyter
|
|
43
|
+
Classifier: Typing :: Typed
|
|
44
|
+
Provides-Extra: kernel
|
|
45
|
+
Provides-Extra: watch
|
|
46
|
+
Provides-Extra: mypy
|
|
47
|
+
Provides-Extra: backports
|
|
48
|
+
Provides-Extra: xonsh
|
|
49
|
+
Provides-Extra: jupyter
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Provides-Extra: ipython
|
|
52
|
+
Provides-Extra: docs
|
|
53
|
+
Provides-Extra: tests
|
|
54
|
+
Provides-Extra: dev
|
|
55
|
+
License-File: LICENSE.txt
|
|
56
|
+
|
|
57
|
+
|logo| Coconut
|
|
58
|
+
==============
|
|
59
|
+
|
|
60
|
+
..
|
|
61
|
+
<insert toctree here>
|
|
62
|
+
|
|
63
|
+
.. |logo| image:: https://github.com/evhub/coconut/raw/gh-pages/favicon-32x32.png
|
|
64
|
+
|
|
65
|
+
.. image:: https://opencollective.com/coconut/backers/badge.svg
|
|
66
|
+
:alt: Backers on Open Collective
|
|
67
|
+
:target: #backers
|
|
68
|
+
.. image:: https://opencollective.com/coconut/sponsors/badge.svg
|
|
69
|
+
:alt: Sponsors on Open Collective
|
|
70
|
+
:target: #sponsors
|
|
71
|
+
.. image:: https://badges.gitter.im/evhub/coconut.svg
|
|
72
|
+
:alt: Join the chat at https://gitter.im/evhub/coconut
|
|
73
|
+
:target: https://gitter.im/evhub/coconut?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
|
74
|
+
|
|
75
|
+
Coconut (`coconut-lang.org`__) is a variant of Python_ that **adds on top of Python syntax** new features for simple, elegant, Pythonic **functional programming**.
|
|
76
|
+
|
|
77
|
+
__ Coconut_
|
|
78
|
+
.. _Coconut: http://coconut-lang.org/
|
|
79
|
+
|
|
80
|
+
Coconut is developed on GitHub_ and hosted on PyPI_. Installing Coconut is as easy as opening a command prompt and entering::
|
|
81
|
+
|
|
82
|
+
pip install coconut
|
|
83
|
+
|
|
84
|
+
To help you get started, check out these links for more information about Coconut:
|
|
85
|
+
|
|
86
|
+
- Tutorial_: If you're new to Coconut, a good place to start is Coconut's **tutorial**.
|
|
87
|
+
- Documentation_: If you're looking for info about a specific feature, check out Coconut's **documentation**.
|
|
88
|
+
- `Online Interpreter`_: If you want to try Coconut in your browser, check out Coconut's **online interpreter**.
|
|
89
|
+
- FAQ_: If you have general questions about Coconut—like who Coconut is built for and whether or not you should use it—Coconut's frequently asked questions are often the best place to start.
|
|
90
|
+
- `Create a New Issue <https://github.com/evhub/coconut/issues/new>`_: If you're having a problem with Coconut, creating a new issue detailing the problem will allow it to be addressed as soon as possible.
|
|
91
|
+
- Gitter_: For any questions, concerns, or comments about anything Coconut-related, ask around at Coconut's Gitter, a GitHub-integrated chat room for Coconut developers.
|
|
92
|
+
- Releases_: Want to know what's been added in recent Coconut versions? Check out the release log for all the new features and fixes.
|
|
93
|
+
|
|
94
|
+
.. _Python: https://www.python.org/
|
|
95
|
+
.. _PyPI: https://pypi.python.org/pypi/coconut
|
|
96
|
+
.. _Tutorial: http://coconut.readthedocs.io/en/latest/HELP.html
|
|
97
|
+
.. _Documentation: http://coconut.readthedocs.io/en/latest/DOCS.html
|
|
98
|
+
.. _`Online Interpreter`: https://cs121-team-panda.github.io/coconut-interpreter
|
|
99
|
+
.. _FAQ: http://coconut.readthedocs.io/en/latest/FAQ.html
|
|
100
|
+
.. _GitHub: https://github.com/evhub/coconut
|
|
101
|
+
.. _Gitter: https://gitter.im/evhub/coconut
|
|
102
|
+
.. _Releases: https://github.com/evhub/coconut/releases
|
|
103
|
+
|
|
104
|
+
Credits
|
|
105
|
+
+++++++
|
|
106
|
+
|
|
107
|
+
Contributors
|
|
108
|
+
------------
|
|
109
|
+
|
|
110
|
+
This project exists thanks to all the people who contribute! `Become a contributor`__.
|
|
111
|
+
|
|
112
|
+
.. image:: https://opencollective.com/coconut/contributors.svg?width=890&button=false
|
|
113
|
+
:target: https://github.com/evhub/coconut/graphs/contributors
|
|
114
|
+
|
|
115
|
+
__ Contributor_
|
|
116
|
+
.. _Contributor: http://coconut.readthedocs.io/en/develop/CONTRIBUTING.html
|
|
117
|
+
|
|
118
|
+
Backers
|
|
119
|
+
-------
|
|
120
|
+
|
|
121
|
+
Thank you to all our backers! `Become a backer`__.
|
|
122
|
+
|
|
123
|
+
.. image:: https://opencollective.com/coconut/backers.svg?width=890
|
|
124
|
+
:target: https://opencollective.com/coconut#backers
|
|
125
|
+
|
|
126
|
+
__ Backer_
|
|
127
|
+
.. _Backer: https://opencollective.com/coconut#backer
|
|
128
|
+
|
|
129
|
+
Sponsors
|
|
130
|
+
--------
|
|
131
|
+
|
|
132
|
+
Support Coconut by becoming a sponsor. Your logo will show up here with a link to your website. `Become a sponsor`__.
|
|
133
|
+
|
|
134
|
+
.. image:: https://opencollective.com/XX/sponsor/0/avatar.svg
|
|
135
|
+
:target: https://opencollective.com/coconut/sponsor/0/website
|
|
136
|
+
|
|
137
|
+
__ Sponsor_
|
|
138
|
+
.. _Sponsor: https://opencollective.com/coconut#sponsor
|
|
139
|
+
|
|
140
|
+
|
{coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/__init__.pyi
RENAMED
|
@@ -530,6 +530,17 @@ def _coconut_base_compose(
|
|
|
530
530
|
) -> _t.Callable[[_T], _t.Any]: ...
|
|
531
531
|
|
|
532
532
|
|
|
533
|
+
def and_then(
|
|
534
|
+
first_async_func: _t.Callable[_P, _t.Awaitable[_U]],
|
|
535
|
+
second_func: _t.Callable[[_U], _V],
|
|
536
|
+
) -> _t.Callable[_P, _t.Awaitable[_V]]: ...
|
|
537
|
+
|
|
538
|
+
def and_then_await(
|
|
539
|
+
first_async_func: _t.Callable[_P, _t.Awaitable[_U]],
|
|
540
|
+
second_async_func: _t.Callable[[_U], _t.Awaitable[_V]],
|
|
541
|
+
) -> _t.Callable[_P, _t.Awaitable[_V]]: ...
|
|
542
|
+
|
|
543
|
+
|
|
533
544
|
# all forward/backward/none composition functions MUST be kept in sync:
|
|
534
545
|
|
|
535
546
|
# @_t.overload
|
{coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/cli.py
RENAMED
|
@@ -115,7 +115,13 @@ arguments.add_argument(
|
|
|
115
115
|
arguments.add_argument(
|
|
116
116
|
"-l", "--line-numbers", "--linenumbers",
|
|
117
117
|
action="store_true",
|
|
118
|
-
help="
|
|
118
|
+
help="force enable line number comments (--line-numbers are enabled by default unless --minify is passed)",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
arguments.add_argument(
|
|
122
|
+
"--no-line-numbers", "--nolinenumbers",
|
|
123
|
+
action="store_true",
|
|
124
|
+
help="disable line number comments (opposite of --line-numbers)",
|
|
119
125
|
)
|
|
120
126
|
|
|
121
127
|
arguments.add_argument(
|
|
@@ -209,7 +215,7 @@ arguments.add_argument(
|
|
|
209
215
|
"--mypy",
|
|
210
216
|
type=str,
|
|
211
217
|
nargs=argparse.REMAINDER,
|
|
212
|
-
help="run MyPy on compiled Python (remaining args passed to MyPy) (implies --package)",
|
|
218
|
+
help="run MyPy on compiled Python (remaining args passed to MyPy) (implies --package --line-numbers)",
|
|
213
219
|
)
|
|
214
220
|
|
|
215
221
|
arguments.add_argument(
|
{coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/command.py
RENAMED
|
@@ -229,8 +229,10 @@ class Command(object):
|
|
|
229
229
|
# validate general command args
|
|
230
230
|
if args.stack_size and args.stack_size % 4 != 0:
|
|
231
231
|
logger.warn("--stack-size should generally be a multiple of 4, not {stack_size} (to support 4 KB pages)".format(stack_size=args.stack_size))
|
|
232
|
-
if args.mypy is not None and args.
|
|
233
|
-
logger.warn("
|
|
232
|
+
if args.mypy is not None and args.no_line_numbers:
|
|
233
|
+
logger.warn("using --mypy running with --no-line-numbers is not recommended; mypy error messages won't include Coconut line numbers")
|
|
234
|
+
if args.line_numbers and args.no_line_numbers:
|
|
235
|
+
raise CoconutException("cannot compile with both --line-numbers and --no-line-numbers")
|
|
234
236
|
if args.site_install and args.site_uninstall:
|
|
235
237
|
raise CoconutException("cannot --site-install and --site-uninstall simultaneously")
|
|
236
238
|
for and_args in getattr(args, "and") or []:
|
|
@@ -266,11 +268,20 @@ class Command(object):
|
|
|
266
268
|
self.argv_args = list(args.argv)
|
|
267
269
|
|
|
268
270
|
# process general compiler args
|
|
271
|
+
if args.line_numbers:
|
|
272
|
+
line_numbers = True
|
|
273
|
+
elif args.no_line_numbers:
|
|
274
|
+
line_numbers = False
|
|
275
|
+
else:
|
|
276
|
+
line_numbers = (
|
|
277
|
+
not args.minify
|
|
278
|
+
or args.mypy is not None
|
|
279
|
+
)
|
|
269
280
|
self.setup(
|
|
270
281
|
target=args.target,
|
|
271
282
|
strict=args.strict,
|
|
272
283
|
minify=args.minify,
|
|
273
|
-
line_numbers=
|
|
284
|
+
line_numbers=line_numbers,
|
|
274
285
|
keep_lines=args.keep_lines,
|
|
275
286
|
no_tco=args.no_tco,
|
|
276
287
|
no_wrap=args.no_wrap_types,
|
{coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/compiler.py
RENAMED
|
@@ -3499,7 +3499,7 @@ if not {check_var}:
|
|
|
3499
3499
|
return "await " + await_expr
|
|
3500
3500
|
elif self.target_info >= (3, 3):
|
|
3501
3501
|
# we have to wrap the yield here so it doesn't cause the function to be detected as an async generator
|
|
3502
|
-
return self.wrap_passthrough("(yield from " + await_expr + ")"
|
|
3502
|
+
return self.wrap_passthrough("(yield from " + await_expr + ")")
|
|
3503
3503
|
else:
|
|
3504
3504
|
# this yield is fine because we can detect the _coconut.asyncio.From
|
|
3505
3505
|
return "(yield _coconut.asyncio.From(" + await_expr + "))"
|
{coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/header.py
RENAMED
|
@@ -488,6 +488,55 @@ items = _coconut.collections.Counter.viewitems
|
|
|
488
488
|
indent=1,
|
|
489
489
|
newline=True,
|
|
490
490
|
),
|
|
491
|
+
def_async_compose_call=prepare(
|
|
492
|
+
r'''
|
|
493
|
+
async def __call__(self, *args, **kwargs):
|
|
494
|
+
arg = await self._coconut_func(*args, **kwargs)
|
|
495
|
+
for f, await_f in self._coconut_func_infos:
|
|
496
|
+
arg = f(arg)
|
|
497
|
+
if await_f:
|
|
498
|
+
arg = await arg
|
|
499
|
+
return arg
|
|
500
|
+
''' if target_info >= (3, 5) else
|
|
501
|
+
pycondition(
|
|
502
|
+
(3, 5),
|
|
503
|
+
if_ge=r'''
|
|
504
|
+
_coconut_call_ns = {}
|
|
505
|
+
_coconut_exec("""async def __call__(self, *args, **kwargs):
|
|
506
|
+
arg = await self._coconut_func(*args, **kwargs)
|
|
507
|
+
for f, await_f in self._coconut_func_infos:
|
|
508
|
+
arg = f(arg)
|
|
509
|
+
if await_f:
|
|
510
|
+
arg = await arg
|
|
511
|
+
return arg""", _coconut_call_ns)
|
|
512
|
+
__call__ = _coconut_call_ns["__call__"]
|
|
513
|
+
''',
|
|
514
|
+
# we got the below code by compiling the above code with yield from instead of await and --target 2
|
|
515
|
+
if_lt=r'''
|
|
516
|
+
@_coconut.asyncio.coroutine
|
|
517
|
+
def __call__(self, *args, **kwargs):
|
|
518
|
+
to_await = _coconut.iter(self._coconut_func(*args, **kwargs))
|
|
519
|
+
while True:
|
|
520
|
+
try:
|
|
521
|
+
yield _coconut.next(to_await)
|
|
522
|
+
except _coconut.StopIteration as stop_it:
|
|
523
|
+
arg = stop_it.args[0] if _coconut.len(stop_it.args) > 0 else None
|
|
524
|
+
break
|
|
525
|
+
for f, await_f in self._coconut_func_infos:
|
|
526
|
+
arg = f(arg)
|
|
527
|
+
if await_f:
|
|
528
|
+
to_await = _coconut.iter(arg)
|
|
529
|
+
while True:
|
|
530
|
+
try:
|
|
531
|
+
yield _coconut.next(to_await)
|
|
532
|
+
except _coconut.StopIteration as stop_it:
|
|
533
|
+
arg = stop_it.args[0] if _coconut.len(stop_it.args) > 0 else None
|
|
534
|
+
break
|
|
535
|
+
raise _coconut.StopIteration(arg)
|
|
536
|
+
''',
|
|
537
|
+
),
|
|
538
|
+
indent=1
|
|
539
|
+
),
|
|
491
540
|
|
|
492
541
|
# used in the second round
|
|
493
542
|
tco_comma="_coconut_tail_call, _coconut_tco, " if not no_tco else "",
|