coconut-develop 3.1.2.post0.dev11__tar.gz → 3.2.0.post0.dev2__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.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/.claude/CLAUDE.md +14 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/.claude/settings.local.json +10 -3
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/DOCS.md +70 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/HELP.md +2 -2
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/PKG-INFO +3 -26
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/README.rst +1 -3
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/compiler.py +48 -11
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/grammar.py +8 -2
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/header.py +0 -11
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/templates/header.py_template +4 -1
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/util.py +8 -2
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/constants.py +4 -2
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/root.py +14 -2
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/main_test.py +5 -3
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/primary_2.coco +80 -4
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/extras.coco +14 -2
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/CONTRIBUTING.md +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/FAQ.md +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/LICENSE.txt +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/MANIFEST.in +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/__coconut__/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/__coconut__/__init__.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/__coconut__/py.typed +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/_coconut/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/_coconut/__init__.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/_coconut/py.typed +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__coconut__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__coconut__.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__init__.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__main__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/_pyparsing.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/api.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/api.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/__init__.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/cli.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/command.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/command.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/mypy.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/resources/zcoconut.pth +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/util.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/watch.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/matching.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/convenience.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/convenience.pyi +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/exceptions.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/highlighter.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/__main__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/coconut/kernel.json +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/coconut_py/kernel.json +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/coconut_py2/kernel.json +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/coconut_py3/kernel.json +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/embed.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/root.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/integrations.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/main.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/py.typed +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/requirements.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/terminal.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/__init__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/__main__.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/constants_test.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/__init__.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/__main__.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/main.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/primary_1.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/specific.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/suite.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/tutorial.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/agnostic/util.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/non_strict/non_strict_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_2/py2_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_3/py3_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_311/py311_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_314/py314_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_35/py35_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_36/py36_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_38/py38_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/cocotest/target_sys/target_sys_test.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/importable.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/runnable.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/runner.coco +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/util.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut_develop.egg-info/SOURCES.txt +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/conf.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/pyproject.toml +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/setup.cfg +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/setup.py +0 -0
- {coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/xontrib/coconut.py +0 -0
|
@@ -75,3 +75,17 @@ To add tests: write Coconut code with `assert` statements in the appropriate `.c
|
|
|
75
75
|
## Branches
|
|
76
76
|
- `master` - Stable releases
|
|
77
77
|
- `develop` - Active development (default branch for contributions)
|
|
78
|
+
|
|
79
|
+
## Debugging GitHub Actions
|
|
80
|
+
|
|
81
|
+
### Viewing Logs for a Specific Job
|
|
82
|
+
|
|
83
|
+
When investigating a failed GitHub Actions job, use the GitHub API directly:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
gh api repos/evhub/coconut/actions/jobs/{job_id}/logs
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Replace `{job_id}` with the job ID from the URL (e.g., for `.../job/59132870840`, use `59132870840`).
|
|
90
|
+
|
|
91
|
+
**Note:** The more common `gh run view {run_id} --log-failed` command doesn't work if the overall run is still in progress, even if the specific job you want has already completed. Using the API directly bypasses this limitation.
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/.claude/settings.local.json
RENAMED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"permissions": {
|
|
3
3
|
"allow": [
|
|
4
|
+
"WebSearch",
|
|
4
5
|
"Bash(cat:*)",
|
|
6
|
+
"Bash(cd:*)",
|
|
7
|
+
"Bash(ls:*)",
|
|
8
|
+
"Bash(echo:*)",
|
|
9
|
+
"Bash(grep:*)",
|
|
10
|
+
"Bash(find:*)",
|
|
5
11
|
"Bash(python:*)",
|
|
6
|
-
"Bash(xonsh:*)",
|
|
7
12
|
"Bash(gh:*)",
|
|
8
13
|
"Bash(pip:*)",
|
|
14
|
+
"Bash(conda:*)",
|
|
15
|
+
"Bash(xonsh:*)",
|
|
9
16
|
"Bash(make test-tests:*)",
|
|
10
|
-
"WebSearch",
|
|
11
17
|
"WebFetch(domain:coconut.readthedocs.io)",
|
|
12
18
|
"WebFetch(domain:github.com)",
|
|
13
19
|
"WebFetch(domain:peps.python.org)",
|
|
14
20
|
"WebFetch(domain:pypi.org)",
|
|
15
|
-
"WebFetch(domain:discuss.python.org)"
|
|
21
|
+
"WebFetch(domain:discuss.python.org)",
|
|
22
|
+
"WebFetch(domain:doc.pypy.org)"
|
|
16
23
|
]
|
|
17
24
|
}
|
|
18
25
|
}
|
|
@@ -1593,6 +1593,76 @@ data namedpt(name `isinstance` str, x `isinstance` int, y `isinstance` int):
|
|
|
1593
1593
|
_Can't be done without a series of method definitions for each data type. See the compiled code for the Python syntax._
|
|
1594
1594
|
|
|
1595
1595
|
|
|
1596
|
+
### `final`
|
|
1597
|
+
|
|
1598
|
+
Coconut supports `final` declarations to mark variables as constant, preventing reassignment within the same scope. The syntax is:
|
|
1599
|
+
```coconut
|
|
1600
|
+
final <name> = <value>
|
|
1601
|
+
```
|
|
1602
|
+
|
|
1603
|
+
Once a variable is declared `final`, it cannot be reassigned within that scope. Attempting to reassign a final variable will result in a compile-time error.
|
|
1604
|
+
|
|
1605
|
+
#### Shadowing
|
|
1606
|
+
|
|
1607
|
+
Inner scopes can freely shadow final variables from outer scopes, creating new bindings:
|
|
1608
|
+
```coconut
|
|
1609
|
+
final x = 1
|
|
1610
|
+
def f():
|
|
1611
|
+
x = 2 # OK - creates new binding in f's scope, doesn't modify outer x
|
|
1612
|
+
x = 3 # OK - x is not final in this scope
|
|
1613
|
+
return x
|
|
1614
|
+
```
|
|
1615
|
+
|
|
1616
|
+
You can also explicitly make the inner binding final:
|
|
1617
|
+
```coconut
|
|
1618
|
+
final x = 1
|
|
1619
|
+
def f():
|
|
1620
|
+
final x = 2 # OK - new final binding that shadows outer x
|
|
1621
|
+
return x
|
|
1622
|
+
```
|
|
1623
|
+
|
|
1624
|
+
#### Usage Contexts
|
|
1625
|
+
|
|
1626
|
+
The `final` keyword can be used in:
|
|
1627
|
+
- Variable assignments: `final x = 1`
|
|
1628
|
+
- Typed assignments: `final x: int = 1`
|
|
1629
|
+
- Function parameters: `def f(final x): ...`
|
|
1630
|
+
- For loops: `for final i in items: ...`
|
|
1631
|
+
- Match patterns: `case final x: ...`
|
|
1632
|
+
|
|
1633
|
+
#### Escape Hatch
|
|
1634
|
+
|
|
1635
|
+
To bypass final checking (e.g., for metaprogramming), prefix the variable name with a backslash:
|
|
1636
|
+
```coconut
|
|
1637
|
+
final x = 1
|
|
1638
|
+
\x = 2 # OK - bypasses final check
|
|
1639
|
+
```
|
|
1640
|
+
|
|
1641
|
+
##### Example
|
|
1642
|
+
|
|
1643
|
+
**Coconut:**
|
|
1644
|
+
```coconut
|
|
1645
|
+
final PI = 3.14159
|
|
1646
|
+
final GREETING = "Hello"
|
|
1647
|
+
|
|
1648
|
+
def calculate_area(final radius):
|
|
1649
|
+
return PI * radius ** 2
|
|
1650
|
+
|
|
1651
|
+
# PI = 3.14 # ERROR - cannot reassign final variable 'PI'
|
|
1652
|
+
```
|
|
1653
|
+
|
|
1654
|
+
**Python:**
|
|
1655
|
+
```python
|
|
1656
|
+
PI = 3.14159
|
|
1657
|
+
GREETING = "Hello"
|
|
1658
|
+
|
|
1659
|
+
def calculate_area(radius):
|
|
1660
|
+
return PI * radius ** 2
|
|
1661
|
+
|
|
1662
|
+
# No compile-time enforcement - reassignment would be allowed
|
|
1663
|
+
```
|
|
1664
|
+
|
|
1665
|
+
|
|
1596
1666
|
### `where`
|
|
1597
1667
|
|
|
1598
1668
|
Coconut's `where` statement is fairly straightforward. The syntax for a `where` statement is just
|
|
@@ -58,7 +58,7 @@ coconut -h
|
|
|
58
58
|
```
|
|
59
59
|
which should display Coconut's command-line help.
|
|
60
60
|
|
|
61
|
-
_Note: If you're having trouble, or if anything mentioned in this tutorial doesn't seem to work for you, feel free to [
|
|
61
|
+
_Note: If you're having trouble, or if anything mentioned in this tutorial doesn't seem to work for you, feel free to [raise an issue on GitHub](https://github.com/evhub/coconut/issues/new)!_
|
|
62
62
|
|
|
63
63
|
## Starting Out
|
|
64
64
|
|
|
@@ -1163,6 +1163,6 @@ def int_map(
|
|
|
1163
1163
|
|
|
1164
1164
|
And that's it for this tutorial! But that's hardly it for Coconut. All of the features examined in this tutorial, as well as a bunch of others, are detailed in Coconut's [documentation](./DOCS.md).
|
|
1165
1165
|
|
|
1166
|
-
Also, if you have any other questions not covered in this tutorial, feel free to
|
|
1166
|
+
Also, if you have any other questions not covered in this tutorial, feel free to [raise an issue on GitHub](https://github.com/evhub/coconut/issues/new)!
|
|
1167
1167
|
|
|
1168
1168
|
Finally, Coconut is a new, growing language, and if you'd like to get involved in the development of Coconut, all the code is available completely open-source on Coconut's [GitHub](https://github.com/evhub/coconut). Contributing is a simple as forking the code, making your changes, and proposing a pull request! See Coconuts [contributing guidelines](./CONTRIBUTING.md) for more information.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coconut-develop
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0.post0.dev2
|
|
4
4
|
Summary: Simple, elegant, Pythonic functional programming.
|
|
5
5
|
Home-page: http://coconut-lang.org
|
|
6
6
|
Author: Evan Hubinger
|
|
7
7
|
Author-email: evanjhub@gmail.com
|
|
8
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,recursive_iterator,infix,function,composition,compose,partial,application,currying,curry,pipeline,pipe,unicode,operator,operators,frozenset,literal,syntax,destructuring,assignment,fold,datamaker,prepattern,iterator,generator,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,process_map,thread_map,addpattern,recursive_generator,fmap,starmap,reiterable,scan,groupsof,memoize,zip_longest,override,flatten,ident,call,safe_call,flip,const,lift,lift_apart,all_equal,collectby,mapreduce,multi_enumerate,cartesian_product,multiset,cycle,windowsof,and_then,and_then_await,async_map,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,py_min,py_max,_namedtuple_of,reveal_type,reveal_locals,MatchError,CoconutWarning,__fmap__,__iter_getitem__,data,match,case,cases,where,addpattern,then,operator,type,copyclosure,λ
|
|
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,recursive_iterator,infix,function,composition,compose,partial,application,currying,curry,pipeline,pipe,unicode,operator,operators,frozenset,literal,syntax,destructuring,assignment,fold,datamaker,prepattern,iterator,generator,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,process_map,thread_map,addpattern,recursive_generator,fmap,starmap,reiterable,scan,groupsof,memoize,zip_longest,override,flatten,ident,call,safe_call,flip,const,lift,lift_apart,all_equal,collectby,mapreduce,multi_enumerate,cartesian_product,multiset,cycle,windowsof,and_then,and_then_await,async_map,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,py_min,py_max,_namedtuple_of,reveal_type,reveal_locals,MatchError,CoconutWarning,__fmap__,__iter_getitem__,data,match,case,cases,where,final,addpattern,then,operator,type,copyclosure,λ
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Topic :: Software Development
|
|
@@ -220,27 +220,6 @@ Requires-Dist: pytest>=7; (python_version >= "3.6" and python_version < "3.8") a
|
|
|
220
220
|
Requires-Dist: pytest<8.1,>=8.0; python_version >= "3.8" and extra == "tests"
|
|
221
221
|
Requires-Dist: pexpect>=4; extra == "tests"
|
|
222
222
|
Requires-Dist: pytest_remotedata>=0.3; extra == "tests"
|
|
223
|
-
Requires-Dist: ipython>=5.4; python_version < "3" and extra == "tests"
|
|
224
|
-
Requires-Dist: ipython<7.10,>=7.9; (python_version >= "3" and python_version < "3.7") and extra == "tests"
|
|
225
|
-
Requires-Dist: ipython>=7.34; (python_version >= "3.7" and python_version < "3.8") and extra == "tests"
|
|
226
|
-
Requires-Dist: ipython>=8.12; (python_version >= "3.8" and python_version < "3.9") and extra == "tests"
|
|
227
|
-
Requires-Dist: ipython>=8.18; (python_version >= "3.9" and python_version < "3.11") and extra == "tests"
|
|
228
|
-
Requires-Dist: ipython>=9; python_version >= "3.11" and extra == "tests"
|
|
229
|
-
Requires-Dist: ipykernel>=4.10; python_version < "3" and extra == "tests"
|
|
230
|
-
Requires-Dist: ipykernel>=5.5; (python_version >= "3" and python_version < "3.8") and extra == "tests"
|
|
231
|
-
Requires-Dist: ipykernel>=6; (python_version >= "3.8" and python_version < "3.10") and extra == "tests"
|
|
232
|
-
Requires-Dist: ipykernel>=7; python_version >= "3.10" and extra == "tests"
|
|
233
|
-
Requires-Dist: jupyter-client>=5.3; python_version < "3.5" and extra == "tests"
|
|
234
|
-
Requires-Dist: jupyter-client<6.1.13,>=6.1.12; (python_version >= "3.5" and python_version < "3.6") and extra == "tests"
|
|
235
|
-
Requires-Dist: jupyter-client>=7.1.2; python_version >= "3.6" and extra == "tests"
|
|
236
|
-
Requires-Dist: jedi<0.18,>=0.17; python_version < "3.9" and extra == "tests"
|
|
237
|
-
Requires-Dist: jedi>=0.19; python_version >= "3.9" and extra == "tests"
|
|
238
|
-
Requires-Dist: pywinpty<0.6,>=0.5; (python_version < "3" and os_name == "nt") and extra == "tests"
|
|
239
|
-
Requires-Dist: jupyter>=1.1; extra == "tests"
|
|
240
|
-
Requires-Dist: jupyter-console>=5.2; python_version < "3.5" and extra == "tests"
|
|
241
|
-
Requires-Dist: jupyter-console>=6.1; (python_version >= "3.5" and python_version < "3.7") and extra == "tests"
|
|
242
|
-
Requires-Dist: jupyter-console>=6.6; python_version >= "3.7" and extra == "tests"
|
|
243
|
-
Requires-Dist: papermill>=1.2; extra == "tests"
|
|
244
223
|
Provides-Extra: dev
|
|
245
224
|
Requires-Dist: ipython>=5.4; python_version < "3" and extra == "dev"
|
|
246
225
|
Requires-Dist: ipython<7.10,>=7.9; (python_version >= "3" and python_version < "3.7") and extra == "dev"
|
|
@@ -364,8 +343,7 @@ To help you get started, check out these links for more information about Coconu
|
|
|
364
343
|
- Documentation_: If you're looking for info about a specific feature, check out Coconut's **documentation**.
|
|
365
344
|
- `Online Interpreter`_: If you want to try Coconut in your browser, check out Coconut's **online interpreter**.
|
|
366
345
|
- 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.
|
|
367
|
-
- `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.
|
|
368
|
-
- 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.
|
|
346
|
+
- `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. Creating a new issue is also absolutely welcome as a way to ask any questions you might have about Coconut.
|
|
369
347
|
- Releases_: Want to know what's been added in recent Coconut versions? Check out the release log for all the new features and fixes.
|
|
370
348
|
|
|
371
349
|
.. _Python: https://www.python.org/
|
|
@@ -375,7 +353,6 @@ To help you get started, check out these links for more information about Coconu
|
|
|
375
353
|
.. _`Online Interpreter`: https://cs121-team-panda.github.io/coconut-interpreter
|
|
376
354
|
.. _FAQ: http://coconut.readthedocs.io/en/latest/FAQ.html
|
|
377
355
|
.. _GitHub: https://github.com/evhub/coconut
|
|
378
|
-
.. _Gitter: https://gitter.im/evhub/coconut
|
|
379
356
|
.. _Releases: https://github.com/evhub/coconut/releases
|
|
380
357
|
|
|
381
358
|
Credits
|
|
@@ -31,8 +31,7 @@ To help you get started, check out these links for more information about Coconu
|
|
|
31
31
|
- Documentation_: If you're looking for info about a specific feature, check out Coconut's **documentation**.
|
|
32
32
|
- `Online Interpreter`_: If you want to try Coconut in your browser, check out Coconut's **online interpreter**.
|
|
33
33
|
- 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.
|
|
34
|
-
- `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.
|
|
35
|
-
- 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.
|
|
34
|
+
- `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. Creating a new issue is also absolutely welcome as a way to ask any questions you might have about Coconut.
|
|
36
35
|
- Releases_: Want to know what's been added in recent Coconut versions? Check out the release log for all the new features and fixes.
|
|
37
36
|
|
|
38
37
|
.. _Python: https://www.python.org/
|
|
@@ -42,7 +41,6 @@ To help you get started, check out these links for more information about Coconu
|
|
|
42
41
|
.. _`Online Interpreter`: https://cs121-team-panda.github.io/coconut-interpreter
|
|
43
42
|
.. _FAQ: http://coconut.readthedocs.io/en/latest/FAQ.html
|
|
44
43
|
.. _GitHub: https://github.com/evhub/coconut
|
|
45
|
-
.. _Gitter: https://gitter.im/evhub/coconut
|
|
46
44
|
.. _Releases: https://github.com/evhub/coconut/releases
|
|
47
45
|
|
|
48
46
|
Credits
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/compiler.py
RENAMED
|
@@ -604,6 +604,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
604
604
|
# but always overwrite temp_vars_by_key since they store locs that will be invalidated
|
|
605
605
|
self.temp_vars_by_key = {}
|
|
606
606
|
self.parsing_context = defaultdict(list)
|
|
607
|
+
self.parsing_context["final_vars"].append(set()) # initialize module-level final scope
|
|
607
608
|
self.name_info = defaultdict(lambda: {"imported": [], "referenced": [], "assigned": []})
|
|
608
609
|
self.star_import = False
|
|
609
610
|
self.kept_lines = []
|
|
@@ -634,6 +635,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
634
635
|
skips, self.skips = self.skips, []
|
|
635
636
|
docstring, self.docstring = self.docstring, ""
|
|
636
637
|
parsing_context, self.parsing_context = self.parsing_context, defaultdict(list)
|
|
638
|
+
self.parsing_context["final_vars"].append(set()) # initialize module-level final scope
|
|
637
639
|
kept_lines, self.kept_lines = self.kept_lines, []
|
|
638
640
|
num_lines, self.num_lines = self.num_lines, 0
|
|
639
641
|
remaining_original, self.remaining_original = self.remaining_original, None
|
|
@@ -816,12 +818,22 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
816
818
|
|
|
817
819
|
# name handlers
|
|
818
820
|
cls.refname <<= attach(cls.name_ref, cls.method("name_handle"))
|
|
819
|
-
cls.
|
|
820
|
-
cls.
|
|
821
|
+
cls.nonfinal_setname <<= attach(cls.name_ref, cls.method("name_handle", assign=True))
|
|
822
|
+
cls.final_setname <<= attach(
|
|
823
|
+
cls.final_setname_ref,
|
|
824
|
+
cls.method("name_handle", assign=True, is_final=True),
|
|
825
|
+
greedy=True,
|
|
826
|
+
)
|
|
827
|
+
cls.nonfinal_classname <<= attach(
|
|
821
828
|
cls.name_ref,
|
|
822
829
|
cls.method("name_handle", assign=True, classname=True),
|
|
823
830
|
greedy=True,
|
|
824
831
|
)
|
|
832
|
+
cls.final_classname <<= attach(
|
|
833
|
+
cls.final_setname_ref,
|
|
834
|
+
cls.method("name_handle", assign=True, classname=True, is_final=True),
|
|
835
|
+
greedy=True,
|
|
836
|
+
)
|
|
825
837
|
cls.expr_setname <<= attach(
|
|
826
838
|
cls.name_ref,
|
|
827
839
|
cls.method("name_handle", assign=True, expr_setname=True),
|
|
@@ -1055,7 +1067,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1055
1067
|
msg + " (add '# NOQA' to suppress)",
|
|
1056
1068
|
original,
|
|
1057
1069
|
loc,
|
|
1058
|
-
**kwargs
|
|
1070
|
+
**kwargs # no comma
|
|
1059
1071
|
)
|
|
1060
1072
|
|
|
1061
1073
|
@contextmanager
|
|
@@ -5015,7 +5027,7 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
5015
5027
|
|
|
5016
5028
|
@contextmanager
|
|
5017
5029
|
def add_to_parsing_context(self, name, obj, callbacks_key=None):
|
|
5018
|
-
"""
|
|
5030
|
+
"""Put the given object on the parsing context stack for the given name."""
|
|
5019
5031
|
self.parsing_context[name].append(obj)
|
|
5020
5032
|
try:
|
|
5021
5033
|
yield
|
|
@@ -5244,7 +5256,8 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
5244
5256
|
try:
|
|
5245
5257
|
# handles support for class type variables
|
|
5246
5258
|
with self.type_alias_stmt_manage():
|
|
5247
|
-
|
|
5259
|
+
with self.add_to_parsing_context("final_vars", set()):
|
|
5260
|
+
yield
|
|
5248
5261
|
finally:
|
|
5249
5262
|
cls_stack.pop()
|
|
5250
5263
|
|
|
@@ -5257,7 +5270,8 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
5257
5270
|
try:
|
|
5258
5271
|
# handles support for function type variables
|
|
5259
5272
|
with self.type_alias_stmt_manage():
|
|
5260
|
-
|
|
5273
|
+
with self.add_to_parsing_context("final_vars", set()):
|
|
5274
|
+
yield
|
|
5261
5275
|
finally:
|
|
5262
5276
|
if cls_context is not None:
|
|
5263
5277
|
cls_context["in_method"] = in_method
|
|
@@ -5283,11 +5297,15 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
5283
5297
|
):
|
|
5284
5298
|
yield
|
|
5285
5299
|
|
|
5286
|
-
def name_handle(self, original, loc, tokens, assign=False, classname=False, expr_setname=False):
|
|
5300
|
+
def name_handle(self, original, loc, tokens, assign=False, classname=False, expr_setname=False, is_final=False):
|
|
5287
5301
|
"""Handle the given base name."""
|
|
5288
|
-
|
|
5302
|
+
if expr_setname:
|
|
5303
|
+
internal_assert(assign, "expr_setname should always imply assign", (expr_setname, assign))
|
|
5304
|
+
if is_final:
|
|
5305
|
+
internal_assert(assign and not expr_setname, "only setnames should ever be final", (assign, is_final))
|
|
5289
5306
|
|
|
5290
5307
|
name, = tokens
|
|
5308
|
+
|
|
5291
5309
|
if name.startswith("\\"):
|
|
5292
5310
|
name = name[1:]
|
|
5293
5311
|
escaped = True
|
|
@@ -5297,6 +5315,28 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
5297
5315
|
if self.disable_name_check:
|
|
5298
5316
|
return name
|
|
5299
5317
|
|
|
5318
|
+
# raise_or_wrap_error for all errors here to make sure we don't
|
|
5319
|
+
# raise spurious errors if not using the computation graph
|
|
5320
|
+
|
|
5321
|
+
# final variable checking
|
|
5322
|
+
final_vars = self.current_parsing_context("final_vars")
|
|
5323
|
+
self.internal_assert(final_vars is not None, original, loc, "no final_vars context")
|
|
5324
|
+
if (
|
|
5325
|
+
assign
|
|
5326
|
+
and not expr_setname
|
|
5327
|
+
and not escaped
|
|
5328
|
+
and name in final_vars
|
|
5329
|
+
):
|
|
5330
|
+
return self.raise_or_wrap_error(
|
|
5331
|
+
CoconutSyntaxError,
|
|
5332
|
+
"cannot reassign final variable '{name}'".format(name=name),
|
|
5333
|
+
original,
|
|
5334
|
+
loc,
|
|
5335
|
+
extra="use explicit '\\{name}' syntax to bypass final checking".format(name=name),
|
|
5336
|
+
)
|
|
5337
|
+
if is_final:
|
|
5338
|
+
final_vars.add(name)
|
|
5339
|
+
|
|
5300
5340
|
# register non-mid-expression variable assignments inside of where statements for later mangling
|
|
5301
5341
|
if assign and not expr_setname:
|
|
5302
5342
|
where_context = self.current_parsing_context("where")
|
|
@@ -5315,9 +5355,6 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
5315
5355
|
self.internal_assert(expr_setnames_context is not None, original, loc, "found expr_setname outside of has_expr_setname_manage", tokens)
|
|
5316
5356
|
expr_setnames_context["new_names"].add(name)
|
|
5317
5357
|
|
|
5318
|
-
# raise_or_wrap_error for all errors here to make sure we don't
|
|
5319
|
-
# raise spurious errors if not using the computation graph
|
|
5320
|
-
|
|
5321
5358
|
if not escaped:
|
|
5322
5359
|
typevar_info = self.current_parsing_context("typevars")
|
|
5323
5360
|
if typevar_info is not None:
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/grammar.py
RENAMED
|
@@ -859,10 +859,16 @@ class Grammar(object):
|
|
|
859
859
|
base_name = regex_item(base_name_regex)
|
|
860
860
|
|
|
861
861
|
refname = Forward()
|
|
862
|
-
setname = Forward()
|
|
863
862
|
expr_setname = Forward()
|
|
864
|
-
|
|
863
|
+
final_setname = Forward()
|
|
864
|
+
nonfinal_setname = Forward()
|
|
865
|
+
final_classname = Forward()
|
|
866
|
+
nonfinal_classname = Forward()
|
|
867
|
+
|
|
865
868
|
name_ref = combine(Optional(backslash) + base_name)
|
|
869
|
+
final_setname_ref = keyword("final").suppress() + name_ref
|
|
870
|
+
setname = final_setname | nonfinal_setname
|
|
871
|
+
classname = final_classname | nonfinal_classname
|
|
866
872
|
unsafe_name = combine(Optional(backslash.suppress()) + base_name)
|
|
867
873
|
|
|
868
874
|
# use unsafe_name for dotted components since name should only be used for base names
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/header.py
RENAMED
|
@@ -766,17 +766,6 @@ asyncio_Return = StopIteration
|
|
|
766
766
|
''',
|
|
767
767
|
indent=1,
|
|
768
768
|
),
|
|
769
|
-
import_tstr=pycondition(
|
|
770
|
-
(3, 14),
|
|
771
|
-
if_lt='''
|
|
772
|
-
try:
|
|
773
|
-
import tstr
|
|
774
|
-
except ImportError as tstr_import_err:
|
|
775
|
-
tstr = _coconut_missing_module(tstr_import_err)
|
|
776
|
-
''',
|
|
777
|
-
if_ge='',
|
|
778
|
-
indent=1,
|
|
779
|
-
),
|
|
780
769
|
class_amap=pycondition(
|
|
781
770
|
(3, 3),
|
|
782
771
|
if_lt='''
|
|
@@ -27,7 +27,10 @@ class _coconut{object}:{COMMENT.EVERYTHING_HERE_MUST_BE_COPIED_TO_STUB_FILE}
|
|
|
27
27
|
import async_generator
|
|
28
28
|
except ImportError as async_generator_import_err:
|
|
29
29
|
async_generator = _coconut_missing_module(async_generator_import_err)
|
|
30
|
-
|
|
30
|
+
try:
|
|
31
|
+
import tstr
|
|
32
|
+
except ImportError as tstr_import_err:
|
|
33
|
+
tstr = _coconut_missing_module(tstr_import_err)
|
|
31
34
|
{import_pickle}
|
|
32
35
|
{import_OrderedDict}
|
|
33
36
|
{import_collections_abc}
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/util.py
RENAMED
|
@@ -106,7 +106,7 @@ from coconut.constants import (
|
|
|
106
106
|
pseudo_targets,
|
|
107
107
|
reserved_vars,
|
|
108
108
|
packrat_cache_size,
|
|
109
|
-
|
|
109
|
+
min_observed_ref_count,
|
|
110
110
|
indchars,
|
|
111
111
|
comment_chars,
|
|
112
112
|
non_syntactic_newline,
|
|
@@ -986,7 +986,13 @@ assert _value_useful == -1, "value must end with usefullness obj"
|
|
|
986
986
|
|
|
987
987
|
def maybe_copy_elem(item, name):
|
|
988
988
|
"""Copy the given grammar element if it's referenced somewhere else."""
|
|
989
|
-
item_ref_count = sys.getrefcount(item) if CPYTHON
|
|
989
|
+
item_ref_count = sys.getrefcount(item) if CPYTHON else float("inf")
|
|
990
|
+
if on_new_python:
|
|
991
|
+
temp_grammar_item_ref_count = 1
|
|
992
|
+
elif isinstance(min_observed_ref_count, dict):
|
|
993
|
+
temp_grammar_item_ref_count = min_observed_ref_count[name]
|
|
994
|
+
else:
|
|
995
|
+
temp_grammar_item_ref_count = min_observed_ref_count
|
|
990
996
|
internal_assert(lambda: item_ref_count >= temp_grammar_item_ref_count, "add_action got item with too low ref count", (item, type(item), item_ref_count))
|
|
991
997
|
if item_ref_count <= temp_grammar_item_ref_count:
|
|
992
998
|
if DEVELOP:
|
|
@@ -26,6 +26,7 @@ import platform
|
|
|
26
26
|
import re
|
|
27
27
|
import datetime as dt
|
|
28
28
|
from warnings import warn
|
|
29
|
+
from collections import defaultdict
|
|
29
30
|
|
|
30
31
|
# -----------------------------------------------------------------------------------------------------------------------
|
|
31
32
|
# UTILITIES:
|
|
@@ -179,8 +180,8 @@ embed_on_internal_exc = get_bool_env_var("COCONUT_EMBED_ON_INTERNAL_EXC", False)
|
|
|
179
180
|
test_computation_graph_pickling = False
|
|
180
181
|
|
|
181
182
|
# should be the minimal ref count observed by maybe_copy_elem
|
|
182
|
-
|
|
183
|
-
1 if PY314
|
|
183
|
+
min_observed_ref_count = (
|
|
184
|
+
defaultdict(lambda: 2, attach=1) if PY314
|
|
184
185
|
else 4 if PY311
|
|
185
186
|
else 5
|
|
186
187
|
)
|
|
@@ -441,6 +442,7 @@ reserved_vars = (
|
|
|
441
442
|
"case",
|
|
442
443
|
"cases",
|
|
443
444
|
"where",
|
|
445
|
+
"final",
|
|
444
446
|
"addpattern",
|
|
445
447
|
"then",
|
|
446
448
|
"operator",
|
|
@@ -23,10 +23,10 @@ import sys as _coconut_sys
|
|
|
23
23
|
# VERSION:
|
|
24
24
|
# -----------------------------------------------------------------------------------------------------------------------
|
|
25
25
|
|
|
26
|
-
VERSION = "3.
|
|
26
|
+
VERSION = "3.2.0"
|
|
27
27
|
VERSION_NAME = None
|
|
28
28
|
# False for release, int >= 1 for develop
|
|
29
|
-
DEVELOP =
|
|
29
|
+
DEVELOP = 2
|
|
30
30
|
ALPHA = False # for pre releases rather than post releases
|
|
31
31
|
|
|
32
32
|
assert DEVELOP is False or DEVELOP >= 1, "DEVELOP must be False or an int >= 1"
|
|
@@ -107,6 +107,12 @@ class int(_coconut_py_int):
|
|
|
107
107
|
return _coconut.isinstance(inst, (_coconut_py_int, _coconut_py_long))
|
|
108
108
|
def __subclasscheck__(cls, subcls):
|
|
109
109
|
return _coconut.issubclass(subcls, (_coconut_py_int, _coconut_py_long))
|
|
110
|
+
def __eq__(cls, other):
|
|
111
|
+
if other is _coconut_py_int or other is _coconut_py_long:
|
|
112
|
+
return True
|
|
113
|
+
return _coconut.type.__eq__(cls, other)
|
|
114
|
+
def __hash__(cls):
|
|
115
|
+
return _coconut.hash(_coconut_py_int)
|
|
110
116
|
class bytes(_coconut_py_bytes):
|
|
111
117
|
__slots__ = ()
|
|
112
118
|
__doc__ = getattr(_coconut_py_bytes, "__doc__", "<see help(py_bytes)>")
|
|
@@ -115,6 +121,12 @@ class bytes(_coconut_py_bytes):
|
|
|
115
121
|
return _coconut.isinstance(inst, _coconut_py_bytes)
|
|
116
122
|
def __subclasscheck__(cls, subcls):
|
|
117
123
|
return _coconut.issubclass(subcls, _coconut_py_bytes)
|
|
124
|
+
def __eq__(cls, other):
|
|
125
|
+
if other is _coconut_py_bytes:
|
|
126
|
+
return True
|
|
127
|
+
return _coconut.type.__eq__(cls, other)
|
|
128
|
+
def __hash__(cls):
|
|
129
|
+
return _coconut.hash(_coconut_py_bytes)
|
|
118
130
|
def __new__(self, *args):
|
|
119
131
|
if not args:
|
|
120
132
|
return b""
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/main_test.py
RENAMED
|
@@ -824,9 +824,11 @@ def run_pyprover(**kwargs):
|
|
|
824
824
|
def comp_prelude(args=[], **kwargs):
|
|
825
825
|
"""Compiles evhub/coconut-prelude."""
|
|
826
826
|
call(["git", "clone", prelude_git])
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
827
|
+
# disabled --mypy: was causing test_prelude to take ~5 hours due to
|
|
828
|
+
# extremely slow mypy type-checking on the coconut-prelude package
|
|
829
|
+
# if MYPY and not WINDOWS:
|
|
830
|
+
# args.extend(["--target", "3.5", "--mypy"])
|
|
831
|
+
# kwargs["check_errors"] = False
|
|
830
832
|
call_coconut([os.path.join(prelude, "setup.coco"), "--force"] + args, **kwargs)
|
|
831
833
|
call_coconut([os.path.join(prelude, "prelude-source"), os.path.join(prelude, "prelude"), "--force"] + args, **kwargs)
|
|
832
834
|
|
|
@@ -491,6 +491,8 @@ def primary_test_2() -> bool:
|
|
|
491
491
|
assert reduce(function=(+), iterable=range(5), initial=-1) == 9 # type: ignore
|
|
492
492
|
assert takewhile(predicate=ident, iterable=[1, 2, 1, 0, 1]) |> list == [1, 2, 1] # type: ignore
|
|
493
493
|
assert dropwhile(predicate=(not), iterable=range(5)) |> list == [1, 2, 3, 4] # type: ignore
|
|
494
|
+
assert type(1) == int
|
|
495
|
+
assert type(b"") == bytes
|
|
494
496
|
@memoize(typed=True)
|
|
495
497
|
def typed_memoized_func(x):
|
|
496
498
|
if x is 1:
|
|
@@ -499,12 +501,12 @@ def primary_test_2() -> bool:
|
|
|
499
501
|
return (x, typed_memoized_func(1))
|
|
500
502
|
assert typed_memoized_func(1.0) == (1.0, None)
|
|
501
503
|
assert typed_memoized_func(1.0)[0] |> type == float
|
|
502
|
-
@memoize()
|
|
503
|
-
def
|
|
504
|
+
@memoize(memoize.RECURSIVE, typed=True) # type: ignore
|
|
505
|
+
def recursive_typed_memoized_func(x=None):
|
|
504
506
|
if x is None:
|
|
505
|
-
return (
|
|
507
|
+
return (recursive_typed_memoized_func(1), recursive_typed_memoized_func(1.0))
|
|
506
508
|
return x
|
|
507
|
-
assert
|
|
509
|
+
assert recursive_typed_memoized_func() |> map$(type) |> tuple == (int, float)
|
|
508
510
|
assert -1 ?↦ abs == 1
|
|
509
511
|
assert None ?↦ abs is None
|
|
510
512
|
|
|
@@ -516,4 +518,78 @@ def primary_test_2() -> bool:
|
|
|
516
518
|
# repeat the same thing again now that my_match_err.str has been called
|
|
517
519
|
assert process_map(ident, [my_match_err]) |> list |> str == str([my_match_err]) # type: ignore
|
|
518
520
|
|
|
521
|
+
# final variable tests - valid cases
|
|
522
|
+
# 1. Simple final declaration
|
|
523
|
+
final final_x = 1
|
|
524
|
+
assert final_x == 1
|
|
525
|
+
# 2. Final parameter (no reassignment inside)
|
|
526
|
+
def final_param_func(final param) = param * 2
|
|
527
|
+
assert final_param_func(5) == 10
|
|
528
|
+
# 3. Shadowing in inner scope WITH final (allowed)
|
|
529
|
+
final final_outer1 = 1
|
|
530
|
+
def final_shadow_test1():
|
|
531
|
+
final final_outer1 = 2 # shadows with final
|
|
532
|
+
return final_outer1
|
|
533
|
+
assert final_shadow_test1() == 2
|
|
534
|
+
assert final_outer1 == 1 # outer unchanged
|
|
535
|
+
# 4. Shadowing in inner scope WITHOUT final (also allowed - creates new non-final binding)
|
|
536
|
+
final final_outer2 = 10
|
|
537
|
+
def final_shadow_test2():
|
|
538
|
+
final_outer2 = 20 # shadows without final - OK, new binding
|
|
539
|
+
final_outer2 = 30 # can reassign since it's not final in this scope
|
|
540
|
+
return final_outer2
|
|
541
|
+
assert final_shadow_test2() == 30
|
|
542
|
+
assert final_outer2 == 10 # outer unchanged
|
|
543
|
+
# 5. Function parameter shadows outer final (no final needed)
|
|
544
|
+
final final_param_shadow = 100
|
|
545
|
+
def final_param_test(final_param_shadow): # parameter shadows outer final - OK
|
|
546
|
+
return final_param_shadow * 2
|
|
547
|
+
assert final_param_test(5) == 10
|
|
548
|
+
assert final_param_shadow == 100
|
|
549
|
+
# 6. Referencing final (read access is fine)
|
|
550
|
+
final final_readable = 42
|
|
551
|
+
final_other = final_readable + 1
|
|
552
|
+
assert final_other == 43
|
|
553
|
+
# 7. Multiple final declarations (different names)
|
|
554
|
+
final final_a = 1
|
|
555
|
+
final final_b = 2
|
|
556
|
+
assert final_a + final_b == 3
|
|
557
|
+
# 8. Final in class body (class attribute)
|
|
558
|
+
class FinalClass:
|
|
559
|
+
final class_final = 100
|
|
560
|
+
assert FinalClass.class_final == 100
|
|
561
|
+
# 9. Typed final
|
|
562
|
+
final final_typed_val: int = 999
|
|
563
|
+
assert final_typed_val == 999
|
|
564
|
+
# 10. Final in for loop (new final binding per iteration)
|
|
565
|
+
final_result = []
|
|
566
|
+
for final final_i in [1, 2, 3]:
|
|
567
|
+
final_result.append(final_i)
|
|
568
|
+
assert final_result == [1, 2, 3]
|
|
569
|
+
# 11. Escape hatch - can bypass with backslash
|
|
570
|
+
final final_escape_test = 1
|
|
571
|
+
\final_escape_test = 2 # bypasses final check
|
|
572
|
+
assert final_escape_test == 2
|
|
573
|
+
# 12. Class body assignment doesn't conflict with outer final
|
|
574
|
+
final final_class_ok = 1
|
|
575
|
+
class OkClass:
|
|
576
|
+
final_class_ok = 2 # This is a class attribute, different namespace
|
|
577
|
+
assert OkClass.final_class_ok == 2
|
|
578
|
+
assert final_class_ok == 1
|
|
579
|
+
# 13. Comprehension variables are independent (not checked for final)
|
|
580
|
+
final final_comp_var = 1
|
|
581
|
+
final_result2 = [final_comp_var for final_comp_var in [10, 20]] # expr_setname, not checked
|
|
582
|
+
assert final_result2 == [10, 20]
|
|
583
|
+
assert final_comp_var == 1 # outer unchanged
|
|
584
|
+
# 14. Nested function shadowing
|
|
585
|
+
final final_nested = 1
|
|
586
|
+
def final_outer_fn():
|
|
587
|
+
final_nested = 2 # shadows without final - OK
|
|
588
|
+
def final_inner_fn():
|
|
589
|
+
final_nested = 3 # shadows again - OK
|
|
590
|
+
return final_nested
|
|
591
|
+
return final_inner_fn() + final_nested
|
|
592
|
+
assert final_outer_fn() == 5
|
|
593
|
+
assert final_nested == 1
|
|
594
|
+
|
|
519
595
|
return True
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/extras.coco
RENAMED
|
@@ -10,7 +10,7 @@ from coconut.constants import (
|
|
|
10
10
|
NUMPY,
|
|
11
11
|
PY35,
|
|
12
12
|
PY36,
|
|
13
|
-
|
|
13
|
+
PY310,
|
|
14
14
|
PYPY,
|
|
15
15
|
) # type: ignore
|
|
16
16
|
from coconut._pyparsing import USE_COMPUTATION_GRAPH # type: ignore
|
|
@@ -335,6 +335,18 @@ def g(x) = x
|
|
|
335
335
|
assert parse("[def x -> (x, y) for y in range(10)]", "lenient").count("def") == 2
|
|
336
336
|
assert parse("123 # derp", "lenient") == "123 # derp"
|
|
337
337
|
|
|
338
|
+
assert_raises(-> parse("final x = 1\nx = 2"), CoconutSyntaxError, err_has="final")
|
|
339
|
+
assert_raises(-> parse("final x = 1\nx += 1"), CoconutSyntaxError, err_has="final")
|
|
340
|
+
assert_raises(-> parse("final x = 1\ndel x"), CoconutSyntaxError, err_has="final")
|
|
341
|
+
assert_raises(-> parse("final x = 1\nfor x in [1]: pass"), CoconutSyntaxError, err_has="final")
|
|
342
|
+
assert_raises(-> parse("final x = 1\nwith foo() as x: pass"), CoconutSyntaxError, err_has="final")
|
|
343
|
+
assert_raises(-> parse("final e = 1\ntry: pass\nexcept E as e: pass"), CoconutSyntaxError, err_has="final")
|
|
344
|
+
assert_raises(-> parse("final os = 1\nimport os"), CoconutSyntaxError, err_has="final")
|
|
345
|
+
assert_raises(-> parse("final path = 1\nfrom os import path"), CoconutSyntaxError, err_has="final")
|
|
346
|
+
assert_raises(-> parse("def f(final x): x = 2"), CoconutSyntaxError, err_has="final")
|
|
347
|
+
assert_raises(-> parse("final x = 1\nmatch y:\n case x: pass"), CoconutSyntaxError, err_has="final")
|
|
348
|
+
assert_raises(-> parse("final x = 1\nfinal x = 2"), CoconutSyntaxError, err_has="final")
|
|
349
|
+
|
|
338
350
|
return True
|
|
339
351
|
|
|
340
352
|
|
|
@@ -768,7 +780,7 @@ def test_extras() -> bool:
|
|
|
768
780
|
if NUMPY and PY36:
|
|
769
781
|
assert test_pandas() is True # .
|
|
770
782
|
print(".", end="")
|
|
771
|
-
if NUMPY and
|
|
783
|
+
if NUMPY and PY310:
|
|
772
784
|
assert test_xarray() is True # ..
|
|
773
785
|
print(".") # newline bc we print stuff after this
|
|
774
786
|
assert test_setup_none() is True # ...
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/__coconut__/__init__.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/__coconut__/__init__.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/_coconut/__init__.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__coconut__.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/__coconut__.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/_pyparsing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/__init__.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/__init__.pyi
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/cli.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/command.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/command.pyi
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/mypy.py
RENAMED
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/util.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/command/watch.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/__init__.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/compiler/matching.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/convenience.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/convenience.pyi
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/exceptions.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/highlighter.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/__init__.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/embed.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/icoconut/root.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/integrations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/requirements.py
RENAMED
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/__init__.py
RENAMED
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coconut_develop-3.1.2.post0.dev11 → coconut_develop-3.2.0.post0.dev2}/coconut/tests/src/runner.coco
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|