coconut-develop 3.1.2.post0.dev2__tar.gz → 3.1.2.post0.dev3__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.dev2 → coconut-develop-3.1.2.post0.dev3}/PKG-INFO +1 -1
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/_pyparsing.py +1 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/compiler.py +304 -33
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/util.py +82 -227
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/constants.py +2 -1
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/root.py +5 -5
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/constants_test.py +2 -1
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/main_test.py +7 -6
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_2/py2_test.coco +1 -1
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/util.py +42 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/CONTRIBUTING.md +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/DOCS.md +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/FAQ.md +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/HELP.md +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/LICENSE.txt +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/MANIFEST.in +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/README.rst +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/__coconut__/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/__coconut__/__init__.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/__coconut__/py.typed +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/_coconut/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/_coconut/__init__.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/_coconut/py.typed +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/__coconut__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/__coconut__.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/__init__.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/__main__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/api.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/api.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/__init__.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/cli.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/command.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/command.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/mypy.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/resources/zcoconut.pth +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/util.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/command/watch.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/grammar.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/header.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/matching.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/templates/header.py_template +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/convenience.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/convenience.pyi +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/exceptions.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/highlighter.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/__main__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/coconut/kernel.json +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/coconut_py/kernel.json +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/coconut_py2/kernel.json +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/coconut_py3/kernel.json +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/embed.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/icoconut/root.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/integrations.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/main.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/py.typed +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/requirements.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/terminal.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/__init__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/__main__.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/__init__.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/__main__.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/main.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/primary_1.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/primary_2.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/specific.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/suite.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/tutorial.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/agnostic/util.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/non_strict/non_strict_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_3/py3_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_311/py311_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_35/py35_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_36/py36_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_38/py38_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/cocotest/target_sys/target_sys_test.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/extras.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/importable.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/runnable.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/tests/src/runner.coco +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut_develop.egg-info/SOURCES.txt +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/conf.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/pyproject.toml +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/setup.cfg +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/setup.py +0 -0
- {coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/xontrib/coconut.py +0 -0
|
@@ -263,6 +263,7 @@ if MODERN_PYPARSING:
|
|
|
263
263
|
else:
|
|
264
264
|
_trim_arity = _pyparsing._trim_arity
|
|
265
265
|
_ParseResultsWithOffset = _pyparsing._ParseResultsWithOffset
|
|
266
|
+
_trim_arity.inspect_tracebacks = False
|
|
266
267
|
|
|
267
268
|
maybe_make_safe = getattr(_pyparsing, "maybe_make_safe", None)
|
|
268
269
|
|
{coconut-develop-3.1.2.post0.dev2 → coconut-develop-3.1.2.post0.dev3}/coconut/compiler/compiler.py
RENAMED
|
@@ -34,7 +34,7 @@ import sys
|
|
|
34
34
|
import os
|
|
35
35
|
import re
|
|
36
36
|
from contextlib import contextmanager
|
|
37
|
-
from functools import partial,
|
|
37
|
+
from functools import partial, update_wrapper
|
|
38
38
|
from collections import defaultdict
|
|
39
39
|
from threading import Lock
|
|
40
40
|
from copy import copy
|
|
@@ -42,12 +42,16 @@ from copy import copy
|
|
|
42
42
|
from coconut._pyparsing import (
|
|
43
43
|
USE_COMPUTATION_GRAPH,
|
|
44
44
|
USE_CACHE,
|
|
45
|
+
SUPPORTS_INCREMENTAL,
|
|
45
46
|
ParseBaseException,
|
|
46
47
|
ParseResults,
|
|
48
|
+
ParserElement,
|
|
47
49
|
col as getcol,
|
|
48
50
|
lineno,
|
|
49
51
|
nums,
|
|
50
52
|
_trim_arity,
|
|
53
|
+
all_parse_elements,
|
|
54
|
+
__version__ as pyparsing_version,
|
|
51
55
|
)
|
|
52
56
|
|
|
53
57
|
from coconut.constants import (
|
|
@@ -94,8 +98,16 @@ from coconut.constants import (
|
|
|
94
98
|
use_adaptive_any_of,
|
|
95
99
|
reverse_any_of,
|
|
96
100
|
tempsep,
|
|
101
|
+
disable_incremental_for_len,
|
|
102
|
+
save_new_cache_items,
|
|
103
|
+
cache_validation_info,
|
|
104
|
+
incremental_mode_cache_size,
|
|
105
|
+
incremental_cache_limit,
|
|
106
|
+
use_line_by_line_parser,
|
|
107
|
+
coconut_cache_dir,
|
|
97
108
|
)
|
|
98
109
|
from coconut.util import (
|
|
110
|
+
pickle,
|
|
99
111
|
pickleable_obj,
|
|
100
112
|
checksum,
|
|
101
113
|
clip,
|
|
@@ -109,6 +121,9 @@ from coconut.util import (
|
|
|
109
121
|
dictset,
|
|
110
122
|
noop_ctx,
|
|
111
123
|
create_method,
|
|
124
|
+
univ_open,
|
|
125
|
+
staledict,
|
|
126
|
+
ensure_dir,
|
|
112
127
|
)
|
|
113
128
|
from coconut.exceptions import (
|
|
114
129
|
CoconutException,
|
|
@@ -141,6 +156,10 @@ from coconut.compiler.grammar import (
|
|
|
141
156
|
)
|
|
142
157
|
from coconut.compiler.util import (
|
|
143
158
|
ExceptionNode,
|
|
159
|
+
ComputationNode,
|
|
160
|
+
StartOfStrGrammar,
|
|
161
|
+
MatchAny,
|
|
162
|
+
CombineToNode,
|
|
144
163
|
sys_target,
|
|
145
164
|
getline,
|
|
146
165
|
addskip,
|
|
@@ -180,16 +199,20 @@ from coconut.compiler.util import (
|
|
|
180
199
|
close_char_for,
|
|
181
200
|
base_keyword,
|
|
182
201
|
enable_incremental_parsing,
|
|
202
|
+
disable_incremental_parsing,
|
|
183
203
|
get_psf_target,
|
|
184
204
|
move_loc_to_non_whitespace,
|
|
185
205
|
move_endpt_to_non_whitespace,
|
|
186
|
-
load_cache_for,
|
|
187
|
-
pickle_cache,
|
|
188
206
|
handle_and_manage,
|
|
189
207
|
manage,
|
|
190
208
|
sub_all,
|
|
191
|
-
|
|
192
|
-
|
|
209
|
+
get_cache_items_for,
|
|
210
|
+
clear_packrat_cache,
|
|
211
|
+
add_packrat_cache_items,
|
|
212
|
+
parse_elem_to_identifier,
|
|
213
|
+
identifier_to_parse_elem,
|
|
214
|
+
_lookup_loc,
|
|
215
|
+
_value_exc_loc_or_ret,
|
|
193
216
|
)
|
|
194
217
|
from coconut.compiler.header import (
|
|
195
218
|
minify_header,
|
|
@@ -396,6 +419,47 @@ def call_decorators(decorators, func_name):
|
|
|
396
419
|
return out
|
|
397
420
|
|
|
398
421
|
|
|
422
|
+
def get_cache_path(codepath):
|
|
423
|
+
"""Get the cache filename to use for the given codepath."""
|
|
424
|
+
code_dir, code_fname = os.path.split(codepath)
|
|
425
|
+
|
|
426
|
+
cache_dir = os.path.join(code_dir, coconut_cache_dir)
|
|
427
|
+
ensure_dir(cache_dir, logger=logger)
|
|
428
|
+
|
|
429
|
+
pickle_fname = code_fname + ".pkl"
|
|
430
|
+
return os.path.join(cache_dir, pickle_fname)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class CompilerMethodCaller(object):
|
|
434
|
+
"""Create a function that will call the given compiler method."""
|
|
435
|
+
# don't set anything up here since it'll be overwritten by update_wrapper
|
|
436
|
+
|
|
437
|
+
def __init__(self, method_name, trim_arity, kwargs):
|
|
438
|
+
update_wrapper(self, getattr(Compiler, method_name))
|
|
439
|
+
self.trim_arity = False
|
|
440
|
+
self._method_name = method_name
|
|
441
|
+
self._trim_arity = trim_arity
|
|
442
|
+
self._kwargs = kwargs
|
|
443
|
+
if kwargs:
|
|
444
|
+
self.__name__ = py_str(self.__name__ + "$(" + ", ".join(str(k) + "=" + repr(v) for k, v in kwargs.items()) + ")")
|
|
445
|
+
|
|
446
|
+
def __reduce__(self):
|
|
447
|
+
return (self.__class__, (self._method_name, self._trim_arity, self._kwargs))
|
|
448
|
+
|
|
449
|
+
def __call__(self, original, loc, tokens_or_item):
|
|
450
|
+
"""Performance sensitive."""
|
|
451
|
+
method = getattr(Compiler.current_compiler, self._method_name)
|
|
452
|
+
if self._kwargs:
|
|
453
|
+
if self._trim_arity:
|
|
454
|
+
return _trim_arity(partial(method, **self._kwargs))(original, loc, tokens_or_item)
|
|
455
|
+
else:
|
|
456
|
+
return method(original, loc, tokens_or_item, **self._kwargs)
|
|
457
|
+
else:
|
|
458
|
+
if self._trim_arity:
|
|
459
|
+
method = _trim_arity(method)
|
|
460
|
+
return method(original, loc, tokens_or_item)
|
|
461
|
+
|
|
462
|
+
|
|
399
463
|
# end: UTILITIES
|
|
400
464
|
# -----------------------------------------------------------------------------------------------------------------------
|
|
401
465
|
# COMPILER:
|
|
@@ -406,7 +470,6 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
406
470
|
"""The Coconut compiler."""
|
|
407
471
|
lock = Lock()
|
|
408
472
|
current_compiler = None
|
|
409
|
-
computation_graph_caches = defaultdict(dict)
|
|
410
473
|
|
|
411
474
|
preprocs = [
|
|
412
475
|
lambda self: self.prepare,
|
|
@@ -555,6 +618,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
555
618
|
self.add_code_before_ignore_names = {}
|
|
556
619
|
self.remaining_original = None
|
|
557
620
|
self.shown_warnings = set()
|
|
621
|
+
self.computation_graph_caches = defaultdict(staledict)
|
|
558
622
|
|
|
559
623
|
@contextmanager
|
|
560
624
|
def inner_environment(self, ln=None):
|
|
@@ -634,28 +698,26 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
634
698
|
cls_method = getattr(cls, method_name)
|
|
635
699
|
if is_action is None:
|
|
636
700
|
is_action = not method_name.endswith("_manage")
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
if kwargs:
|
|
643
|
-
self_method = partial(self_method, **kwargs)
|
|
644
|
-
if trim_arity:
|
|
645
|
-
self_method = _trim_arity(self_method)
|
|
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()) + ")")
|
|
701
|
+
method = CompilerMethodCaller(
|
|
702
|
+
method_name=method_name,
|
|
703
|
+
trim_arity=should_trim_arity(cls_method) if is_action else False,
|
|
704
|
+
kwargs=kwargs,
|
|
705
|
+
)
|
|
649
706
|
internal_assert(
|
|
650
|
-
|
|
707
|
+
not method.trim_arity
|
|
708
|
+
and hasattr(cls_method, "ignore_arguments") is hasattr(method, "ignore_arguments")
|
|
651
709
|
and hasattr(cls_method, "ignore_no_tokens") is hasattr(method, "ignore_no_tokens")
|
|
652
710
|
and hasattr(cls_method, "ignore_one_token") is hasattr(method, "ignore_one_token"),
|
|
653
711
|
"failed to properly wrap method",
|
|
654
712
|
method_name,
|
|
655
713
|
)
|
|
656
|
-
method.trim_arity = False
|
|
657
714
|
return method
|
|
658
715
|
|
|
716
|
+
@classmethod
|
|
717
|
+
def method_of(cls, method_name, is_action, kwargs):
|
|
718
|
+
"""Version of Compiler.method for use in pickling."""
|
|
719
|
+
return cls.method(method_name, is_action, **kwargs)
|
|
720
|
+
|
|
659
721
|
@classmethod
|
|
660
722
|
def bind(cls):
|
|
661
723
|
"""Binds reference objects to the proper parse actions."""
|
|
@@ -1310,7 +1372,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1310
1372
|
with self.inner_environment(ln=outer_ln):
|
|
1311
1373
|
self.streamline(parser, inputstring, inner=True)
|
|
1312
1374
|
pre_procd = self.pre(inputstring, **preargs)
|
|
1313
|
-
parsed =
|
|
1375
|
+
parsed = self.cached_parse("inner_parse_eval", parser, pre_procd)
|
|
1314
1376
|
return self.post(parsed, **postargs)
|
|
1315
1377
|
|
|
1316
1378
|
@contextmanager
|
|
@@ -1366,6 +1428,216 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1366
1428
|
for loc in info["referenced"]:
|
|
1367
1429
|
self.qa_error("found undefined name " + repr(self.reformat(name, ignore_errors=True)), original, loc)
|
|
1368
1430
|
|
|
1431
|
+
def pickle_cache(self, original, cache_path, include_incremental=True):
|
|
1432
|
+
"""Pickle the pyparsing cache for original to cache_path."""
|
|
1433
|
+
internal_assert(all_parse_elements is not None, "pickle_cache requires cPyparsing")
|
|
1434
|
+
if not save_new_cache_items:
|
|
1435
|
+
logger.log("Skipping saving cache items due to environment variable.")
|
|
1436
|
+
return
|
|
1437
|
+
|
|
1438
|
+
validation_dict = {} if cache_validation_info else None
|
|
1439
|
+
|
|
1440
|
+
# incremental cache
|
|
1441
|
+
pickleable_cache_items = []
|
|
1442
|
+
if ParserElement._incrementalEnabled and include_incremental:
|
|
1443
|
+
# note that exclude_stale is fine here because that means it was never used,
|
|
1444
|
+
# since _parseIncremental sets usefullness to True when a cache item is used
|
|
1445
|
+
for lookup, value in get_cache_items_for(original, only_useful=True):
|
|
1446
|
+
if incremental_mode_cache_size is not None and len(pickleable_cache_items) > incremental_mode_cache_size:
|
|
1447
|
+
logger.log(
|
|
1448
|
+
"Got too large incremental cache: "
|
|
1449
|
+
+ str(len(get_pyparsing_cache())) + " > " + str(incremental_mode_cache_size)
|
|
1450
|
+
)
|
|
1451
|
+
break
|
|
1452
|
+
if len(pickleable_cache_items) >= incremental_cache_limit:
|
|
1453
|
+
break
|
|
1454
|
+
loc = lookup[_lookup_loc]
|
|
1455
|
+
# only include cache items that aren't at the start or end, since those
|
|
1456
|
+
# are the only ones that parseIncremental will reuse
|
|
1457
|
+
if 0 < loc < len(original) - 1:
|
|
1458
|
+
elem = lookup[0]
|
|
1459
|
+
identifier = parse_elem_to_identifier(elem, validation_dict)
|
|
1460
|
+
pickleable_lookup = (identifier,) + lookup[1:]
|
|
1461
|
+
internal_assert(value[_value_exc_loc_or_ret] is True or isinstance(value[_value_exc_loc_or_ret], int), "cache must be dehybridized before pickling", value[_value_exc_loc_or_ret])
|
|
1462
|
+
pickleable_cache_items.append((pickleable_lookup, value))
|
|
1463
|
+
|
|
1464
|
+
# adaptive cache
|
|
1465
|
+
all_adaptive_items = []
|
|
1466
|
+
for wkref in MatchAny.all_match_anys:
|
|
1467
|
+
match_any = wkref()
|
|
1468
|
+
if match_any is not None and match_any.adaptive_usage is not None:
|
|
1469
|
+
identifier = parse_elem_to_identifier(match_any, validation_dict)
|
|
1470
|
+
match_any.expr_order.sort(key=lambda i: (-match_any.adaptive_usage[i], i))
|
|
1471
|
+
all_adaptive_items.append((identifier, (match_any.adaptive_usage, match_any.expr_order)))
|
|
1472
|
+
logger.log("Caching adaptive item:", match_any, (match_any.adaptive_usage, match_any.expr_order))
|
|
1473
|
+
|
|
1474
|
+
# computation graph cache
|
|
1475
|
+
computation_graph_cache_items = []
|
|
1476
|
+
for (call_site_name, grammar_elem), cache in self.computation_graph_caches.items():
|
|
1477
|
+
identifier = parse_elem_to_identifier(grammar_elem, validation_dict)
|
|
1478
|
+
computation_graph_cache_items.append(((call_site_name, identifier), cache))
|
|
1479
|
+
|
|
1480
|
+
logger.log("Saving {num_inc} incremental, {num_adapt} adaptive, and {num_comp_graph} computation graph cache items to {cache_path!r}.".format(
|
|
1481
|
+
num_inc=len(pickleable_cache_items),
|
|
1482
|
+
num_adapt=len(all_adaptive_items),
|
|
1483
|
+
num_comp_graph=sum(len(cache) for _, cache in computation_graph_cache_items) if computation_graph_cache_items else 0,
|
|
1484
|
+
cache_path=cache_path,
|
|
1485
|
+
))
|
|
1486
|
+
pickle_info_obj = {
|
|
1487
|
+
"VERSION": VERSION,
|
|
1488
|
+
"pyparsing_version": pyparsing_version,
|
|
1489
|
+
"validation_dict": validation_dict,
|
|
1490
|
+
"pickleable_cache_items": pickleable_cache_items,
|
|
1491
|
+
"all_adaptive_items": all_adaptive_items,
|
|
1492
|
+
"computation_graph_cache_items": computation_graph_cache_items,
|
|
1493
|
+
}
|
|
1494
|
+
try:
|
|
1495
|
+
with CombineToNode.enable_pickling(validation_dict):
|
|
1496
|
+
with univ_open(cache_path, "wb") as pickle_file:
|
|
1497
|
+
pickle.dump(pickle_info_obj, pickle_file, protocol=pickle.HIGHEST_PROTOCOL)
|
|
1498
|
+
except Exception:
|
|
1499
|
+
logger.log_exc()
|
|
1500
|
+
return False
|
|
1501
|
+
else:
|
|
1502
|
+
return True
|
|
1503
|
+
finally:
|
|
1504
|
+
# clear the packrat cache when we're done so we don't interfere with anything else happening in this process
|
|
1505
|
+
clear_packrat_cache(force=True)
|
|
1506
|
+
|
|
1507
|
+
def unpickle_cache(self, cache_path):
|
|
1508
|
+
"""Unpickle and load the given incremental cache file."""
|
|
1509
|
+
internal_assert(all_parse_elements is not None, "unpickle_cache requires cPyparsing")
|
|
1510
|
+
|
|
1511
|
+
if not os.path.exists(cache_path):
|
|
1512
|
+
return False
|
|
1513
|
+
try:
|
|
1514
|
+
with univ_open(cache_path, "rb") as pickle_file:
|
|
1515
|
+
pickle_info_obj = pickle.load(pickle_file)
|
|
1516
|
+
except Exception:
|
|
1517
|
+
logger.log_exc()
|
|
1518
|
+
return False
|
|
1519
|
+
if (
|
|
1520
|
+
pickle_info_obj["VERSION"] != VERSION
|
|
1521
|
+
or pickle_info_obj["pyparsing_version"] != pyparsing_version
|
|
1522
|
+
):
|
|
1523
|
+
return False
|
|
1524
|
+
|
|
1525
|
+
# unpack pickle_info_obj
|
|
1526
|
+
validation_dict = pickle_info_obj["validation_dict"]
|
|
1527
|
+
if ParserElement._incrementalEnabled:
|
|
1528
|
+
pickleable_cache_items = pickle_info_obj["pickleable_cache_items"]
|
|
1529
|
+
else:
|
|
1530
|
+
pickleable_cache_items = []
|
|
1531
|
+
all_adaptive_items = pickle_info_obj["all_adaptive_items"]
|
|
1532
|
+
computation_graph_cache_items = pickle_info_obj["computation_graph_cache_items"]
|
|
1533
|
+
|
|
1534
|
+
# incremental cache
|
|
1535
|
+
new_cache_items = []
|
|
1536
|
+
for pickleable_lookup, value in pickleable_cache_items:
|
|
1537
|
+
maybe_elem = identifier_to_parse_elem(pickleable_lookup[0], validation_dict)
|
|
1538
|
+
if maybe_elem is not None:
|
|
1539
|
+
internal_assert(value[_value_exc_loc_or_ret] is True or isinstance(value[_value_exc_loc_or_ret], int), "attempting to unpickle hybrid cache item", value[_value_exc_loc_or_ret])
|
|
1540
|
+
lookup = (maybe_elem,) + pickleable_lookup[1:]
|
|
1541
|
+
usefullness = value[-1][0]
|
|
1542
|
+
internal_assert(usefullness, "loaded useless cache item", (lookup, value))
|
|
1543
|
+
stale_value = value[:-1] + ([usefullness + 1],)
|
|
1544
|
+
new_cache_items.append((lookup, stale_value))
|
|
1545
|
+
add_packrat_cache_items(new_cache_items)
|
|
1546
|
+
|
|
1547
|
+
# adaptive cache
|
|
1548
|
+
for identifier, (adaptive_usage, expr_order) in all_adaptive_items:
|
|
1549
|
+
maybe_elem = identifier_to_parse_elem(identifier, validation_dict)
|
|
1550
|
+
if maybe_elem is not None:
|
|
1551
|
+
maybe_elem.adaptive_usage = adaptive_usage
|
|
1552
|
+
maybe_elem.expr_order = expr_order
|
|
1553
|
+
|
|
1554
|
+
max_cache_size = min(
|
|
1555
|
+
incremental_mode_cache_size or float("inf"),
|
|
1556
|
+
incremental_cache_limit or float("inf"),
|
|
1557
|
+
)
|
|
1558
|
+
if max_cache_size != float("inf"):
|
|
1559
|
+
pickleable_cache_items = pickleable_cache_items[-max_cache_size:]
|
|
1560
|
+
|
|
1561
|
+
# computation graph cache
|
|
1562
|
+
for (call_site_name, identifier), cache in computation_graph_cache_items:
|
|
1563
|
+
maybe_elem = identifier_to_parse_elem(identifier, validation_dict)
|
|
1564
|
+
if maybe_elem is not None:
|
|
1565
|
+
self.computation_graph_caches[(call_site_name, maybe_elem)].update(cache)
|
|
1566
|
+
|
|
1567
|
+
num_inc = len(pickleable_cache_items)
|
|
1568
|
+
num_adapt = len(all_adaptive_items)
|
|
1569
|
+
num_comp_graph = sum(len(cache) for _, cache in computation_graph_cache_items) if computation_graph_cache_items else 0
|
|
1570
|
+
return num_inc, num_adapt, num_comp_graph
|
|
1571
|
+
|
|
1572
|
+
def load_cache_for(self, inputstring, codepath):
|
|
1573
|
+
"""Load cache_path (for the given inputstring and filename)."""
|
|
1574
|
+
if not SUPPORTS_INCREMENTAL:
|
|
1575
|
+
raise CoconutException("the parsing cache requires cPyparsing (run '{python} -m pip install --upgrade cPyparsing' to fix)".format(python=sys.executable))
|
|
1576
|
+
filename = os.path.basename(codepath)
|
|
1577
|
+
|
|
1578
|
+
if len(inputstring) < disable_incremental_for_len:
|
|
1579
|
+
incremental_enabled = enable_incremental_parsing(reason="input length")
|
|
1580
|
+
if incremental_enabled:
|
|
1581
|
+
incremental_info = "incremental parsing mode enabled due to len == {input_len} < {max_len}".format(
|
|
1582
|
+
input_len=len(inputstring),
|
|
1583
|
+
max_len=disable_incremental_for_len,
|
|
1584
|
+
)
|
|
1585
|
+
else:
|
|
1586
|
+
incremental_info = "failed to enable incremental parsing mode"
|
|
1587
|
+
else:
|
|
1588
|
+
disable_incremental_parsing()
|
|
1589
|
+
incremental_enabled = False
|
|
1590
|
+
incremental_info = "not using incremental parsing mode due to len == {input_len} >= {max_len}".format(
|
|
1591
|
+
input_len=len(inputstring),
|
|
1592
|
+
max_len=disable_incremental_for_len,
|
|
1593
|
+
)
|
|
1594
|
+
|
|
1595
|
+
if (
|
|
1596
|
+
# only load the cache if we're using anything that makes use of it
|
|
1597
|
+
incremental_enabled
|
|
1598
|
+
or use_adaptive_any_of
|
|
1599
|
+
or use_line_by_line_parser
|
|
1600
|
+
):
|
|
1601
|
+
cache_path = get_cache_path(codepath)
|
|
1602
|
+
did_load_cache = self.unpickle_cache(cache_path)
|
|
1603
|
+
if did_load_cache:
|
|
1604
|
+
num_inc, num_adapt, num_comp_graph = did_load_cache
|
|
1605
|
+
logger.log("Loaded {num_inc} incremental, {num_adapt} adaptive, and {num_comp_graph} computation graph cache items for {filename!r} ({incremental_info}).".format(
|
|
1606
|
+
num_inc=num_inc,
|
|
1607
|
+
num_adapt=num_adapt,
|
|
1608
|
+
num_comp_graph=num_comp_graph,
|
|
1609
|
+
filename=filename,
|
|
1610
|
+
incremental_info=incremental_info,
|
|
1611
|
+
))
|
|
1612
|
+
else:
|
|
1613
|
+
logger.log("Failed to load cache for {filename!r} from {cache_path!r} ({incremental_info}).".format(
|
|
1614
|
+
filename=filename,
|
|
1615
|
+
cache_path=cache_path,
|
|
1616
|
+
incremental_info=incremental_info,
|
|
1617
|
+
))
|
|
1618
|
+
if incremental_enabled:
|
|
1619
|
+
logger.warn("Populating initial parsing cache (initial compilation may take a while; pass --no-cache to disable)...")
|
|
1620
|
+
else:
|
|
1621
|
+
cache_path = None
|
|
1622
|
+
logger.log("Declined to load cache for {filename!r} ({incremental_info}).".format(
|
|
1623
|
+
filename=filename,
|
|
1624
|
+
incremental_info=incremental_info,
|
|
1625
|
+
))
|
|
1626
|
+
|
|
1627
|
+
return cache_path, incremental_enabled
|
|
1628
|
+
|
|
1629
|
+
def cached_parse(self, call_site_name, parser, text, **kwargs):
|
|
1630
|
+
"""Call cached_parse using self.computation_graph_caches."""
|
|
1631
|
+
return cached_parse(self.computation_graph_caches[(call_site_name, parser)], parser, text, **kwargs)
|
|
1632
|
+
|
|
1633
|
+
def cached_try_parse(self, call_site_name, parser, text, **kwargs):
|
|
1634
|
+
"""Call cached_try_parse using self.computation_graph_caches."""
|
|
1635
|
+
return try_parse(parser, text, computation_graph_cache=self.computation_graph_caches[(call_site_name, parser)], **kwargs)
|
|
1636
|
+
|
|
1637
|
+
def cached_does_parse(self, call_site_name, parser, text, **kwargs):
|
|
1638
|
+
"""Call cached_does_parse using self.computation_graph_caches."""
|
|
1639
|
+
return does_parse(parser, text, computation_graph_cache=self.computation_graph_caches[(call_site_name, parser)], **kwargs)
|
|
1640
|
+
|
|
1369
1641
|
def parse_line_by_line(self, init_parser, line_parser, original):
|
|
1370
1642
|
"""Apply init_parser then line_parser repeatedly."""
|
|
1371
1643
|
if not USE_COMPUTATION_GRAPH:
|
|
@@ -1379,8 +1651,8 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1379
1651
|
self.remaining_original = original[cur_loc:]
|
|
1380
1652
|
ComputationNode.add_to_loc = cur_loc
|
|
1381
1653
|
parser = init_parser if init else line_parser
|
|
1382
|
-
results = cached_parse(
|
|
1383
|
-
|
|
1654
|
+
results = self.cached_parse(
|
|
1655
|
+
"parse_line_by_line",
|
|
1384
1656
|
parser,
|
|
1385
1657
|
self.remaining_original,
|
|
1386
1658
|
inner=False,
|
|
@@ -1417,7 +1689,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1417
1689
|
# unpickling must happen after streamlining and must occur in the
|
|
1418
1690
|
# compiler so that it happens in the same process as compilation
|
|
1419
1691
|
if use_cache:
|
|
1420
|
-
cache_path, incremental_enabled = load_cache_for(inputstring, codepath)
|
|
1692
|
+
cache_path, incremental_enabled = self.load_cache_for(inputstring, codepath)
|
|
1421
1693
|
else:
|
|
1422
1694
|
cache_path = None
|
|
1423
1695
|
pre_procd = parsed = None
|
|
@@ -1444,7 +1716,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1444
1716
|
)
|
|
1445
1717
|
finally:
|
|
1446
1718
|
if cache_path is not None and pre_procd is not None:
|
|
1447
|
-
pickle_cache(pre_procd, cache_path, include_incremental=incremental_enabled)
|
|
1719
|
+
self.pickle_cache(pre_procd, cache_path, include_incremental=incremental_enabled)
|
|
1448
1720
|
self.run_final_checks(pre_procd, keep_state)
|
|
1449
1721
|
return out
|
|
1450
1722
|
|
|
@@ -1540,7 +1812,7 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1540
1812
|
hold["exprs"][-1] += c
|
|
1541
1813
|
elif hold["paren_level"] > 0:
|
|
1542
1814
|
raise self.make_err(CoconutSyntaxError, "imbalanced parentheses in format string expression", inputstring, i, reformat=False)
|
|
1543
|
-
elif
|
|
1815
|
+
elif self.cached_does_parse("str_proc", self.end_f_str_expr, remaining_text):
|
|
1544
1816
|
hold["in_expr"] = False
|
|
1545
1817
|
hold["str_parts"].append(c)
|
|
1546
1818
|
else:
|
|
@@ -1733,9 +2005,9 @@ class Compiler(Grammar, pickleable_obj):
|
|
|
1733
2005
|
stripped_line = base_line.lstrip()
|
|
1734
2006
|
|
|
1735
2007
|
imp_from = None
|
|
1736
|
-
op =
|
|
2008
|
+
op = self.cached_try_parse("operator_proc", self.operator_stmt, stripped_line)
|
|
1737
2009
|
if op is None:
|
|
1738
|
-
op_imp_toks =
|
|
2010
|
+
op_imp_toks = self.cached_try_parse("operator_proc", self.from_import_operator, base_line)
|
|
1739
2011
|
if op_imp_toks is not None:
|
|
1740
2012
|
imp_from, op = op_imp_toks
|
|
1741
2013
|
if op is not None:
|
|
@@ -2367,7 +2639,7 @@ else:
|
|
|
2367
2639
|
# extract information about the function
|
|
2368
2640
|
with self.complain_on_err():
|
|
2369
2641
|
try:
|
|
2370
|
-
split_func_tokens =
|
|
2642
|
+
split_func_tokens = self.cached_parse("proc_funcdef", self.split_func, def_stmt)
|
|
2371
2643
|
|
|
2372
2644
|
self.internal_assert(len(split_func_tokens) == 2, original, loc, "invalid function definition splitting tokens", split_func_tokens)
|
|
2373
2645
|
func_name, func_arg_tokens = split_func_tokens
|
|
@@ -4394,7 +4666,7 @@ __annotations__["{name}"] = {annotation}
|
|
|
4394
4666
|
py_expr = self.inner_parse_eval(original, loc, co_expr)
|
|
4395
4667
|
except ParseBaseException:
|
|
4396
4668
|
raise CoconutDeferredSyntaxError("parsing failed for format string expression: " + co_expr, loc)
|
|
4397
|
-
if not
|
|
4669
|
+
if not self.cached_does_parse("f_string_handle", self.no_unquoted_newlines, py_expr):
|
|
4398
4670
|
raise CoconutDeferredSyntaxError("illegal complex expression in format string: " + co_expr, loc)
|
|
4399
4671
|
compiled_exprs.append(py_expr)
|
|
4400
4672
|
|
|
@@ -4652,9 +4924,9 @@ async with {iter_item} as {temp_var}:
|
|
|
4652
4924
|
def impl_call_handle(self, loc, tokens):
|
|
4653
4925
|
"""Process implicit function application or coefficient syntax."""
|
|
4654
4926
|
internal_assert(len(tokens) >= 2, "invalid implicit call / coefficient tokens", tokens)
|
|
4655
|
-
first_is_num =
|
|
4927
|
+
first_is_num = self.cached_does_parse("impl_call_handle", self.number, tokens[0])
|
|
4656
4928
|
if first_is_num:
|
|
4657
|
-
if
|
|
4929
|
+
if self.cached_does_parse("impl_call_handle", self.number, tokens[1]):
|
|
4658
4930
|
raise CoconutDeferredSyntaxError("multiplying two or more numeric literals with implicit coefficient syntax is prohibited", loc)
|
|
4659
4931
|
return "(" + " * ".join(tokens) + ")"
|
|
4660
4932
|
else:
|
|
@@ -4894,7 +5166,6 @@ class {protocol_var}({tokens}, _coconut.typing.Protocol): pass
|
|
|
4894
5166
|
|
|
4895
5167
|
where_assigns = self.current_parsing_context("where")["assigns"]
|
|
4896
5168
|
internal_assert(lambda: where_assigns is not None, "missing where_assigns")
|
|
4897
|
-
print(where_assigns)
|
|
4898
5169
|
|
|
4899
5170
|
where_init = "".join(body_stmts)
|
|
4900
5171
|
where_final = main_stmt + "\n"
|