setta 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- setta/__init__.py +1 -1
- setta/cli/__init__.py +1 -0
- setta/cli/connect.py +43 -0
- setta/cli/logger.py +225 -0
- setta/code_gen/__init__.py +0 -0
- setta/code_gen/create_runnable_scripts.py +466 -0
- setta/code_gen/export_selected.py +776 -0
- setta/code_gen/find_placeholders.py +13 -0
- setta/code_gen/python/__init__.py +0 -0
- setta/code_gen/python/ast_utils.py +183 -0
- setta/code_gen/python/check_scope.py +187 -0
- setta/code_gen/python/generate_code.py +280 -0
- setta/code_gen/python/make_parseable.py +97 -0
- setta/code_gen/python/position_line_col.py +33 -0
- setta/code_gen/python/validate_imports.py +87 -0
- setta/code_gen/utils.py +120 -0
- setta/code_gen/yaml/__init__.py +0 -0
- setta/code_gen/yaml/generate_yaml.py +23 -0
- setta/code_gen/yaml/section_dict.py +93 -0
- setta/database/__init__.py +0 -0
- setta/database/backup.py +80 -0
- setta/database/db/__init__.py +0 -0
- setta/database/db/artifacts/__init__.py +0 -0
- setta/database/db/artifacts/load.py +93 -0
- setta/database/db/artifacts/save.py +85 -0
- setta/database/db/artifacts/save_or_create.py +68 -0
- setta/database/db/artifacts/utils.py +13 -0
- setta/database/db/codeInfo/__init__.py +0 -0
- setta/database/db/codeInfo/copy.py +26 -0
- setta/database/db/codeInfo/load.py +65 -0
- setta/database/db/codeInfo/save.py +75 -0
- setta/database/db/codeInfo/utils.py +33 -0
- setta/database/db/evRefs/__init__.py +0 -0
- setta/database/db/evRefs/load.py +45 -0
- setta/database/db/evRefs/save.py +95 -0
- setta/database/db/projects/__init__.py +0 -0
- setta/database/db/projects/copy.py +36 -0
- setta/database/db/projects/delete.py +7 -0
- setta/database/db/projects/load.py +184 -0
- setta/database/db/projects/save.py +267 -0
- setta/database/db/projects/saveAs.py +40 -0
- setta/database/db/projects/utils.py +135 -0
- setta/database/db/sectionVariants/__init__.py +0 -0
- setta/database/db/sectionVariants/copy.py +28 -0
- setta/database/db/sectionVariants/load.py +139 -0
- setta/database/db/sectionVariants/save.py +140 -0
- setta/database/db/sectionVariants/utils.py +44 -0
- setta/database/db/sections/__init__.py +0 -0
- setta/database/db/sections/copy.py +70 -0
- setta/database/db/sections/jsonSource.py +119 -0
- setta/database/db/sections/load.py +350 -0
- setta/database/db/sections/save.py +204 -0
- setta/database/db/sections/utils.py +13 -0
- setta/database/db/uiTypes/__init__.py +0 -0
- setta/database/db/uiTypes/copy.py +33 -0
- setta/database/db/uiTypes/load.py +51 -0
- setta/database/db/uiTypes/save.py +99 -0
- setta/database/db/uiTypes/utils.py +27 -0
- setta/database/db_init.py +36 -0
- setta/database/db_objs.py +102 -0
- setta/database/db_path.py +8 -0
- setta/database/export_db/__init__.py +0 -0
- setta/database/export_db/export_db.py +43 -0
- setta/database/export_db/export_raw.py +53 -0
- setta/database/export_db/export_readable.py +242 -0
- setta/database/export_db/utils.py +16 -0
- setta/database/import_db.py +28 -0
- setta/database/seed.py +41 -0
- setta/database/settings_file.py +118 -0
- setta/database/utils.py +32 -0
- setta/lsp/__init__.py +0 -0
- setta/lsp/file_watcher.py +113 -0
- setta/lsp/reader.py +184 -0
- setta/lsp/reader_fns/__init__.py +0 -0
- setta/lsp/reader_fns/completion.py +84 -0
- setta/lsp/reader_fns/definition.py +2 -0
- setta/lsp/reader_fns/diagnostics.py +99 -0
- setta/lsp/reader_fns/documentHighlight.py +25 -0
- setta/lsp/reader_fns/references.py +34 -0
- setta/lsp/reader_fns/signatureHelp.py +99 -0
- setta/lsp/server.py +150 -0
- setta/lsp/utils.py +60 -0
- setta/lsp/writer.py +306 -0
- setta/routers/__init__.py +11 -0
- setta/routers/artifact.py +105 -0
- setta/routers/code_info.py +32 -0
- setta/routers/dependencies.py +49 -0
- setta/routers/in_memory_fn_stdout_websocket.py +21 -0
- setta/routers/interactive.py +119 -0
- setta/routers/lsp.py +14 -0
- setta/routers/projects.py +188 -0
- setta/routers/reference_renaming.py +111 -0
- setta/routers/sections.py +174 -0
- setta/routers/settings.py +40 -0
- setta/routers/terminals.py +83 -0
- setta/routers/websocket.py +36 -0
- setta/server.py +141 -0
- setta/start.py +112 -0
- setta/static/constants/BaseUITypes.json +153 -0
- setta/static/constants/Settings.json +113 -0
- setta/static/constants/constants.json +117 -0
- setta/static/constants/db_init.sql +249 -0
- setta/static/constants/defaultValues.json +125 -0
- setta/static/constants/settingsProject.json +276 -0
- setta/static/frontend/android-chrome-192x192.png +0 -0
- setta/static/frontend/android-chrome-512x512.png +0 -0
- setta/static/frontend/apple-touch-icon.png +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-0cdd387c.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-30da91e8.woff +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-68534840.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-07d8e303.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-1ae6bd74.woff +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-de7701e4.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-3398dd02.woff +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-5d53e70a.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-ed0b7437.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-74444efd.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-9163df9c.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-9be7ceb8.woff +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-1e6f9579.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-51814d27.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-5e28753b.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-0f60d1b8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-138ac28d.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-c76c5d69.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-70ee1f64.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-99cd42a3.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-a6f7ec0d.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-0d85ae7c.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-97479ca6.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-f1d6ef86.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-c2342cd8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-c6368d87.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-d0332f52.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-850c0af5.woff +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-dc47344d.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-f9377ab0.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-08ce98e5.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-7af58c5e.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-8a8d2445.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-1ece03f7.ttf +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-e99ae511.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-ece03cfd.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-00b26ac8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-3931dd81.ttf +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-91ee6750.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-11e4dc8a.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-68e8c73e.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-f36ea897.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-036d4e95.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-1c67f068.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-d96cdf2b.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-6b47c401.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-95b6d2f1.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-c943cc98.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-2014c523.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-a6b2099f.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-d04c5421.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size3-Regular-500e04d5.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size3-Regular-6ab6b62e.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-99f9c675.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-a4af7d41.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-c647367d.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-71d517d6.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-e14fed02.woff +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-f01f3e87.ttf +0 -0
- setta/static/frontend/assets/cormorant-garamond-all-700-italic-c9b58582.woff +0 -0
- setta/static/frontend/assets/cormorant-garamond-cyrillic-700-italic-9101ad5f.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-cyrillic-ext-700-italic-950de0d6.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-latin-700-italic-0bc53e12.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-525738e0.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-99563037.woff2 +0 -0
- setta/static/frontend/assets/erase-5e0448ea.svg +15 -0
- setta/static/frontend/assets/index-1d4b4ecf.css +32 -0
- setta/static/frontend/assets/index-ee99dc72.js +678 -0
- setta/static/frontend/assets/inter-all-400-normal-054f12d0.woff +0 -0
- setta/static/frontend/assets/inter-all-600-normal-c03769e5.woff +0 -0
- setta/static/frontend/assets/inter-all-800-normal-15dc6e4b.woff +0 -0
- setta/static/frontend/assets/inter-cyrillic-400-normal-a4eee61a.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-600-normal-8b14f703.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-800-normal-e706eaaa.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-400-normal-70047a3b.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-600-normal-d4ab9bc4.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-800-normal-eae7515a.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-400-normal-381ea30d.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-600-normal-601f93a2.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-800-normal-7af4fb64.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-400-normal-27027b17.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-600-normal-f2ddf9de.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-800-normal-4cb6189e.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-400-normal-d56fec21.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-600-normal-ff769fa6.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-800-normal-5eea1309.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-400-normal-bb698d85.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-600-normal-ca4808f9.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-800-normal-ebdacc0f.woff2 +0 -0
- setta/static/frontend/assets/logo/logo.svg +8 -0
- setta/static/frontend/assets/pen-455d7d8a.svg +19 -0
- setta/static/frontend/assets/source-code-pro-all-500-normal-6bdaa03b.woff +0 -0
- setta/static/frontend/assets/source-code-pro-cyrillic-500-normal-288a0d68.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-cyrillic-ext-500-normal-b110a13b.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-greek-500-normal-04328acb.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-latin-500-normal-06edef1e.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-latin-ext-500-normal-6dc60d5e.woff2 +0 -0
- setta/static/frontend/assets/web-vitals-44a8e082.js +1 -0
- setta/static/frontend/assets/work-sans-all-400-normal-38034a3c.woff +0 -0
- setta/static/frontend/assets/work-sans-all-500-normal-550d64e5.woff +0 -0
- setta/static/frontend/assets/work-sans-all-600-normal-ccf14060.woff +0 -0
- setta/static/frontend/assets/work-sans-all-700-normal-494c2971.woff +0 -0
- setta/static/frontend/assets/work-sans-latin-400-normal-36735bc1.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-500-normal-3790bfda.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-600-normal-5fba494e.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-700-normal-a5033d0a.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-400-normal-c20f571a.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-500-normal-0f5ac96c.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-600-normal-97a237d1.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-700-normal-103e112c.woff2 +0 -0
- setta/static/frontend/browserconfig.xml +9 -0
- setta/static/frontend/favicon-16x16.png +0 -0
- setta/static/frontend/favicon-32x32.png +0 -0
- setta/static/frontend/favicon.ico +0 -0
- setta/static/frontend/index.html +30 -0
- setta/static/frontend/manifest.json +25 -0
- setta/static/frontend/mstile-144x144.png +0 -0
- setta/static/frontend/mstile-150x150.png +0 -0
- setta/static/frontend/mstile-310x150.png +0 -0
- setta/static/frontend/mstile-310x310.png +0 -0
- setta/static/frontend/mstile-70x70.png +0 -0
- setta/static/frontend/robots.txt +3 -0
- setta/static/frontend/safari-pinned-tab.svg +18 -0
- setta/static/frontend/site.webmanifest +19 -0
- setta/static/seed/.DS_Store +0 -0
- setta/static/seed/examples/.DS_Store +0 -0
- setta/tasks/__init__.py +0 -0
- setta/tasks/fns/__init__.py +9 -0
- setta/tasks/fns/codeAreaAutocomplete.py +209 -0
- setta/tasks/fns/codeAreaFindTemplateVars.py +128 -0
- setta/tasks/fns/codeAreaInitializeCode.py +98 -0
- setta/tasks/fns/findEVRefs.py +236 -0
- setta/tasks/fns/parametersRequest.py +71 -0
- setta/tasks/fns/textFieldAutocomplete.py +210 -0
- setta/tasks/fns/textFieldInitializeCode.py +99 -0
- setta/tasks/fns/typeCheck.py +40 -0
- setta/tasks/fns/utils.py +134 -0
- setta/tasks/task_runner.py +29 -0
- setta/tasks/tasks.py +152 -0
- setta/tasks/utils.py +178 -0
- setta/terminals/__init__.py +0 -0
- setta/terminals/terminals.py +242 -0
- setta/terminals/utils.py +37 -0
- setta/utils/__init__.py +0 -0
- setta/utils/constants.py +148 -0
- setta/utils/generate_memorable_string.py +431 -0
- setta/utils/generate_new_filename.py +80 -0
- setta/utils/section_contents.py +133 -0
- setta/utils/utils.py +271 -0
- setta/utils/websocket_manager.py +91 -0
- setta-0.0.2.dist-info/LICENSE +201 -0
- setta-0.0.2.dist-info/METADATA +24 -0
- setta-0.0.2.dist-info/RECORD +263 -0
- {setta-0.0.1.dist-info → setta-0.0.2.dist-info}/WHEEL +1 -1
- setta-0.0.2.dist-info/entry_points.txt +2 -0
- setta-0.0.1.dist-info/METADATA +0 -18
- setta-0.0.1.dist-info/RECORD +0 -5
- {setta-0.0.1.dist-info → setta-0.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
import json
|
2
|
+
|
3
|
+
from pydantic import BaseModel
|
4
|
+
|
5
|
+
from setta.code_gen.create_runnable_scripts import generate_final_code_for_sections
|
6
|
+
from setta.code_gen.export_selected import export_selected
|
7
|
+
from setta.code_gen.find_placeholders import tp
|
8
|
+
from setta.tasks.task_runner import RunType
|
9
|
+
from setta.utils.constants import C
|
10
|
+
|
11
|
+
from .utils import (
|
12
|
+
TaskDefinition,
|
13
|
+
send_document_open_request_with_diagnostics_with_code_dict,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
class TextFieldInitializeCodeContent(BaseModel):
|
18
|
+
project: dict
|
19
|
+
sectionId: str
|
20
|
+
paramInfoId: str | None
|
21
|
+
|
22
|
+
|
23
|
+
async def _textFieldInitializeCode(message, lsp_writers):
|
24
|
+
message = TextFieldInitializeCodeContent.parse_obj(message.content)
|
25
|
+
project = message.project
|
26
|
+
exporter_obj = export_selected(
|
27
|
+
project, always_export_args_objs=True, force_include_template_var=True
|
28
|
+
)
|
29
|
+
|
30
|
+
var_name = exporter_obj.var_name_mapping[
|
31
|
+
(message.sectionId, message.paramInfoId, False)
|
32
|
+
]
|
33
|
+
projectConfigName = project["projectConfig"]["name"]
|
34
|
+
code_dict = await generate_final_code_for_sections(
|
35
|
+
project,
|
36
|
+
exporter_obj,
|
37
|
+
lsp_writers=lsp_writers,
|
38
|
+
folder_path=lsp_writers["full"].project_code_folder(projectConfigName),
|
39
|
+
push_var_name=var_name,
|
40
|
+
)
|
41
|
+
send_document_open_request_with_diagnostics_with_code_dict(
|
42
|
+
lsp_writers["full"],
|
43
|
+
code_dict,
|
44
|
+
exporter_obj,
|
45
|
+
projectConfigName,
|
46
|
+
)
|
47
|
+
|
48
|
+
gen_code_section_details = exporter_obj.code_gen_template_var_section_details[
|
49
|
+
"section"
|
50
|
+
]
|
51
|
+
gen_code_dict = code_dict[gen_code_section_details["id"]]
|
52
|
+
var_name_to_decl_position = gen_code_dict["var_name_to_decl_rel_position_dict"][
|
53
|
+
tp(C.SETTA_GENERATED_PYTHON)
|
54
|
+
]
|
55
|
+
pushed_var_name_position = var_name_to_decl_position[var_name]
|
56
|
+
generated_var_names = list(var_name_to_decl_position.keys())
|
57
|
+
infoToFullName = {
|
58
|
+
tuple(json.loads(k)): v for k, v in project["infoToFullName"].items()
|
59
|
+
}
|
60
|
+
referencable_var_names = [
|
61
|
+
infoToFullName[exporter_obj.var_name_reverse_mapping[v]]
|
62
|
+
for v, (startPos, _, _) in var_name_to_decl_position.items()
|
63
|
+
if startPos < pushed_var_name_position[0]
|
64
|
+
]
|
65
|
+
|
66
|
+
return {
|
67
|
+
"cache": [
|
68
|
+
gen_code_dict,
|
69
|
+
var_name,
|
70
|
+
referencable_var_names,
|
71
|
+
generated_var_names,
|
72
|
+
exporter_obj,
|
73
|
+
project["fullNameToInfo"],
|
74
|
+
],
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
def get_cache_key(projectConfigId, sectionId, paramInfoId):
|
79
|
+
return f"textFieldInitializeCode-{projectConfigId}-{sectionId}-{paramInfoId}"
|
80
|
+
|
81
|
+
|
82
|
+
def write_cache(cache, message, result):
|
83
|
+
if result.get("cache") is None:
|
84
|
+
return
|
85
|
+
message = TextFieldInitializeCodeContent.parse_obj(message.content)
|
86
|
+
key = get_cache_key(
|
87
|
+
message.project["projectConfig"]["id"], message.sectionId, message.paramInfoId
|
88
|
+
)
|
89
|
+
cache[key] = result["cache"]
|
90
|
+
|
91
|
+
|
92
|
+
textFieldInitializeCode = TaskDefinition(
|
93
|
+
name="textFieldInitializeCode",
|
94
|
+
return_message_type="textFieldInitializeCodeReturn",
|
95
|
+
fn=_textFieldInitializeCode,
|
96
|
+
write_cache=write_cache,
|
97
|
+
run_as=RunType.NONE,
|
98
|
+
server_dependencies=["lsp_writers"],
|
99
|
+
)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from setta.code_gen.create_runnable_scripts import generate_final_code_for_sections
|
2
|
+
from setta.code_gen.export_selected import export_selected
|
3
|
+
from setta.tasks.task_runner import RunType
|
4
|
+
|
5
|
+
from .utils import (
|
6
|
+
TaskDefinition,
|
7
|
+
send_document_open_request_with_diagnostics_with_code_dict,
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
# this just initializes a document which gets the lsp to send back diagnostics
|
12
|
+
async def _typeCheck(message, lsp_writers):
|
13
|
+
project = message.content
|
14
|
+
exporter_obj = export_selected(
|
15
|
+
project, always_export_args_objs=False, force_include_template_var=True
|
16
|
+
)
|
17
|
+
projectConfigName = project["projectConfig"]["name"]
|
18
|
+
code_dict = await generate_final_code_for_sections(
|
19
|
+
project,
|
20
|
+
exporter_obj,
|
21
|
+
lsp_writers=lsp_writers,
|
22
|
+
folder_path=lsp_writers["full"].project_code_folder(projectConfigName),
|
23
|
+
)
|
24
|
+
send_document_open_request_with_diagnostics_with_code_dict(
|
25
|
+
lsp_writers["full"],
|
26
|
+
code_dict,
|
27
|
+
exporter_obj,
|
28
|
+
projectConfigName,
|
29
|
+
)
|
30
|
+
|
31
|
+
return None
|
32
|
+
|
33
|
+
|
34
|
+
typeCheck = TaskDefinition(
|
35
|
+
name="typeCheck",
|
36
|
+
return_message_type="typeCheckReturn",
|
37
|
+
fn=_typeCheck,
|
38
|
+
run_as=RunType.NONE,
|
39
|
+
server_dependencies=["lsp_writers"],
|
40
|
+
)
|
setta/tasks/fns/utils.py
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
import asyncio
|
2
|
+
import random
|
3
|
+
import string
|
4
|
+
from typing import Any, Callable, List, Optional
|
5
|
+
|
6
|
+
from pydantic import BaseModel
|
7
|
+
|
8
|
+
from setta.tasks.task_runner import RunType
|
9
|
+
from setta.utils.constants import C
|
10
|
+
from setta.utils.utils import multireplace
|
11
|
+
|
12
|
+
|
13
|
+
def send_document_open_request_with_diagnostics_with_code_dict(
|
14
|
+
lsp_writer,
|
15
|
+
code_dict,
|
16
|
+
exporter_obj,
|
17
|
+
projectConfigName,
|
18
|
+
):
|
19
|
+
for codeSectionId, details in code_dict.items():
|
20
|
+
if details["codeLanguage"] != "python":
|
21
|
+
continue
|
22
|
+
asyncio.create_task(
|
23
|
+
send_document_open_request_with_diagnostics(
|
24
|
+
lsp_writer,
|
25
|
+
details["code"],
|
26
|
+
exporter_obj,
|
27
|
+
details["ref_template_var_positions"],
|
28
|
+
projectConfigName,
|
29
|
+
details["sanitized_full_name"],
|
30
|
+
codeSectionId,
|
31
|
+
)
|
32
|
+
)
|
33
|
+
|
34
|
+
|
35
|
+
async def send_document_open_request_with_diagnostics(
|
36
|
+
lsp_writer,
|
37
|
+
code,
|
38
|
+
exporter_obj,
|
39
|
+
ref_template_var_positions,
|
40
|
+
projectConfigName,
|
41
|
+
sectionName,
|
42
|
+
codeSectionId,
|
43
|
+
):
|
44
|
+
code_id = lsp_writer.construct_code_id(
|
45
|
+
projectConfigName,
|
46
|
+
sectionName,
|
47
|
+
)
|
48
|
+
await lsp_writer.send_document_open_request(
|
49
|
+
code_id=code_id,
|
50
|
+
code=code,
|
51
|
+
codeJson=exporter_obj.output if exporter_obj else None,
|
52
|
+
ref_template_var_positions=ref_template_var_positions,
|
53
|
+
needsDiagnostics=True,
|
54
|
+
projectConfigId=exporter_obj.p["projectConfig"]["id"],
|
55
|
+
codeSectionId=codeSectionId,
|
56
|
+
)
|
57
|
+
|
58
|
+
return code_id
|
59
|
+
|
60
|
+
|
61
|
+
def prepare_code_for_scope_checking(fullText, templateVars, target_template_var):
|
62
|
+
the_special_var_name = None
|
63
|
+
for t in templateVars:
|
64
|
+
startPos = t["startPos"]
|
65
|
+
keyword = t["keyword"]
|
66
|
+
endPos = startPos + len(keyword)
|
67
|
+
if t is target_template_var:
|
68
|
+
# need to assign something to the replacement variable so that ast considers it a variable
|
69
|
+
decl = "=None"
|
70
|
+
# the [:-len(decl)] is to keep the full declaration the same length as the original keyword
|
71
|
+
the_special_var_name = generate_unique_variable(fullText, keyword)[
|
72
|
+
: -len(decl)
|
73
|
+
]
|
74
|
+
replacement = the_special_var_name + decl
|
75
|
+
else:
|
76
|
+
# variable assignment not necessary for the keywords that we don't care about
|
77
|
+
replacement = generate_unique_variable(fullText, keyword)
|
78
|
+
fullText = fullText[:startPos] + replacement + fullText[endPos:]
|
79
|
+
|
80
|
+
return fullText, the_special_var_name
|
81
|
+
|
82
|
+
|
83
|
+
# generate valid variable names because for example $SETTA_GENERATED_PYTHON is not valid
|
84
|
+
def replace_template_vars_with_random_names(candidateTemplateVars, fullText):
|
85
|
+
var_name_mapping = {}
|
86
|
+
reverse_var_name_mapping = {}
|
87
|
+
keyword_to_pos = {}
|
88
|
+
for keyword, pos in candidateTemplateVars:
|
89
|
+
new_keyword = generate_unique_variable(fullText, keyword)
|
90
|
+
var_name_mapping[keyword] = new_keyword
|
91
|
+
reverse_var_name_mapping[new_keyword] = keyword
|
92
|
+
# we only need 1 position of the keyword, even if there are multiple positions
|
93
|
+
keyword_to_pos[keyword] = pos
|
94
|
+
|
95
|
+
code = multireplace(fullText, var_name_mapping)
|
96
|
+
return code, list(keyword_to_pos.values()), reverse_var_name_mapping
|
97
|
+
|
98
|
+
|
99
|
+
def generate_unique_variable(code, keyword):
|
100
|
+
length = len(keyword)
|
101
|
+
chars = string.ascii_lowercase + string.digits + "_"
|
102
|
+
|
103
|
+
while True:
|
104
|
+
# Ensure the variable starts with a letter or underscore
|
105
|
+
new_var = random.choice(string.ascii_lowercase + "_")
|
106
|
+
# Fill the rest with random characters
|
107
|
+
new_var += "".join(random.choice(chars) for _ in range(length - 1))
|
108
|
+
|
109
|
+
if new_var.isidentifier() and new_var not in code:
|
110
|
+
return new_var
|
111
|
+
|
112
|
+
|
113
|
+
def do_nothing(*args, **kwargs):
|
114
|
+
pass
|
115
|
+
|
116
|
+
|
117
|
+
class TaskDefinition(BaseModel):
|
118
|
+
name: Optional[str] = ""
|
119
|
+
return_message_type: str
|
120
|
+
fn: Callable
|
121
|
+
read_cache: Optional[Callable] = do_nothing
|
122
|
+
write_cache: Optional[Callable] = do_nothing
|
123
|
+
run_as: Optional[RunType] = RunType.NONE
|
124
|
+
dependencies: Optional[List[str]] = None
|
125
|
+
server_dependencies: Optional[List[str]] = []
|
126
|
+
|
127
|
+
|
128
|
+
class TaskMessage(BaseModel):
|
129
|
+
id: str
|
130
|
+
content: Any
|
131
|
+
|
132
|
+
|
133
|
+
class SettaInMemoryFn(TaskDefinition):
|
134
|
+
return_message_type: str = C.WS_IN_MEMORY_FN_RETURN
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import asyncio
|
2
|
+
import inspect
|
3
|
+
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
|
4
|
+
from enum import Enum
|
5
|
+
|
6
|
+
|
7
|
+
class RunType(Enum):
|
8
|
+
SUBPROCESS = "SUBPROCESS"
|
9
|
+
THREAD = "THREAD"
|
10
|
+
NONE = "NONE"
|
11
|
+
|
12
|
+
|
13
|
+
class TaskRunner:
|
14
|
+
def __init__(self):
|
15
|
+
self.thread_executor = ThreadPoolExecutor(max_workers=2)
|
16
|
+
self.process_executor = ProcessPoolExecutor(max_workers=2)
|
17
|
+
|
18
|
+
async def run(self, fn, fn_args, run_as):
|
19
|
+
if inspect.iscoroutinefunction(fn):
|
20
|
+
return await fn(*fn_args)
|
21
|
+
|
22
|
+
if run_as == RunType.NONE:
|
23
|
+
return fn(*fn_args)
|
24
|
+
elif run_as == RunType.THREAD:
|
25
|
+
executor = self.thread_executor
|
26
|
+
elif run_as == RunType.SUBPROCESS:
|
27
|
+
executor = self.process_executor
|
28
|
+
|
29
|
+
return await asyncio.get_running_loop().run_in_executor(executor, fn, *fn_args)
|
setta/tasks/tasks.py
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
3
|
+
import queue
|
4
|
+
import threading
|
5
|
+
from typing import Dict
|
6
|
+
|
7
|
+
from setta.database.utils import create_new_id
|
8
|
+
|
9
|
+
from . import fns
|
10
|
+
from .fns.utils import TaskDefinition, TaskMessage
|
11
|
+
from .task_runner import RunType, TaskRunner
|
12
|
+
from .utils import SettaInMemoryFnSubprocess, add_fns_from_module
|
13
|
+
|
14
|
+
logger = logging.getLogger(__name__)
|
15
|
+
|
16
|
+
|
17
|
+
class Tasks:
|
18
|
+
def __init__(self, lsp_writers):
|
19
|
+
self.lsp_writers = lsp_writers
|
20
|
+
self.task_runner = TaskRunner()
|
21
|
+
self.cache = {}
|
22
|
+
self.fns: Dict[str, TaskDefinition] = {}
|
23
|
+
self.in_memory_subprocess = SettaInMemoryFnSubprocess()
|
24
|
+
self.websockets = [] # Store the websocket connections
|
25
|
+
add_fns_from_module(self.fns, fns)
|
26
|
+
|
27
|
+
# Start stdout listener thread
|
28
|
+
self._stop_event = asyncio.Event()
|
29
|
+
self.stdout_queue = queue.Queue() # regular Queue
|
30
|
+
self._stdout_processor_task = None
|
31
|
+
self.stdout_thread = threading.Thread(target=self._stdout_listener, daemon=True)
|
32
|
+
self.stdout_thread.start()
|
33
|
+
|
34
|
+
# Backend Changes (Tasks class)
|
35
|
+
async def connect(self, websocket):
|
36
|
+
# Accept the new connection
|
37
|
+
await websocket.accept()
|
38
|
+
self.websockets.append(websocket)
|
39
|
+
|
40
|
+
# Start the processor task if it's not running
|
41
|
+
if self._stdout_processor_task is None or self._stdout_processor_task.done():
|
42
|
+
self._stdout_processor_task = asyncio.create_task(
|
43
|
+
self._process_stdout_queue()
|
44
|
+
)
|
45
|
+
|
46
|
+
async def disconnect(self, websocket):
|
47
|
+
self.websockets.remove(websocket)
|
48
|
+
if len(self.websockets) == 0:
|
49
|
+
# Cancel the processor task
|
50
|
+
if self._stdout_processor_task and not self._stdout_processor_task.done():
|
51
|
+
self._stdout_processor_task.cancel()
|
52
|
+
try:
|
53
|
+
await self._stdout_processor_task
|
54
|
+
except asyncio.CancelledError:
|
55
|
+
pass
|
56
|
+
self._stdout_processor_task = None
|
57
|
+
|
58
|
+
def _stdout_listener(self):
|
59
|
+
while not self._stop_event.is_set():
|
60
|
+
try:
|
61
|
+
stdout_data = self.in_memory_subprocess.stdout_parent_conn.recv()
|
62
|
+
self.stdout_queue.put(stdout_data) # simple put, no async needed
|
63
|
+
except Exception as e:
|
64
|
+
if self._stop_event.is_set():
|
65
|
+
break
|
66
|
+
logger.debug(f"Error in stdout listener: {e}")
|
67
|
+
|
68
|
+
async def _process_stdout_queue(self):
|
69
|
+
while not self._stop_event.is_set():
|
70
|
+
try:
|
71
|
+
if self._stop_event.is_set():
|
72
|
+
break
|
73
|
+
if len(self.websockets) > 0:
|
74
|
+
stdout_data = self.stdout_queue.get_nowait()
|
75
|
+
stdout_data = stdout_data.replace("\n", "\r\n")
|
76
|
+
for w in self.websockets:
|
77
|
+
await w.send_text(stdout_data)
|
78
|
+
self.stdout_queue.task_done()
|
79
|
+
except queue.Empty:
|
80
|
+
await asyncio.sleep(0.1) # Check for connection every 100ms
|
81
|
+
except asyncio.CancelledError:
|
82
|
+
break
|
83
|
+
except Exception as e:
|
84
|
+
if self._stop_event.is_set():
|
85
|
+
break
|
86
|
+
logger.debug(f"Error processing stdout: {e}")
|
87
|
+
|
88
|
+
async def __call__(self, fn_name, message: TaskMessage):
|
89
|
+
if fn_name in self.fns:
|
90
|
+
return await self.call_regular_fn(fn_name, message)
|
91
|
+
return await self.call_in_memory_subprocess_fn(fn_name, message)
|
92
|
+
|
93
|
+
async def call_regular_fn(self, fn_name, message: TaskMessage):
|
94
|
+
fn = self.fns[fn_name]
|
95
|
+
fn.read_cache(self.cache, message)
|
96
|
+
fn_args = [message, *(getattr(self, k) for k in fn.server_dependencies)]
|
97
|
+
result = await self.task_runner.run(fn.fn, fn_args, fn.run_as)
|
98
|
+
fn.write_cache(self.cache, message, result)
|
99
|
+
if result is None:
|
100
|
+
result = {}
|
101
|
+
result["messageType"] = fn.return_message_type
|
102
|
+
return result
|
103
|
+
|
104
|
+
async def call_in_memory_subprocess_fn(self, fn_name, message: TaskMessage):
|
105
|
+
self.in_memory_subprocess.parent_conn.send(
|
106
|
+
{"type": "call", "fn_name": fn_name, "message": message}
|
107
|
+
)
|
108
|
+
result = await self.task_runner.run(
|
109
|
+
self.in_memory_subprocess.parent_conn.recv, [], RunType.THREAD
|
110
|
+
)
|
111
|
+
# if result["status"] == "success":
|
112
|
+
# for x in result["content"]:
|
113
|
+
# x.setdefault("sectionType", default_section_type(x["type"]))
|
114
|
+
if result["status"] != "success":
|
115
|
+
result["content"] = {}
|
116
|
+
|
117
|
+
return {"content": result["content"], "messageType": result["messageType"]}
|
118
|
+
|
119
|
+
async def add_custom_fns(self, code_list, to_cache):
|
120
|
+
error_msgs = {}
|
121
|
+
task_metadata = {}
|
122
|
+
initial_content = []
|
123
|
+
for c in code_list:
|
124
|
+
# Send import request to subprocess
|
125
|
+
self.in_memory_subprocess.parent_conn.send(
|
126
|
+
{
|
127
|
+
"type": "import",
|
128
|
+
"code": c["code"],
|
129
|
+
"module_name": c["module_name"],
|
130
|
+
"to_cache": to_cache,
|
131
|
+
}
|
132
|
+
)
|
133
|
+
result = await self.task_runner.run(
|
134
|
+
self.in_memory_subprocess.parent_conn.recv, [], RunType.THREAD
|
135
|
+
)
|
136
|
+
if result["status"] == "success":
|
137
|
+
task_metadata.update(result["content"])
|
138
|
+
else:
|
139
|
+
error_msgs[c["module_name"]] = result["error"]
|
140
|
+
|
141
|
+
for k in task_metadata.keys():
|
142
|
+
task_output = await self(k, TaskMessage(id=create_new_id(), content={}))
|
143
|
+
initial_content.extend(task_output["content"])
|
144
|
+
|
145
|
+
return task_metadata, error_msgs, initial_content
|
146
|
+
|
147
|
+
def close(self):
|
148
|
+
self._stop_event.set()
|
149
|
+
self.in_memory_subprocess.close()
|
150
|
+
self.stdout_thread.join()
|
151
|
+
if self._stdout_processor_task:
|
152
|
+
self._stdout_processor_task.cancel()
|
setta/tasks/utils.py
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
import importlib.util
|
2
|
+
import json
|
3
|
+
import multiprocessing
|
4
|
+
import os
|
5
|
+
import sys
|
6
|
+
import traceback
|
7
|
+
import uuid
|
8
|
+
|
9
|
+
from setta.tasks.fns.utils import TaskDefinition
|
10
|
+
from setta.utils.utils import nested_access
|
11
|
+
|
12
|
+
|
13
|
+
def import_code_from_string(code_string, module_name=None, add_to_sys_modules=True):
|
14
|
+
# Generate a unique module name if one isn't provided
|
15
|
+
if module_name is None:
|
16
|
+
module_name = f"setta_dynamic_module_{uuid.uuid4().hex}"
|
17
|
+
|
18
|
+
# Add current directory to sys.path if it's not already there
|
19
|
+
current_dir = os.getcwd()
|
20
|
+
if current_dir not in sys.path:
|
21
|
+
sys.path.insert(0, current_dir)
|
22
|
+
|
23
|
+
spec = importlib.util.spec_from_loader(module_name, loader=None)
|
24
|
+
|
25
|
+
# Create a new module based on the spec
|
26
|
+
module = importlib.util.module_from_spec(spec)
|
27
|
+
|
28
|
+
# Optionally add the module to sys.modules
|
29
|
+
if add_to_sys_modules:
|
30
|
+
print(f"adding {module_name} to sys.modules", flush=True)
|
31
|
+
sys.modules[module_name] = module
|
32
|
+
|
33
|
+
# Compile the code string
|
34
|
+
code_object = compile(code_string, module_name, "exec")
|
35
|
+
|
36
|
+
# Execute the compiled code object in the module's namespace
|
37
|
+
exec(code_object, module.__dict__)
|
38
|
+
|
39
|
+
return module
|
40
|
+
|
41
|
+
|
42
|
+
class SettaInMemoryFnSubprocess:
|
43
|
+
def __init__(self):
|
44
|
+
self.parent_conn, self.child_conn = multiprocessing.Pipe()
|
45
|
+
self.process = multiprocessing.Process(target=self._subprocess_main)
|
46
|
+
self.stdout_parent_conn, self.stdout_child_conn = multiprocessing.Pipe()
|
47
|
+
self.process.daemon = True # Ensure process dies with parent
|
48
|
+
self.process.start()
|
49
|
+
|
50
|
+
def _subprocess_main(self):
|
51
|
+
"""Main loop in subprocess that handles all requests"""
|
52
|
+
# Initialize store for imported modules
|
53
|
+
fns_dict = {}
|
54
|
+
cache = {}
|
55
|
+
|
56
|
+
class OutputCapture:
|
57
|
+
def __init__(self, stdout_pipe):
|
58
|
+
self.stdout_pipe = stdout_pipe
|
59
|
+
|
60
|
+
def write(self, text):
|
61
|
+
self.stdout_pipe.send(text)
|
62
|
+
|
63
|
+
def flush(self):
|
64
|
+
pass
|
65
|
+
|
66
|
+
# Redirect stdout as soon as subprocess starts
|
67
|
+
output_capture = OutputCapture(self.stdout_child_conn)
|
68
|
+
sys.stdout = output_capture
|
69
|
+
sys.stderr = output_capture
|
70
|
+
|
71
|
+
while True:
|
72
|
+
msg = self.child_conn.recv() # Wait for requests
|
73
|
+
msg_type = msg["type"]
|
74
|
+
return_message_type = None
|
75
|
+
|
76
|
+
if msg_type == "shutdown":
|
77
|
+
break
|
78
|
+
|
79
|
+
try:
|
80
|
+
if msg_type == "import":
|
81
|
+
code = msg["code"]
|
82
|
+
module_name = msg["module_name"]
|
83
|
+
# Import and store module
|
84
|
+
module = import_code_from_string(code, module_name)
|
85
|
+
added_fn_names = add_fns_from_module(fns_dict, module, module_name)
|
86
|
+
task_metadata = {}
|
87
|
+
for k in added_fn_names:
|
88
|
+
cache[k] = msg["to_cache"]
|
89
|
+
task_metadata[k] = get_task_metadata(fns_dict[k], cache[k])
|
90
|
+
|
91
|
+
self.child_conn.send(
|
92
|
+
{
|
93
|
+
"status": "success",
|
94
|
+
"content": task_metadata,
|
95
|
+
}
|
96
|
+
)
|
97
|
+
|
98
|
+
elif msg_type == "call":
|
99
|
+
fn_name = msg["fn_name"]
|
100
|
+
message = self.process_message(fn_name, msg["message"], cache)
|
101
|
+
fn = fns_dict[fn_name]
|
102
|
+
result = fn.fn(message)
|
103
|
+
return_message_type = fn.return_message_type
|
104
|
+
|
105
|
+
self.child_conn.send(
|
106
|
+
{
|
107
|
+
"status": "success",
|
108
|
+
"content": result,
|
109
|
+
"messageType": return_message_type,
|
110
|
+
}
|
111
|
+
)
|
112
|
+
|
113
|
+
except Exception as e:
|
114
|
+
traceback.print_exc()
|
115
|
+
self.child_conn.send(
|
116
|
+
{
|
117
|
+
"status": "error",
|
118
|
+
"error": str(e),
|
119
|
+
"messageType": return_message_type,
|
120
|
+
}
|
121
|
+
)
|
122
|
+
|
123
|
+
def close(self):
|
124
|
+
try:
|
125
|
+
self.parent_conn.send({"type": "shutdown"})
|
126
|
+
self.process.join(timeout=1.0)
|
127
|
+
except:
|
128
|
+
pass
|
129
|
+
|
130
|
+
if self.process.is_alive():
|
131
|
+
self.process.terminate()
|
132
|
+
self.process.join()
|
133
|
+
|
134
|
+
# Close both sets of connections
|
135
|
+
self.parent_conn.close()
|
136
|
+
self.child_conn.close()
|
137
|
+
self.stdout_parent_conn.close()
|
138
|
+
self.stdout_child_conn.close()
|
139
|
+
|
140
|
+
def process_message(self, fn_name, message, cache):
|
141
|
+
if fn_name in cache:
|
142
|
+
exporter_obj = cache[fn_name]
|
143
|
+
for k, v in message.content.items():
|
144
|
+
nice_str = exporter_obj.var_name_mapping[tuple(json.loads(k))]
|
145
|
+
p_dict, key = nested_access(exporter_obj.output, nice_str)
|
146
|
+
p_dict[key] = v
|
147
|
+
message.content = exporter_obj.output
|
148
|
+
return message.content
|
149
|
+
|
150
|
+
|
151
|
+
def add_fns_from_module(fns_dict, module, module_name=None):
|
152
|
+
count = 1
|
153
|
+
added_fn_names = []
|
154
|
+
for attr in vars(module).values():
|
155
|
+
if isinstance(attr, TaskDefinition):
|
156
|
+
if not attr.name:
|
157
|
+
if not module_name:
|
158
|
+
raise ValueError(
|
159
|
+
"Either TaskDefinition must be initialized with a name, or task_name must be specified"
|
160
|
+
)
|
161
|
+
attr.name = f"{module_name}-{count}"
|
162
|
+
count += 1
|
163
|
+
fns_dict[attr.name] = attr
|
164
|
+
added_fn_names.append(attr.name)
|
165
|
+
return added_fn_names
|
166
|
+
|
167
|
+
|
168
|
+
def get_task_metadata(in_memory_fn, exporter_obj):
|
169
|
+
# None means run the task on every change
|
170
|
+
if in_memory_fn.dependencies is None:
|
171
|
+
dependencies = None
|
172
|
+
# Empty array means only run when the task imported.
|
173
|
+
# Non-empty array means run when specified dependencies update.
|
174
|
+
else:
|
175
|
+
dependencies = [
|
176
|
+
exporter_obj.var_name_reverse_mapping[d] for d in in_memory_fn.dependencies
|
177
|
+
]
|
178
|
+
return {"dependencies": dependencies}
|
File without changes
|