jaclang 0.8.9__py3-none-any.whl → 0.8.10__py3-none-any.whl

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.

Potentially problematic release.


This version of jaclang might be problematic. Click here for more details.

Files changed (103) hide show
  1. jaclang/cli/cli.py +147 -25
  2. jaclang/cli/cmdreg.py +144 -8
  3. jaclang/compiler/__init__.py +6 -1
  4. jaclang/compiler/codeinfo.py +16 -1
  5. jaclang/compiler/constant.py +33 -13
  6. jaclang/compiler/jac.lark +130 -31
  7. jaclang/compiler/larkparse/jac_parser.py +2 -2
  8. jaclang/compiler/parser.py +567 -176
  9. jaclang/compiler/passes/__init__.py +2 -1
  10. jaclang/compiler/passes/ast_gen/__init__.py +5 -0
  11. jaclang/compiler/passes/ast_gen/base_ast_gen_pass.py +54 -0
  12. jaclang/compiler/passes/ast_gen/jsx_processor.py +344 -0
  13. jaclang/compiler/passes/ecmascript/__init__.py +25 -0
  14. jaclang/compiler/passes/ecmascript/es_unparse.py +576 -0
  15. jaclang/compiler/passes/ecmascript/esast_gen_pass.py +2068 -0
  16. jaclang/compiler/passes/ecmascript/estree.py +972 -0
  17. jaclang/compiler/passes/ecmascript/tests/__init__.py +1 -0
  18. jaclang/compiler/passes/ecmascript/tests/fixtures/advanced_language_features.jac +170 -0
  19. jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.impl.jac +30 -0
  20. jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.jac +14 -0
  21. jaclang/compiler/passes/ecmascript/tests/fixtures/client_jsx.jac +89 -0
  22. jaclang/compiler/passes/ecmascript/tests/fixtures/core_language_features.jac +195 -0
  23. jaclang/compiler/passes/ecmascript/tests/test_esast_gen_pass.py +167 -0
  24. jaclang/compiler/passes/ecmascript/tests/test_js_generation.py +239 -0
  25. jaclang/compiler/passes/main/__init__.py +0 -3
  26. jaclang/compiler/passes/main/annex_pass.py +23 -1
  27. jaclang/compiler/passes/main/pyast_gen_pass.py +324 -234
  28. jaclang/compiler/passes/main/pyast_load_pass.py +46 -11
  29. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +2 -0
  30. jaclang/compiler/passes/main/sym_tab_build_pass.py +18 -1
  31. jaclang/compiler/passes/main/tests/fixtures/autoimpl.cl.jac +7 -0
  32. jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +3 -0
  33. jaclang/compiler/passes/main/tests/fixtures/checker_class_construct.jac +33 -0
  34. jaclang/compiler/passes/main/tests/fixtures/defuse_modpath.jac +7 -0
  35. jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +2 -1
  36. jaclang/compiler/passes/main/tests/test_checker_pass.py +31 -2
  37. jaclang/compiler/passes/main/tests/test_def_use_pass.py +12 -0
  38. jaclang/compiler/passes/main/tests/test_import_pass.py +23 -4
  39. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +25 -0
  40. jaclang/compiler/passes/main/type_checker_pass.py +7 -0
  41. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +115 -0
  42. jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -10
  43. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -1
  44. jaclang/compiler/passes/transform.py +9 -1
  45. jaclang/compiler/passes/uni_pass.py +5 -7
  46. jaclang/compiler/program.py +22 -25
  47. jaclang/compiler/tests/test_client_codegen.py +113 -0
  48. jaclang/compiler/tests/test_importer.py +12 -10
  49. jaclang/compiler/tests/test_parser.py +249 -3
  50. jaclang/compiler/type_system/type_evaluator.jac +169 -50
  51. jaclang/compiler/type_system/type_utils.py +1 -1
  52. jaclang/compiler/type_system/types.py +6 -0
  53. jaclang/compiler/unitree.py +430 -84
  54. jaclang/langserve/engine.jac +224 -288
  55. jaclang/langserve/sem_manager.jac +12 -8
  56. jaclang/langserve/server.jac +48 -48
  57. jaclang/langserve/tests/fixtures/greet.py +17 -0
  58. jaclang/langserve/tests/fixtures/md_path.jac +22 -0
  59. jaclang/langserve/tests/fixtures/user.jac +15 -0
  60. jaclang/langserve/tests/test_server.py +66 -371
  61. jaclang/lib.py +1 -1
  62. jaclang/runtimelib/client_bundle.py +169 -0
  63. jaclang/runtimelib/client_runtime.jac +586 -0
  64. jaclang/runtimelib/constructs.py +2 -0
  65. jaclang/runtimelib/machine.py +259 -100
  66. jaclang/runtimelib/meta_importer.py +111 -22
  67. jaclang/runtimelib/mtp.py +15 -0
  68. jaclang/runtimelib/server.py +1089 -0
  69. jaclang/runtimelib/tests/fixtures/client_app.jac +18 -0
  70. jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
  71. jaclang/runtimelib/tests/fixtures/savable_object.jac +4 -5
  72. jaclang/runtimelib/tests/fixtures/serve_api.jac +75 -0
  73. jaclang/runtimelib/tests/test_client_bundle.py +55 -0
  74. jaclang/runtimelib/tests/test_client_render.py +63 -0
  75. jaclang/runtimelib/tests/test_serve.py +1069 -0
  76. jaclang/settings.py +0 -2
  77. jaclang/tests/fixtures/iife_functions.jac +142 -0
  78. jaclang/tests/fixtures/iife_functions_client.jac +143 -0
  79. jaclang/tests/fixtures/multistatement_lambda.jac +116 -0
  80. jaclang/tests/fixtures/multistatement_lambda_client.jac +113 -0
  81. jaclang/tests/fixtures/needs_import_dup.jac +6 -4
  82. jaclang/tests/fixtures/py_run.py +7 -5
  83. jaclang/tests/fixtures/pyfunc_fstr.py +2 -2
  84. jaclang/tests/fixtures/simple_lambda_test.jac +12 -0
  85. jaclang/tests/test_cli.py +1 -1
  86. jaclang/tests/test_language.py +10 -39
  87. jaclang/tests/test_reference.py +17 -2
  88. jaclang/utils/NonGPT.py +375 -0
  89. jaclang/utils/helpers.py +44 -16
  90. jaclang/utils/lang_tools.py +31 -4
  91. jaclang/utils/tests/test_lang_tools.py +1 -1
  92. jaclang/utils/treeprinter.py +8 -3
  93. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/METADATA +3 -3
  94. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/RECORD +96 -66
  95. jaclang/compiler/passes/main/binder_pass.py +0 -594
  96. jaclang/compiler/passes/main/tests/fixtures/sym_binder.jac +0 -47
  97. jaclang/compiler/passes/main/tests/test_binder_pass.py +0 -111
  98. jaclang/langserve/tests/session.jac +0 -294
  99. jaclang/langserve/tests/test_dev_server.py +0 -80
  100. jaclang/runtimelib/importer.py +0 -351
  101. jaclang/tests/test_typecheck.py +0 -542
  102. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/WHEEL +0 -0
  103. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/entry_points.txt +0 -0
@@ -1,17 +1,71 @@
1
- """Jac meta path importer."""
1
+ """Jac meta path importer.
2
+
3
+ This module implements PEP 451-compliant import hooks for .jac modules.
4
+ It leverages Python's modern import machinery (importlib.abc) to seamlessly
5
+ integrate Jac modules into Python's import system.
6
+ """
7
+
8
+ from __future__ import annotations
2
9
 
3
10
  import importlib.abc
4
11
  import importlib.machinery
5
12
  import importlib.util
6
13
  import os
14
+ import sys
7
15
  from types import ModuleType
8
16
  from typing import Optional, Sequence
9
17
 
10
18
  from jaclang.runtimelib.machine import JacMachine as Jac
11
19
  from jaclang.runtimelib.machine import JacMachineInterface
12
20
  from jaclang.settings import settings
21
+ from jaclang.utils.log import logging
13
22
  from jaclang.utils.module_resolver import get_jac_search_paths, get_py_search_paths
14
23
 
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ class _ByllmFallbackClass:
28
+ """A fallback class that can be instantiated and returns None for any attribute."""
29
+
30
+ def __init__(self, *args: object, **kwargs: object) -> None:
31
+ """Accept any arguments and store them."""
32
+ pass
33
+
34
+ def __getattr__(self, name: str) -> None:
35
+ """Return None for any attribute access."""
36
+ return None
37
+
38
+ def __call__(self, *args: object, **kwargs: object) -> _ByllmFallbackClass:
39
+ """Return self when called to allow chaining."""
40
+ # Return a new instance when called as a constructor
41
+ return _ByllmFallbackClass()
42
+
43
+
44
+ class ByllmFallbackLoader(importlib.abc.Loader):
45
+ """Fallback loader for byllm when it's not installed."""
46
+
47
+ def create_module(
48
+ self, spec: importlib.machinery.ModuleSpec
49
+ ) -> Optional[ModuleType]:
50
+ """Create a placeholder module."""
51
+ return None # use default machinery
52
+
53
+ def exec_module(self, module: ModuleType) -> None:
54
+ """Populate the module with fallback classes."""
55
+ # Set common attributes
56
+ module.__dict__["__all__"] = []
57
+ module.__file__ = None
58
+ module.__path__ = []
59
+
60
+ # Use a custom __getattr__ to return fallback classes for any attribute access
61
+ def _getattr(name: str) -> type[_ByllmFallbackClass]:
62
+ if not name.startswith("_"):
63
+ # Return a fallback class that can be instantiated
64
+ return _ByllmFallbackClass
65
+ raise AttributeError(f"module 'byllm' has no attribute '{name}'")
66
+
67
+ module.__getattr__ = _getattr # type: ignore
68
+
15
69
 
16
70
  class JacMetaImporter(importlib.abc.MetaPathFinder, importlib.abc.Loader):
17
71
  """Meta path importer to load .jac modules via Python's import system."""
@@ -23,6 +77,35 @@ class JacMetaImporter(importlib.abc.MetaPathFinder, importlib.abc.Loader):
23
77
  target: Optional[ModuleType] = None,
24
78
  ) -> Optional[importlib.machinery.ModuleSpec]:
25
79
  """Find the spec for the module."""
80
+ # Handle case where no byllm plugin is installed
81
+ if fullname == "byllm" or fullname.startswith("byllm."):
82
+ # Check if byllm is actually installed by looking for it in sys.path
83
+ # We use importlib.util.find_spec with a custom path to avoid recursion
84
+ byllm_found = False
85
+ for finder in sys.meta_path:
86
+ # Skip ourselves to avoid infinite recursion
87
+ if isinstance(finder, JacMetaImporter):
88
+ continue
89
+ if hasattr(finder, "find_spec"):
90
+ try:
91
+ spec = finder.find_spec(fullname, path, target)
92
+ if spec is not None:
93
+ byllm_found = True
94
+ break
95
+ except (ImportError, AttributeError):
96
+ continue
97
+
98
+ if not byllm_found:
99
+ # If byllm is not installed, return a spec for our fallback loader
100
+ print(
101
+ f"Please install a byllm plugin, but for now patching {fullname} with NonGPT"
102
+ )
103
+ return importlib.machinery.ModuleSpec(
104
+ fullname,
105
+ ByllmFallbackLoader(),
106
+ is_package=fullname == "byllm",
107
+ )
108
+
26
109
  if path is None:
27
110
  # Top-level import
28
111
  paths_to_search = get_jac_search_paths()
@@ -82,31 +165,37 @@ class JacMetaImporter(importlib.abc.MetaPathFinder, importlib.abc.Loader):
82
165
  return None # use default machinery
83
166
 
84
167
  def exec_module(self, module: ModuleType) -> None:
85
- """Execute the module."""
168
+ """Execute the module by loading and executing its bytecode.
169
+
170
+ This method implements PEP 451's exec_module() protocol, which separates
171
+ module creation from execution. It handles both package (__init__.jac) and
172
+ regular module (.jac/.py) execution.
173
+ """
86
174
  if not module.__spec__ or not module.__spec__.origin:
87
175
  raise ImportError(
88
176
  f"Cannot find spec or origin for module {module.__name__}"
89
177
  )
178
+
90
179
  file_path = module.__spec__.origin
91
180
  is_pkg = module.__spec__.submodule_search_locations is not None
92
181
 
93
- if is_pkg:
94
- codeobj = Jac.program.get_bytecode(full_target=file_path)
95
- if codeobj:
96
- exec(codeobj, module.__dict__)
97
- JacMachineInterface.load_module(module.__name__, module)
98
- return
99
-
100
- base_path = os.path.dirname(file_path)
101
- target = os.path.splitext(os.path.basename(file_path))[0]
102
- ret = JacMachineInterface.jac_import(
103
- target=target,
104
- base_path=base_path,
105
- override_name=module.__name__,
106
- lng="py" if file_path.endswith(".py") else "jac",
107
- )
108
- if ret:
109
- loaded_module = ret[0]
110
- module.__dict__.update(loaded_module.__dict__)
111
- else:
112
- raise ImportError(f"Unable to import {module.__name__}")
182
+ # Register module in JacMachine's tracking
183
+ JacMachineInterface.load_module(module.__name__, module)
184
+
185
+ # Get and execute bytecode
186
+ codeobj = Jac.program.get_bytecode(full_target=file_path)
187
+ if not codeobj:
188
+ if is_pkg:
189
+ # Empty package is OK - just register it
190
+ return
191
+ raise ImportError(f"No bytecode found for {file_path}")
192
+
193
+ try:
194
+ # Execute the bytecode directly in the module's namespace
195
+ exec(codeobj, module.__dict__)
196
+ except Exception as e:
197
+ logger.error(f"Error executing module {module.__name__}: {e}")
198
+ from jaclang.utils.helpers import dump_traceback
199
+
200
+ logger.error(dump_traceback(e))
201
+ raise
@@ -0,0 +1,15 @@
1
+ """Meaning Typed Programming constructs for Jac Language."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Callable
7
+
8
+
9
+ @dataclass(eq=False, repr=False)
10
+ class MTIR:
11
+ """Meaning Typed Intermediate Representation."""
12
+
13
+ caller: Callable
14
+ args: dict[int | str, object]
15
+ call_params: dict[str, object]