solpython 0.1.1__py3-none-any.whl → 0.1.3__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.
pysol/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """solpython — Python-to-EVM compiler, runs Python on-chain."""
2
2
 
3
- __version__ = "0.1.1"
3
+ __version__ = "0.1.3"
pysol/cli/main.py CHANGED
@@ -16,6 +16,8 @@ def main():
16
16
  parser.add_argument("-v", "--verbose", action="store_true", help="Show compilation details")
17
17
  parser.add_argument("--version", action="store_true", help="Show version and exit")
18
18
  parser.add_argument("--build", action="store_true", help="Compile Solidity contracts and exit")
19
+ parser.add_argument("--backend", choices=["vm", "solidity", "yul"], default="vm",
20
+ help="Backend: vm (execute, default), solidity (transpile), yul (transpile)")
19
21
 
20
22
  args = parser.parse_args()
21
23
 
@@ -33,23 +35,28 @@ def main():
33
35
  source = args.command
34
36
  if not source.endswith("\n"):
35
37
  source += "\n"
36
- _execute(source, verbose=args.verbose)
38
+ _execute(source, verbose=args.verbose, backend=args.backend)
37
39
  return
38
40
 
39
41
  if args.script:
40
42
  if not os.path.exists(args.script):
41
43
  print(f"solpython: can't open file '{args.script}': No such file or directory")
42
44
  sys.exit(1)
43
- _execute_file(args.script, verbose=args.verbose)
45
+ _execute_file(args.script, verbose=args.verbose, backend=args.backend)
44
46
  return
45
47
 
46
48
  _repl(verbose=args.verbose)
47
49
 
48
50
 
49
- def _execute(source: str, *, verbose: bool = False):
50
- from pysol.executor import run
51
+ def _execute(source: str, *, verbose: bool = False, backend: str = "vm"):
52
+ from pysol.executor import run, compile_to_solidity, compile_to_yul
51
53
  try:
52
- output = run(source, verbose=verbose)
54
+ if backend == "solidity":
55
+ output = compile_to_solidity(source, verbose=verbose)
56
+ elif backend == "yul":
57
+ output = compile_to_yul(source, verbose=verbose)
58
+ else:
59
+ output = run(source, verbose=verbose)
53
60
  if output:
54
61
  print(output)
55
62
  except FileNotFoundError as e:
@@ -63,10 +70,17 @@ def _execute(source: str, *, verbose: bool = False):
63
70
  sys.exit(1)
64
71
 
65
72
 
66
- def _execute_file(path: str, *, verbose: bool = False):
67
- from pysol.executor import run_file
73
+ def _execute_file(path: str, *, verbose: bool = False, backend: str = "vm"):
74
+ from pysol.executor import run_file, compile_to_solidity, compile_to_yul
68
75
  try:
69
- output = run_file(path, verbose=verbose)
76
+ if backend in ("solidity", "yul"):
77
+ source = Path(path).read_text()
78
+ if backend == "solidity":
79
+ output = compile_to_solidity(source, verbose=verbose)
80
+ else:
81
+ output = compile_to_yul(source, verbose=verbose)
82
+ else:
83
+ output = run_file(path, verbose=verbose)
70
84
  if output:
71
85
  print(output)
72
86
  except FileNotFoundError as e:
pysol/executor.py CHANGED
@@ -111,23 +111,22 @@ def run(source: str, *, verbose: bool = False) -> str:
111
111
  return _decode_output(w3, receipt)
112
112
 
113
113
 
114
- def _resolve_imports(source: str, script_dir: Path) -> dict[str, str]:
115
- """Parse source for import statements and load module files from disk."""
114
+ def _resolve_imports(source: str, script_dir: Path, *, _seen: set[str] | None = None) -> dict[str, str]:
115
+ """Parse source for import statements and load module files from disk (recursive)."""
116
+ if _seen is None:
117
+ _seen = set()
116
118
  modules = {}
117
- for match in re.finditer(r"^from\s+(\w+)\s+import\s+", source, re.MULTILINE):
118
- mod_name = match.group(1)
119
- if mod_name in modules:
119
+ for match in re.finditer(r"^(?:from\s+(\w+)\s+import\s+|import\s+(\w+))", source, re.MULTILINE):
120
+ mod_name = match.group(1) or match.group(2)
121
+ if mod_name in _seen:
120
122
  continue
123
+ _seen.add(mod_name)
121
124
  mod_path = script_dir / f"{mod_name}.py"
122
125
  if mod_path.exists():
123
- modules[mod_name] = mod_path.read_text()
124
- for match in re.finditer(r"^import\s+(\w+)", source, re.MULTILINE):
125
- mod_name = match.group(1)
126
- if mod_name in modules:
127
- continue
128
- mod_path = script_dir / f"{mod_name}.py"
129
- if mod_path.exists():
130
- modules[mod_name] = mod_path.read_text()
126
+ mod_src = mod_path.read_text()
127
+ modules[mod_name] = mod_src
128
+ nested = _resolve_imports(mod_src, script_dir, _seen=_seen)
129
+ modules.update(nested)
131
130
  return modules
132
131
 
133
132
 
@@ -156,3 +155,19 @@ def run_with_imports(source: str, modules: dict[str, str], *, verbose: bool = Fa
156
155
  receipt = w3.eth.get_transaction_receipt(tx_hash)
157
156
 
158
157
  return _decode_output(w3, receipt)
158
+
159
+
160
+ def compile_to_solidity(source: str, *, verbose: bool = False) -> str:
161
+ """Compile Python source and return generated Solidity code."""
162
+ w3, compiler, vm, sender, gas = _setup_evm()
163
+ if verbose:
164
+ print(f"[solpython] Compiling {len(source)} chars of Python to Solidity...")
165
+ return compiler.functions.compileToSolidity(source).call({"from": sender, "gas": gas})
166
+
167
+
168
+ def compile_to_yul(source: str, *, verbose: bool = False) -> str:
169
+ """Compile Python source and return generated Yul code."""
170
+ w3, compiler, vm, sender, gas = _setup_evm()
171
+ if verbose:
172
+ print(f"[solpython] Compiling {len(source)} chars of Python to Yul...")
173
+ return compiler.functions.compileToYul(source).call({"from": sender, "gas": gas})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solpython
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Python-to-EVM compiler — run Python on-chain via a Solidity smart contract pipeline
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
@@ -0,0 +1,14 @@
1
+ pysol/__init__.py,sha256=VpZTa_WvsgxVpkMXhAGS5VzPi4cO5fR0ISH8rBbf7TI,89
2
+ pysol/build.py,sha256=HUF8iFaegQcCY0DP45xsoFUCEWqPqIaXb4YhwXABETk,4483
3
+ pysol/executor.py,sha256=oG4qnmgwCmOoxHHuJwLOfjMOCcW2AHIIYuSeAV9l5ZI,6260
4
+ pysol/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ pysol/cli/main.py,sha256=uWoMXvMc6skAHBQvZX51nXrqjWe6RWNbk4ps5JL5El8,4134
6
+ pysol/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ pysol/contracts/artifacts/PythonCompiler.json,sha256=01k6L0j8ZBWn2JG6CNdlRmhxpa-cHewJjY86-V3XfnU,437747
8
+ pysol/contracts/artifacts/VM.json,sha256=_qK4oc1KN2Zy0bhRMvrGorYhp2mHbKWGddqjQv4kSEE,91038
9
+ solpython-0.1.3.dist-info/licenses/LICENSE,sha256=GTNYUQJMKq5FV1co1N2BKUIxkAPPa2FCc8sLKO7x9FA,1065
10
+ solpython-0.1.3.dist-info/METADATA,sha256=g5iVZm_DZ9oKrtBOvpWhLEVN0iQ-j0yWkOWeeiIKW20,6497
11
+ solpython-0.1.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
12
+ solpython-0.1.3.dist-info/entry_points.txt,sha256=_s3EKcXf0MyFyfvA2r3llhjghAuMwS0PNRgFLxERppo,84
13
+ solpython-0.1.3.dist-info/top_level.txt,sha256=rM0iJ3CoB_QH43ATGuXjYgViiQkxBgtslv7tJqxUulM,6
14
+ solpython-0.1.3.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- pysol/__init__.py,sha256=CrThJr4pnScCO4lsl6ltTLk0JWxiQZ9ZRNb18AyhFmU,89
2
- pysol/build.py,sha256=HUF8iFaegQcCY0DP45xsoFUCEWqPqIaXb4YhwXABETk,4483
3
- pysol/executor.py,sha256=WaRZd3fOchFoACkn-e86RbcFUWpe0mw5zWLuxZ7LBTI,5517
4
- pysol/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- pysol/cli/main.py,sha256=ElB-LXK7Br0vtn84i-QhPNBDzAOLu_d9RBIWJxNCFlU,3280
6
- pysol/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- pysol/contracts/artifacts/PythonCompiler.json,sha256=01k6L0j8ZBWn2JG6CNdlRmhxpa-cHewJjY86-V3XfnU,437747
8
- pysol/contracts/artifacts/VM.json,sha256=_qK4oc1KN2Zy0bhRMvrGorYhp2mHbKWGddqjQv4kSEE,91038
9
- solpython-0.1.1.dist-info/licenses/LICENSE,sha256=GTNYUQJMKq5FV1co1N2BKUIxkAPPa2FCc8sLKO7x9FA,1065
10
- solpython-0.1.1.dist-info/METADATA,sha256=ggj-hf8P8w51exL1auqa656jxxylwE1idX-n2UpEqaA,6497
11
- solpython-0.1.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
12
- solpython-0.1.1.dist-info/entry_points.txt,sha256=_s3EKcXf0MyFyfvA2r3llhjghAuMwS0PNRgFLxERppo,84
13
- solpython-0.1.1.dist-info/top_level.txt,sha256=rM0iJ3CoB_QH43ATGuXjYgViiQkxBgtslv7tJqxUulM,6
14
- solpython-0.1.1.dist-info/RECORD,,