coconut-develop 3.1.2.post0.dev1__tar.gz → 3.1.2.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.
Files changed (91) hide show
  1. coconut-develop-3.1.2.post0.dev2/PKG-INFO +141 -0
  2. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/compiler.py +57 -44
  3. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/grammar.py +2 -5
  4. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/util.py +99 -22
  5. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/constants.py +1 -1
  6. coconut-develop-3.1.2.post0.dev2/coconut/icoconut/coconut/kernel.json +11 -0
  7. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/root.py +1 -1
  8. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/terminal.py +11 -5
  9. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/util.py +9 -4
  10. coconut-develop-3.1.2.post0.dev1/PKG-INFO +0 -141
  11. coconut-develop-3.1.2.post0.dev1/coconut/icoconut/coconut/kernel.json +0 -11
  12. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/CONTRIBUTING.md +0 -0
  13. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/DOCS.md +0 -0
  14. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/FAQ.md +0 -0
  15. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/HELP.md +0 -0
  16. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/LICENSE.txt +0 -0
  17. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/MANIFEST.in +0 -0
  18. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/README.rst +0 -0
  19. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/__coconut__/__init__.py +0 -0
  20. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/__coconut__/__init__.pyi +0 -0
  21. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/__coconut__/py.typed +0 -0
  22. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/_coconut/__init__.py +0 -0
  23. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/_coconut/__init__.pyi +0 -0
  24. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/_coconut/py.typed +0 -0
  25. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/__coconut__.py +0 -0
  26. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/__coconut__.pyi +0 -0
  27. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/__init__.py +0 -0
  28. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/__init__.pyi +0 -0
  29. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/__main__.py +0 -0
  30. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/_pyparsing.py +0 -0
  31. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/api.py +0 -0
  32. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/api.pyi +0 -0
  33. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/__init__.py +0 -0
  34. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/__init__.pyi +0 -0
  35. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/cli.py +0 -0
  36. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/command.py +0 -0
  37. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/command.pyi +0 -0
  38. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/mypy.py +0 -0
  39. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/resources/zcoconut.pth +0 -0
  40. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/util.py +0 -0
  41. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/command/watch.py +0 -0
  42. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/__init__.py +0 -0
  43. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/header.py +0 -0
  44. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/matching.py +0 -0
  45. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/compiler/templates/header.py_template +0 -0
  46. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/convenience.py +0 -0
  47. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/convenience.pyi +0 -0
  48. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/exceptions.py +0 -0
  49. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/highlighter.py +0 -0
  50. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/__init__.py +0 -0
  51. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/__main__.py +0 -0
  52. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/coconut_py/kernel.json +0 -0
  53. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/coconut_py2/kernel.json +0 -0
  54. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/coconut_py3/kernel.json +0 -0
  55. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/embed.py +0 -0
  56. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/icoconut/root.py +0 -0
  57. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/integrations.py +0 -0
  58. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/main.py +0 -0
  59. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/py.typed +0 -0
  60. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/requirements.py +0 -0
  61. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/__init__.py +0 -0
  62. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/__main__.py +0 -0
  63. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/constants_test.py +0 -0
  64. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/main_test.py +0 -0
  65. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/__init__.coco +0 -0
  66. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/__main__.coco +0 -0
  67. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/main.coco +0 -0
  68. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/primary_1.coco +0 -0
  69. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/primary_2.coco +0 -0
  70. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/specific.coco +0 -0
  71. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/suite.coco +0 -0
  72. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/tutorial.coco +0 -0
  73. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/agnostic/util.coco +0 -0
  74. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/non_strict/non_strict_test.coco +0 -0
  75. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_2/py2_test.coco +0 -0
  76. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_3/py3_test.coco +0 -0
  77. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_311/py311_test.coco +0 -0
  78. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_35/py35_test.coco +0 -0
  79. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_36/py36_test.coco +0 -0
  80. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_38/py38_test.coco +0 -0
  81. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/cocotest/target_sys/target_sys_test.coco +0 -0
  82. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/extras.coco +0 -0
  83. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/importable.coco +0 -0
  84. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/runnable.coco +0 -0
  85. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut/tests/src/runner.coco +0 -0
  86. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/coconut_develop.egg-info/SOURCES.txt +0 -0
  87. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/conf.py +0 -0
  88. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/pyproject.toml +0 -0
  89. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/setup.cfg +0 -0
  90. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/setup.py +0 -0
  91. {coconut-develop-3.1.2.post0.dev1 → coconut-develop-3.1.2.post0.dev2}/xontrib/coconut.py +0 -0
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.1
2
+ Name: coconut-develop
3
+ Version: 3.1.2.post0.dev2
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
+ Description: |logo| Coconut
10
+ ==============
11
+
12
+ ..
13
+ <insert toctree here>
14
+
15
+ .. |logo| image:: https://github.com/evhub/coconut/raw/gh-pages/favicon-32x32.png
16
+
17
+ .. image:: https://opencollective.com/coconut/backers/badge.svg
18
+ :alt: Backers on Open Collective
19
+ :target: #backers
20
+ .. image:: https://opencollective.com/coconut/sponsors/badge.svg
21
+ :alt: Sponsors on Open Collective
22
+ :target: #sponsors
23
+ .. image:: https://badges.gitter.im/evhub/coconut.svg
24
+ :alt: Join the chat at https://gitter.im/evhub/coconut
25
+ :target: https://gitter.im/evhub/coconut?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
26
+
27
+ Coconut (`coconut-lang.org`__) is a variant of Python_ that **adds on top of Python syntax** new features for simple, elegant, Pythonic **functional programming**.
28
+
29
+ __ Coconut_
30
+ .. _Coconut: http://coconut-lang.org/
31
+
32
+ Coconut is developed on GitHub_ and hosted on PyPI_. Installing Coconut is as easy as opening a command prompt and entering::
33
+
34
+ pip install coconut
35
+
36
+ To help you get started, check out these links for more information about Coconut:
37
+
38
+ - Tutorial_: If you're new to Coconut, a good place to start is Coconut's **tutorial**.
39
+ - Documentation_: If you're looking for info about a specific feature, check out Coconut's **documentation**.
40
+ - `Online Interpreter`_: If you want to try Coconut in your browser, check out Coconut's **online interpreter**.
41
+ - 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.
42
+ - `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.
43
+ - 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.
44
+ - Releases_: Want to know what's been added in recent Coconut versions? Check out the release log for all the new features and fixes.
45
+
46
+ .. _Python: https://www.python.org/
47
+ .. _PyPI: https://pypi.python.org/pypi/coconut
48
+ .. _Tutorial: http://coconut.readthedocs.io/en/latest/HELP.html
49
+ .. _Documentation: http://coconut.readthedocs.io/en/latest/DOCS.html
50
+ .. _`Online Interpreter`: https://cs121-team-panda.github.io/coconut-interpreter
51
+ .. _FAQ: http://coconut.readthedocs.io/en/latest/FAQ.html
52
+ .. _GitHub: https://github.com/evhub/coconut
53
+ .. _Gitter: https://gitter.im/evhub/coconut
54
+ .. _Releases: https://github.com/evhub/coconut/releases
55
+
56
+ Credits
57
+ +++++++
58
+
59
+ Contributors
60
+ ------------
61
+
62
+ This project exists thanks to all the people who contribute! `Become a contributor`__.
63
+
64
+ .. image:: https://opencollective.com/coconut/contributors.svg?width=890&button=false
65
+ :target: https://github.com/evhub/coconut/graphs/contributors
66
+
67
+ __ Contributor_
68
+ .. _Contributor: http://coconut.readthedocs.io/en/develop/CONTRIBUTING.html
69
+
70
+ Backers
71
+ -------
72
+
73
+ Thank you to all our backers! `Become a backer`__.
74
+
75
+ .. image:: https://opencollective.com/coconut/backers.svg?width=890
76
+ :target: https://opencollective.com/coconut#backers
77
+
78
+ __ Backer_
79
+ .. _Backer: https://opencollective.com/coconut#backer
80
+
81
+ Sponsors
82
+ --------
83
+
84
+ Support Coconut by becoming a sponsor. Your logo will show up here with a link to your website. `Become a sponsor`__.
85
+
86
+ .. image:: https://opencollective.com/XX/sponsor/0/avatar.svg
87
+ :target: https://opencollective.com/coconut/sponsor/0/website
88
+
89
+ __ Sponsor_
90
+ .. _Sponsor: https://opencollective.com/coconut#sponsor
91
+
92
+ 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,λ
93
+ Platform: UNKNOWN
94
+ Classifier: Development Status :: 5 - Production/Stable
95
+ Classifier: License :: OSI Approved :: Apache Software License
96
+ Classifier: Intended Audience :: Developers
97
+ Classifier: Topic :: Software Development
98
+ Classifier: Topic :: Software Development :: Code Generators
99
+ Classifier: Topic :: Software Development :: Compilers
100
+ Classifier: Topic :: Software Development :: Interpreters
101
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
102
+ Classifier: Topic :: Utilities
103
+ Classifier: Environment :: Console
104
+ Classifier: Operating System :: OS Independent
105
+ Classifier: Programming Language :: Python
106
+ Classifier: Programming Language :: Python :: 2
107
+ Classifier: Programming Language :: Python :: 2.6
108
+ Classifier: Programming Language :: Python :: 2.7
109
+ Classifier: Programming Language :: Python :: 3
110
+ Classifier: Programming Language :: Python :: 3.2
111
+ Classifier: Programming Language :: Python :: 3.3
112
+ Classifier: Programming Language :: Python :: 3.4
113
+ Classifier: Programming Language :: Python :: 3.5
114
+ Classifier: Programming Language :: Python :: 3.6
115
+ Classifier: Programming Language :: Python :: 3.7
116
+ Classifier: Programming Language :: Python :: 3.8
117
+ Classifier: Programming Language :: Python :: 3.9
118
+ Classifier: Programming Language :: Python :: 3.10
119
+ Classifier: Programming Language :: Python :: 3.11
120
+ Classifier: Programming Language :: Python :: 3.12
121
+ Classifier: Programming Language :: Other
122
+ Classifier: Programming Language :: Other Scripting Engines
123
+ Classifier: Programming Language :: Python :: Implementation :: CPython
124
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
125
+ Classifier: Framework :: IPython
126
+ Classifier: Framework :: Jupyter
127
+ Classifier: Typing :: Typed
128
+ Provides-Extra: kernel
129
+ Provides-Extra: watch
130
+ Provides-Extra: mypy
131
+ Provides-Extra: pyright
132
+ Provides-Extra: xonsh
133
+ Provides-Extra: numpy
134
+ Provides-Extra: jupyter
135
+ Provides-Extra: jupyterlab
136
+ Provides-Extra: jupytext
137
+ Provides-Extra: all
138
+ Provides-Extra: ipython
139
+ Provides-Extra: docs
140
+ Provides-Extra: tests
141
+ Provides-Extra: dev
@@ -37,11 +37,11 @@ from contextlib import contextmanager
37
37
  from functools import partial, wraps
38
38
  from collections import defaultdict
39
39
  from threading import Lock
40
+ from copy import copy
40
41
 
41
42
  from coconut._pyparsing import (
42
43
  USE_COMPUTATION_GRAPH,
43
44
  USE_CACHE,
44
- USE_LINE_BY_LINE,
45
45
  ParseBaseException,
46
46
  ParseResults,
47
47
  col as getcol,
@@ -108,6 +108,7 @@ from coconut.util import (
108
108
  assert_remove_suffix,
109
109
  dictset,
110
110
  noop_ctx,
111
+ create_method,
111
112
  )
112
113
  from coconut.exceptions import (
113
114
  CoconutException,
@@ -155,6 +156,7 @@ from coconut.compiler.util import (
155
156
  match_in,
156
157
  transform,
157
158
  parse,
159
+ cached_parse,
158
160
  get_target_info_smart,
159
161
  split_leading_comments,
160
162
  compile_regex,
@@ -404,6 +406,7 @@ class Compiler(Grammar, pickleable_obj):
404
406
  """The Coconut compiler."""
405
407
  lock = Lock()
406
408
  current_compiler = None
409
+ computation_graph_caches = defaultdict(dict)
407
410
 
408
411
  preprocs = [
409
412
  lambda self: self.prepare,
@@ -428,7 +431,7 @@ class Compiler(Grammar, pickleable_obj):
428
431
  ]
429
432
 
430
433
  def __init__(self, *args, **kwargs):
431
- """Creates a new compiler with the given parsing parameters."""
434
+ """Create a new compiler with the given parsing parameters."""
432
435
  self.setup(*args, **kwargs)
433
436
  self.reset()
434
437
 
@@ -464,7 +467,7 @@ class Compiler(Grammar, pickleable_obj):
464
467
  self.no_wrap = no_wrap
465
468
 
466
469
  def __reduce__(self):
467
- """Return pickling information."""
470
+ """Get pickling information."""
468
471
  return (self.__class__, (self.target, self.strict, self.minify, self.line_numbers, self.keep_lines, self.no_tco, self.no_wrap))
469
472
 
470
473
  def get_cli_args(self):
@@ -484,12 +487,16 @@ class Compiler(Grammar, pickleable_obj):
484
487
  args.append("--no-wrap-types")
485
488
  return args
486
489
 
487
- def __copy__(self):
488
- """Create a new, blank copy of the compiler."""
489
- cls, args = self.__reduce__()
490
- return cls(*args)
491
-
492
- copy = __copy__
490
+ def copy(self, snapshot=False):
491
+ """Create a blank copy of the compiler, or a non-blank copy if snapshot=True."""
492
+ if snapshot:
493
+ old_reduce, self.__reduce__ = self.__reduce__, create_method(object.__reduce__, self, self.__class__)
494
+ try:
495
+ return copy(self)
496
+ finally:
497
+ self.__reduce__ = old_reduce
498
+ else:
499
+ return copy(self)
493
500
 
494
501
  def genhash(self, code, package_level=-1):
495
502
  """Generate a hash from code."""
@@ -637,6 +644,8 @@ class Compiler(Grammar, pickleable_obj):
637
644
  if trim_arity:
638
645
  self_method = _trim_arity(self_method)
639
646
  return self_method(original, loc, tokens_or_item)
647
+ if kwargs:
648
+ method.__name__ = py_str(method.__name__ + "$(" + ", ".join(str(k) + "=" + repr(v) for k, v in kwargs.items()) + ")")
640
649
  internal_assert(
641
650
  hasattr(cls_method, "ignore_arguments") is hasattr(method, "ignore_arguments")
642
651
  and hasattr(cls_method, "ignore_no_tokens") is hasattr(method, "ignore_no_tokens")
@@ -1079,18 +1088,20 @@ class Compiler(Grammar, pickleable_obj):
1079
1088
  """Wrap a comment."""
1080
1089
  return "#" + self.add_ref("comment", text) + unwrapper
1081
1090
 
1082
- def wrap_error(self, error):
1091
+ def wrap_error(self, error_maker):
1083
1092
  """Create a symbol that will raise the given error in postprocessing."""
1084
- return errwrapper + self.add_ref("error", error) + unwrapper
1093
+ return errwrapper + self.add_ref("error_maker", error_maker) + unwrapper
1085
1094
 
1086
- def raise_or_wrap_error(self, error):
1087
- """Raise if USE_COMPUTATION_GRAPH else wrap."""
1095
+ def raise_or_wrap_error(self, *args, **kwargs):
1096
+ """Raise or defer if USE_COMPUTATION_GRAPH else wrap."""
1097
+ error_maker = partial(self.make_err, *args, **kwargs)
1088
1098
  if not USE_COMPUTATION_GRAPH:
1089
- return self.wrap_error(error)
1099
+ return self.wrap_error(error_maker)
1100
+ # differently-ordered any ofs can push these errors earlier than they should be, requiring us to defer them
1090
1101
  elif use_adaptive_any_of or reverse_any_of:
1091
- return ExceptionNode(error)
1102
+ return ExceptionNode(error_maker)
1092
1103
  else:
1093
- raise error
1104
+ raise error_maker()
1094
1105
 
1095
1106
  def type_ignore_comment(self):
1096
1107
  """Get a "type: ignore" comment."""
@@ -1357,7 +1368,7 @@ class Compiler(Grammar, pickleable_obj):
1357
1368
 
1358
1369
  def parse_line_by_line(self, init_parser, line_parser, original):
1359
1370
  """Apply init_parser then line_parser repeatedly."""
1360
- if not USE_LINE_BY_LINE:
1371
+ if not USE_COMPUTATION_GRAPH:
1361
1372
  raise CoconutException("line-by-line parsing not supported", extra="run 'pip install --upgrade cPyparsing' to fix")
1362
1373
  with ComputationNode.using_overrides():
1363
1374
  ComputationNode.override_original = original
@@ -1367,14 +1378,20 @@ class Compiler(Grammar, pickleable_obj):
1367
1378
  while cur_loc < len(original):
1368
1379
  self.remaining_original = original[cur_loc:]
1369
1380
  ComputationNode.add_to_loc = cur_loc
1370
- results = parse(init_parser if init else line_parser, self.remaining_original, inner=False)
1381
+ parser = init_parser if init else line_parser
1382
+ results = cached_parse(
1383
+ self.computation_graph_caches[("line_by_line", parser)],
1384
+ parser,
1385
+ self.remaining_original,
1386
+ inner=False,
1387
+ )
1371
1388
  if len(results) == 1:
1372
1389
  got_loc, = results
1373
1390
  else:
1374
1391
  got, got_loc = results
1375
1392
  out_parts.append(got)
1376
1393
  got_loc = int(got_loc)
1377
- internal_assert(got_loc >= cur_loc and (init or got_loc > cur_loc), "invalid line by line parse", (cur_loc, results), extra=lambda: "in: " + repr(self.remaining_original.split("\n", 1)[0]))
1394
+ internal_assert(got_loc >= cur_loc and (init or got_loc > cur_loc), "invalid line by line parse", (cur_loc, got_loc, results), extra=lambda: "in: " + repr(self.remaining_original.split("\n", 1)[0]))
1378
1395
  cur_loc = got_loc
1379
1396
  init = False
1380
1397
  return "".join(out_parts)
@@ -2729,7 +2746,7 @@ else:
2729
2746
  pre_err_line, err_line = raw_line.split(errwrapper, 1)
2730
2747
  err_ref, post_err_line = err_line.split(unwrapper, 1)
2731
2748
  if not ignore_errors:
2732
- raise self.get_ref("error", err_ref)
2749
+ raise self.get_ref("error_maker", err_ref)()
2733
2750
  raw_line = pre_err_line + " " + post_err_line
2734
2751
 
2735
2752
  # look for functions
@@ -4877,6 +4894,7 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
4877
4894
 
4878
4895
  where_assigns = self.current_parsing_context("where")["assigns"]
4879
4896
  internal_assert(lambda: where_assigns is not None, "missing where_assigns")
4897
+ print(where_assigns)
4880
4898
 
4881
4899
  where_init = "".join(body_stmts)
4882
4900
  where_final = main_stmt + "\n"
@@ -4976,7 +4994,8 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
4976
4994
  if self.disable_name_check:
4977
4995
  return name
4978
4996
 
4979
- if assign:
4997
+ # register non-mid-expression variable assignments inside of where statements for later mangling
4998
+ if assign and not expr_setname:
4980
4999
  where_context = self.current_parsing_context("where")
4981
5000
  if where_context is not None:
4982
5001
  where_assigns = where_context["assigns"]
@@ -5007,13 +5026,11 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
5007
5026
  if typevar_info["typevar_locs"].get(name, None) != loc:
5008
5027
  if assign:
5009
5028
  return self.raise_or_wrap_error(
5010
- self.make_err(
5011
- CoconutSyntaxError,
5012
- "cannot reassign type variable '{name}'".format(name=name),
5013
- original,
5014
- loc,
5015
- extra="use explicit '\\{name}' syntax if intended".format(name=name),
5016
- ),
5029
+ CoconutSyntaxError,
5030
+ "cannot reassign type variable '{name}'".format(name=name),
5031
+ original,
5032
+ loc,
5033
+ extra="use explicit '\\{name}' syntax if intended".format(name=name),
5017
5034
  )
5018
5035
  return typevars[name]
5019
5036
 
@@ -5044,13 +5061,11 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
5044
5061
  return name
5045
5062
  elif assign:
5046
5063
  return self.raise_or_wrap_error(
5047
- self.make_err(
5048
- CoconutTargetError,
5049
- "found Python-3-only assignment to 'exec' as a variable name",
5050
- original,
5051
- loc,
5052
- target="3",
5053
- ),
5064
+ CoconutTargetError,
5065
+ "found Python-3-only assignment to 'exec' as a variable name",
5066
+ original,
5067
+ loc,
5068
+ target="3",
5054
5069
  )
5055
5070
  else:
5056
5071
  return "_coconut_exec"
@@ -5063,12 +5078,10 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
5063
5078
  return name
5064
5079
  elif not escaped and name.startswith(reserved_prefix) and name not in self.operators:
5065
5080
  return self.raise_or_wrap_error(
5066
- self.make_err(
5067
- CoconutSyntaxError,
5068
- "variable names cannot start with reserved prefix '{prefix}' (use explicit '\\{name}' syntax if intending to access Coconut internals)".format(prefix=reserved_prefix, name=name),
5069
- original,
5070
- loc,
5071
- ),
5081
+ CoconutSyntaxError,
5082
+ "variable names cannot start with reserved prefix '{prefix}' (use explicit '\\{name}' syntax if intending to access Coconut internals)".format(prefix=reserved_prefix, name=name),
5083
+ original,
5084
+ loc,
5072
5085
  )
5073
5086
  else:
5074
5087
  return name
@@ -5091,7 +5104,7 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
5091
5104
  else:
5092
5105
  if always_warn:
5093
5106
  kwargs["extra"] = "remove --strict to downgrade to a warning"
5094
- return self.raise_or_wrap_error(self.make_err(CoconutStyleError, message, original, loc, **kwargs))
5107
+ return self.raise_or_wrap_error(CoconutStyleError, message, original, loc, **kwargs)
5095
5108
  elif always_warn:
5096
5109
  self.syntax_warning(message, original, loc)
5097
5110
  return tokens[0]
@@ -5132,13 +5145,13 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
5132
5145
  self.internal_assert(len(tokens) == 1, original, loc, "invalid " + name + " tokens", tokens)
5133
5146
  version_info = get_target_info(version)
5134
5147
  if self.target_info < version_info:
5135
- return self.raise_or_wrap_error(self.make_err(
5148
+ return self.raise_or_wrap_error(
5136
5149
  CoconutTargetError,
5137
5150
  "found Python " + ".".join(str(v) for v in version_info) + " " + name,
5138
5151
  original,
5139
5152
  loc,
5140
5153
  target=version,
5141
- ))
5154
+ )
5142
5155
  else:
5143
5156
  return tokens[0]
5144
5157
 
@@ -2616,7 +2616,6 @@ class Grammar(object):
2616
2616
  decoratable_data_stmt,
2617
2617
  match_stmt,
2618
2618
  passthrough_stmt,
2619
- where_stmt,
2620
2619
  )
2621
2620
 
2622
2621
  flow_stmt = any_of(
@@ -2661,8 +2660,8 @@ class Grammar(object):
2661
2660
  stmt <<= final(
2662
2661
  compound_stmt
2663
2662
  | simple_stmt # includes destructuring
2664
- # must be after destructuring due to ambiguity
2665
- | cases_stmt
2663
+ | cases_stmt # must be after destructuring due to ambiguity
2664
+ | where_stmt # slows down parsing when put before simple_stmt
2666
2665
  # at the very end as a fallback case for the anything parser
2667
2666
  | anything_stmt
2668
2667
  )
@@ -2781,8 +2780,6 @@ class Grammar(object):
2781
2780
  rparen,
2782
2781
  ) + end_marker,
2783
2782
  tco_return_handle,
2784
- # this is the root in what it's used for, so might as well evaluate greedily
2785
- greedy=True,
2786
2783
  ))
2787
2784
 
2788
2785
  rest_of_lambda = Forward()
@@ -199,6 +199,7 @@ def evaluate_tokens(tokens, **kwargs):
199
199
 
200
200
  if not USE_COMPUTATION_GRAPH:
201
201
  return tokens
202
+ final_evaluate_tokens.enabled = True # special variable used by cached_parse
202
203
 
203
204
  if isinstance(tokens, ParseResults):
204
205
 
@@ -264,7 +265,7 @@ def evaluate_tokens(tokens, **kwargs):
264
265
  elif isinstance(tokens, ComputationNode):
265
266
  result = tokens.evaluate()
266
267
  if is_final and isinstance(result, ExceptionNode):
267
- raise result.exception
268
+ result.evaluate()
268
269
  elif isinstance(result, ParseResults):
269
270
  return make_modified_tokens(result, cls=MergeNode)
270
271
  elif isinstance(result, list):
@@ -285,7 +286,7 @@ def evaluate_tokens(tokens, **kwargs):
285
286
 
286
287
  elif isinstance(tokens, ExceptionNode):
287
288
  if is_final:
288
- raise tokens.exception
289
+ tokens.evaluate()
289
290
  return tokens
290
291
 
291
292
  elif isinstance(tokens, DeferredNode):
@@ -320,9 +321,12 @@ def build_new_toks_for(tokens, new_toklist, unchanged=False):
320
321
  return new_toklist
321
322
 
322
323
 
324
+ cached_trim_arity = memoize()(_trim_arity)
325
+
326
+
323
327
  class ComputationNode(object):
324
328
  """A single node in the computation graph."""
325
- __slots__ = ("action", "original", "loc", "tokens")
329
+ __slots__ = ("action", "original", "loc", "tokens", "trim_arity")
326
330
  pprinting = False
327
331
  override_original = None
328
332
  add_to_loc = 0
@@ -338,7 +342,7 @@ class ComputationNode(object):
338
342
  cls.override_original = override_original
339
343
  cls.add_to_loc = add_to_loc
340
344
 
341
- def __new__(cls, action, original, loc, tokens, ignore_no_tokens=False, ignore_one_token=False, greedy=False, trim_arity=True):
345
+ def __new__(cls, action, original, loc, tokens, trim_arity=True, ignore_no_tokens=False, ignore_one_token=False, greedy=False):
342
346
  """Create a ComputionNode to return from a parse action.
343
347
 
344
348
  If ignore_no_tokens, then don't call the action if there are no tokens.
@@ -349,18 +353,20 @@ class ComputationNode(object):
349
353
  return build_new_toks_for(tokens, tokens, unchanged=True)
350
354
  else:
351
355
  self = super(ComputationNode, cls).__new__(cls)
352
- if trim_arity:
353
- self.action = _trim_arity(action)
354
- else:
355
- self.action = action
356
- self.original = original if self.override_original is None else self.override_original
357
- self.loc = self.add_to_loc + loc
356
+ self.action = action
357
+ self.original = original
358
+ self.loc = loc
358
359
  self.tokens = tokens
360
+ self.trim_arity = trim_arity
359
361
  if greedy:
360
362
  return self.evaluate()
361
363
  else:
362
364
  return self
363
365
 
366
+ def __reduce__(self):
367
+ """Get pickling information."""
368
+ return (self.__class__, (self.action, self.original, self.loc, self.tokens, self.trim_arity))
369
+
364
370
  @property
365
371
  def name(self):
366
372
  """Get the name of the action."""
@@ -374,15 +380,25 @@ class ComputationNode(object):
374
380
  # note that this should never cache, since if a greedy Wrap that doesn't add to the packrat context
375
381
  # hits the cache, it'll get the same ComputationNode object, but since it's greedy that object needs
376
382
  # to actually be reevaluated
383
+ if logger.tracing and not final_evaluate_tokens.enabled:
384
+ logger.log_tag("cached_parse invalidated by", self)
385
+
386
+ if self.trim_arity:
387
+ using_action = cached_trim_arity(self.action)
388
+ else:
389
+ using_action = self.action
390
+ using_original = self.original if self.override_original is None else self.override_original
391
+ using_loc = self.loc + self.add_to_loc
377
392
  evaluated_toks = evaluate_tokens(self.tokens)
393
+
378
394
  if logger.tracing: # avoid the overhead of the call if not tracing
379
- logger.log_trace(self.name, self.original, self.loc, evaluated_toks, self.tokens)
395
+ logger.log_trace(self.name, using_original, using_loc, evaluated_toks, self.tokens)
380
396
  if isinstance(evaluated_toks, ExceptionNode):
381
397
  return evaluated_toks # short-circuit if we got an ExceptionNode
382
398
  try:
383
- result = self.action(
384
- self.original,
385
- self.loc,
399
+ result = using_action(
400
+ using_original,
401
+ using_loc,
386
402
  evaluated_toks,
387
403
  )
388
404
  except CoconutException:
@@ -395,6 +411,7 @@ class ComputationNode(object):
395
411
  embed(depth=2)
396
412
  else:
397
413
  raise error
414
+
398
415
  out = build_new_toks_for(evaluated_toks, result)
399
416
  if logger.tracing: # avoid the overhead if not tracing
400
417
  dropped_keys = set(self.tokens._ParseResults__tokdict.keys())
@@ -431,12 +448,16 @@ class DeferredNode(object):
431
448
 
432
449
  class ExceptionNode(object):
433
450
  """A node in the computation graph that stores an exception that will be raised upon final evaluation."""
434
- __slots__ = ("exception",)
451
+ __slots__ = ("exception_maker",)
435
452
 
436
- def __init__(self, exception):
453
+ def __init__(self, exception_maker):
437
454
  if not USE_COMPUTATION_GRAPH:
438
- raise exception
439
- self.exception = exception
455
+ raise exception_maker()
456
+ self.exception_maker = exception_maker
457
+
458
+ def evaluate(self):
459
+ """Raise the stored exception."""
460
+ raise self.exception_maker()
440
461
 
441
462
 
442
463
  class CombineToNode(Combine):
@@ -523,12 +544,17 @@ def attach(item, action, ignore_no_tokens=None, ignore_one_token=None, ignore_ar
523
544
 
524
545
  def final_evaluate_tokens(tokens):
525
546
  """Same as evaluate_tokens but should only be used once a parse is assured."""
547
+ if not final_evaluate_tokens.enabled: # handled by cached_parse
548
+ return tokens
526
549
  result = evaluate_tokens(tokens, is_final=True)
527
550
  # clear packrat cache after evaluating tokens so error creation gets to see the cache
528
551
  clear_packrat_cache()
529
552
  return result
530
553
 
531
554
 
555
+ final_evaluate_tokens.enabled = True
556
+
557
+
532
558
  def final(item):
533
559
  """Collapse the computation graph upon parsing the given item."""
534
560
  # evaluate_tokens expects a computation graph, so we just call add_action directly
@@ -674,17 +700,66 @@ def parse(grammar, text, inner=None, eval_parse_tree=True):
674
700
  return result
675
701
 
676
702
 
677
- def try_parse(grammar, text, inner=None, eval_parse_tree=True):
703
+ def cached_parse(computation_graph_cache, grammar, text, inner=None, eval_parse_tree=True):
704
+ """Version of parse that caches the result when it's a pure ComputationNode."""
705
+ if not CPYPARSING: # caching is only supported on cPyparsing
706
+ return parse(grammar, text, inner)
707
+
708
+ for (prefix, is_at_end), tokens in computation_graph_cache.items():
709
+ # the assumption here is that if the prior parse didn't make it to the end,
710
+ # then we can freely change the text after the end of where it made it,
711
+ # but if it did make it to the end, then we can't add more text after that
712
+ if (
713
+ is_at_end and text == prefix
714
+ or not is_at_end and text.startswith(prefix)
715
+ ):
716
+ if DEVELOP:
717
+ logger.record_stat("cached_parse", True)
718
+ logger.log_tag("cached_parse hit", (prefix, text[len(prefix):], tokens))
719
+ break
720
+ else: # no break
721
+ # disable token evaluation by final() to allow us to get a ComputationNode;
722
+ # this makes long parses very slow, however, so once a greedy parse action
723
+ # is hit such that evaluate_tokens gets called, evaluate_tokens will set
724
+ # final_evaluate_tokens.enabled back to True, which speeds up the rest of the
725
+ # parse and tells us that something greedy happened so we can't cache
726
+ final_evaluate_tokens.enabled = False
727
+ try:
728
+ with parsing_context(inner):
729
+ loc, tokens = prep_grammar(grammar, for_scan=False).parseString(text, returnLoc=True)
730
+ if not final_evaluate_tokens.enabled:
731
+ prefix = text[:loc + 1]
732
+ is_at_end = loc >= len(text)
733
+ computation_graph_cache[(prefix, is_at_end)] = tokens
734
+ finally:
735
+ if DEVELOP:
736
+ logger.record_stat("cached_parse", False)
737
+ logger.log_tag(
738
+ "cached_parse miss " + ("-> stored" if not final_evaluate_tokens.enabled else "(not stored)"),
739
+ text,
740
+ multiline=True,
741
+ )
742
+ final_evaluate_tokens.enabled = True
743
+
744
+ if eval_parse_tree:
745
+ tokens = unpack(tokens)
746
+ return tokens
747
+
748
+
749
+ def try_parse(grammar, text, inner=None, eval_parse_tree=True, computation_graph_cache=None):
678
750
  """Attempt to parse text using grammar else None."""
679
751
  try:
680
- return parse(grammar, text, inner, eval_parse_tree)
752
+ if computation_graph_cache is None:
753
+ return parse(grammar, text, inner, eval_parse_tree)
754
+ else:
755
+ return cached_parse(computation_graph_cache, grammar, text, inner, eval_parse_tree)
681
756
  except ParseBaseException:
682
757
  return None
683
758
 
684
759
 
685
- def does_parse(grammar, text, inner=None):
760
+ def does_parse(grammar, text, inner=None, **kwargs):
686
761
  """Determine if text can be parsed using grammar."""
687
- return try_parse(grammar, text, inner, eval_parse_tree=False)
762
+ return try_parse(grammar, text, inner, eval_parse_tree=False, **kwargs)
688
763
 
689
764
 
690
765
  def all_matches(grammar, text, inner=None, eval_parse_tree=True):
@@ -1370,6 +1445,8 @@ class Wrap(ParseElementEnhance):
1370
1445
  with self.wrapped_context():
1371
1446
  parse_loc, tokens = super(Wrap, self).parseImpl(original, loc, *args, **kwargs)
1372
1447
  if self.greedy:
1448
+ if logger.tracing and not final_evaluate_tokens.enabled:
1449
+ logger.log_tag("cached_parse invalidated by", self)
1373
1450
  tokens = evaluate_tokens(tokens)
1374
1451
  if reparse and parse_loc is None:
1375
1452
  raise CoconutInternalException("illegal double reparse in", self)
@@ -1050,7 +1050,7 @@ all_reqs = {
1050
1050
 
1051
1051
  # min versions are inclusive
1052
1052
  unpinned_min_versions = {
1053
- "cPyparsing": (2, 4, 7, 2, 4, 0),
1053
+ "cPyparsing": (2, 4, 7, 2, 4, 1),
1054
1054
  ("pre-commit", "py3"): (3,),
1055
1055
  ("psutil", "py>=27"): (6,),
1056
1056
  "jupyter": (1, 1),
@@ -0,0 +1,11 @@
1
+ {
2
+ "argv": [
3
+ "python",
4
+ "-m",
5
+ "coconut.icoconut",
6
+ "-f",
7
+ "{connection_file}"
8
+ ],
9
+ "display_name": "Coconut",
10
+ "language": "coconut"
11
+ }
@@ -26,7 +26,7 @@ import sys as _coconut_sys
26
26
  VERSION = "3.1.2"
27
27
  VERSION_NAME = None
28
28
  # False for release, int >= 1 for develop
29
- DEVELOP = 1
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"
@@ -561,7 +561,10 @@ class Logger(object):
561
561
  return item
562
562
 
563
563
  def record_stat(self, stat_name, stat_bool):
564
- """Record the given boolean statistic for the given stat_name."""
564
+ """Record the given boolean statistic for the given stat_name.
565
+
566
+ All stats recorded here must have some printing logic added to gather_parsing_stats or log_compiler_stats.
567
+ Printed stats should also be added to the regex in the Makefile for getting non-informational lines."""
565
568
  self.recorded_stats[stat_name][stat_bool] += 1
566
569
 
567
570
  @contextmanager
@@ -569,6 +572,7 @@ class Logger(object):
569
572
  """Times parsing if --verbose."""
570
573
  if self.verbose:
571
574
  self.recorded_stats.pop("adaptive", None)
575
+ self.recorded_stats.pop("cached_parse", None)
572
576
  start_time = get_clock_time()
573
577
  try:
574
578
  yield
@@ -584,6 +588,9 @@ class Logger(object):
584
588
  if "adaptive" in self.recorded_stats:
585
589
  failures, successes = self.recorded_stats["adaptive"]
586
590
  self.printlog("\tAdaptive parsing stats:", successes, "successes;", failures, "failures")
591
+ if "cached_parse" in self.recorded_stats:
592
+ misses, hits = self.recorded_stats["cached_parse"]
593
+ self.printlog("\tComputation graph cache stats:", hits, "hits;", misses, "misses")
587
594
  if maybe_make_safe is not None:
588
595
  hits, misses = maybe_make_safe.stats
589
596
  self.printlog("\tErrorless parsing stats:", hits, "errorless;", misses, "with errors")
@@ -595,10 +602,9 @@ class Logger(object):
595
602
  if self.verbose:
596
603
  self.log("Grammar init time: " + str(comp.grammar_init_time) + " secs / Total init time: " + str(get_clock_time() - first_import_time) + " secs")
597
604
  for stat_name, (no_copy, yes_copy) in self.recorded_stats.items():
598
- if not stat_name.startswith("maybe_copy_"):
599
- continue
600
- name = assert_remove_prefix(stat_name, "maybe_copy_")
601
- self.printlog("\tGrammar copying stats (" + name + "):", no_copy, "not copied;", yes_copy, "copied")
605
+ if stat_name.startswith("maybe_copy_"):
606
+ name = assert_remove_prefix(stat_name, "maybe_copy_")
607
+ self.printlog("\tGrammar copying stats (" + name + "):", no_copy, "not copied;", yes_copy, "copied")
602
608
 
603
609
  total_block_time = defaultdict(int)
604
610
 
@@ -107,6 +107,14 @@ class const(pickleable_obj):
107
107
  return self.value
108
108
 
109
109
 
110
+ def create_method(func, obj, objtype):
111
+ """Universally create a new method object."""
112
+ if PY2:
113
+ return MethodType(func, obj, objtype)
114
+ else:
115
+ return MethodType(func, obj)
116
+
117
+
110
118
  class override(pickleable_obj):
111
119
  """Implementation of Coconut's @override for use within Coconut."""
112
120
  __slots__ = ("func",)
@@ -129,10 +137,7 @@ class override(pickleable_obj):
129
137
  return self.func.__get__(obj, objtype)
130
138
  if obj is None:
131
139
  return self.func
132
- if PY2:
133
- return MethodType(self.func, obj, objtype)
134
- else:
135
- return MethodType(self.func, obj)
140
+ return create_method(self.func, obj, objtype)
136
141
 
137
142
  def __set_name__(self, obj, name):
138
143
  if not hasattr(super(obj, obj), name):
@@ -1,141 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: coconut-develop
3
- Version: 3.1.2.post0.dev1
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,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,λ
10
- Classifier: Development Status :: 5 - Production/Stable
11
- Classifier: License :: OSI Approved :: Apache Software License
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Software Development
14
- Classifier: Topic :: Software Development :: Code Generators
15
- Classifier: Topic :: Software Development :: Compilers
16
- Classifier: Topic :: Software Development :: Interpreters
17
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
- Classifier: Topic :: Utilities
19
- Classifier: Environment :: Console
20
- Classifier: Operating System :: OS Independent
21
- Classifier: Programming Language :: Python
22
- Classifier: Programming Language :: Python :: 2
23
- Classifier: Programming Language :: Python :: 2.6
24
- Classifier: Programming Language :: Python :: 2.7
25
- Classifier: Programming Language :: Python :: 3
26
- Classifier: Programming Language :: Python :: 3.2
27
- Classifier: Programming Language :: Python :: 3.3
28
- Classifier: Programming Language :: Python :: 3.4
29
- Classifier: Programming Language :: Python :: 3.5
30
- Classifier: Programming Language :: Python :: 3.6
31
- Classifier: Programming Language :: Python :: 3.7
32
- Classifier: Programming Language :: Python :: 3.8
33
- Classifier: Programming Language :: Python :: 3.9
34
- Classifier: Programming Language :: Python :: 3.10
35
- Classifier: Programming Language :: Python :: 3.11
36
- Classifier: Programming Language :: Python :: 3.12
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: pyright
48
- Provides-Extra: xonsh
49
- Provides-Extra: numpy
50
- Provides-Extra: jupyter
51
- Provides-Extra: jupyterlab
52
- Provides-Extra: jupytext
53
- Provides-Extra: all
54
- Provides-Extra: ipython
55
- Provides-Extra: docs
56
- Provides-Extra: tests
57
- Provides-Extra: dev
58
- License-File: LICENSE.txt
59
-
60
- |logo| Coconut
61
- ==============
62
-
63
- ..
64
- <insert toctree here>
65
-
66
- .. |logo| image:: https://github.com/evhub/coconut/raw/gh-pages/favicon-32x32.png
67
-
68
- .. image:: https://opencollective.com/coconut/backers/badge.svg
69
- :alt: Backers on Open Collective
70
- :target: #backers
71
- .. image:: https://opencollective.com/coconut/sponsors/badge.svg
72
- :alt: Sponsors on Open Collective
73
- :target: #sponsors
74
- .. image:: https://badges.gitter.im/evhub/coconut.svg
75
- :alt: Join the chat at https://gitter.im/evhub/coconut
76
- :target: https://gitter.im/evhub/coconut?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
77
-
78
- Coconut (`coconut-lang.org`__) is a variant of Python_ that **adds on top of Python syntax** new features for simple, elegant, Pythonic **functional programming**.
79
-
80
- __ Coconut_
81
- .. _Coconut: http://coconut-lang.org/
82
-
83
- Coconut is developed on GitHub_ and hosted on PyPI_. Installing Coconut is as easy as opening a command prompt and entering::
84
-
85
- pip install coconut
86
-
87
- To help you get started, check out these links for more information about Coconut:
88
-
89
- - Tutorial_: If you're new to Coconut, a good place to start is Coconut's **tutorial**.
90
- - Documentation_: If you're looking for info about a specific feature, check out Coconut's **documentation**.
91
- - `Online Interpreter`_: If you want to try Coconut in your browser, check out Coconut's **online interpreter**.
92
- - 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.
93
- - `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.
94
- - 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.
95
- - Releases_: Want to know what's been added in recent Coconut versions? Check out the release log for all the new features and fixes.
96
-
97
- .. _Python: https://www.python.org/
98
- .. _PyPI: https://pypi.python.org/pypi/coconut
99
- .. _Tutorial: http://coconut.readthedocs.io/en/latest/HELP.html
100
- .. _Documentation: http://coconut.readthedocs.io/en/latest/DOCS.html
101
- .. _`Online Interpreter`: https://cs121-team-panda.github.io/coconut-interpreter
102
- .. _FAQ: http://coconut.readthedocs.io/en/latest/FAQ.html
103
- .. _GitHub: https://github.com/evhub/coconut
104
- .. _Gitter: https://gitter.im/evhub/coconut
105
- .. _Releases: https://github.com/evhub/coconut/releases
106
-
107
- Credits
108
- +++++++
109
-
110
- Contributors
111
- ------------
112
-
113
- This project exists thanks to all the people who contribute! `Become a contributor`__.
114
-
115
- .. image:: https://opencollective.com/coconut/contributors.svg?width=890&button=false
116
- :target: https://github.com/evhub/coconut/graphs/contributors
117
-
118
- __ Contributor_
119
- .. _Contributor: http://coconut.readthedocs.io/en/develop/CONTRIBUTING.html
120
-
121
- Backers
122
- -------
123
-
124
- Thank you to all our backers! `Become a backer`__.
125
-
126
- .. image:: https://opencollective.com/coconut/backers.svg?width=890
127
- :target: https://opencollective.com/coconut#backers
128
-
129
- __ Backer_
130
- .. _Backer: https://opencollective.com/coconut#backer
131
-
132
- Sponsors
133
- --------
134
-
135
- Support Coconut by becoming a sponsor. Your logo will show up here with a link to your website. `Become a sponsor`__.
136
-
137
- .. image:: https://opencollective.com/XX/sponsor/0/avatar.svg
138
- :target: https://opencollective.com/coconut/sponsor/0/website
139
-
140
- __ Sponsor_
141
- .. _Sponsor: https://opencollective.com/coconut#sponsor
@@ -1,11 +0,0 @@
1
- {
2
- "argv": [
3
- "python",
4
- "-m",
5
- "coconut.icoconut",
6
- "-f",
7
- "{connection_file}"
8
- ],
9
- "display_name": "Coconut",
10
- "language": "coconut"
11
- }