easypy-lang 2.0.2__tar.gz → 2.1.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vadik Goel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,17 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easypy-lang
3
- Version: 2.0.2
3
+ Version: 2.1.1
4
4
  Summary: A simple, powerful language for AI, ML, and apps - No coding experience needed!
5
5
  Home-page: https://github.com/VadikGoel/easypy-lang
6
6
  Author: Vadik Goel
7
7
  Author-email: vadikgoel1@gmail.com
8
+ License: MIT
8
9
  Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Intended Audience :: Education
12
12
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
13
13
  Requires-Python: >=3.9
14
14
  Description-Content-Type: text/markdown
15
+ License-File: LICENSE
15
16
  Requires-Dist: rich>=13.7.0
16
17
  Requires-Dist: requests>=2.28.0
17
18
  Requires-Dist: numpy>=1.21.0
@@ -27,6 +28,8 @@ Dynamic: classifier
27
28
  Dynamic: description
28
29
  Dynamic: description-content-type
29
30
  Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
30
33
  Dynamic: requires-dist
31
34
  Dynamic: requires-python
32
35
  Dynamic: summary
@@ -66,7 +69,21 @@ docker run -it vadikgoel/easypy-lang
66
69
  - **Python Compatible**: Runs on top of the robust Python ecosystem.
67
70
  - **Zero Configuration**: No complex build tools or compilers needed.
68
71
 
69
- ## 🚀 Quick Start
72
+ ## Modules (Batteries Included)
73
+
74
+ | Module | Purpose | Example |
75
+ |--------|---------|---------|
76
+ | `gui` | Desktop Apps | `gui.create_app("My App")` |
77
+ | `ml` | Machine Learning | `ml.model("classifier")` |
78
+ | `ai` | AI Helpers | `ai.ask("Hello")` |
79
+ | `db` | Database | `db.sqlite("my.db")` |
80
+ | `game` | 2D Games | `game.window()` |
81
+ | `web` | Internet | `web.get("https://google.com")` |
82
+ | `file` | File I/O | `file.write("test.txt", "Hi")` |
83
+ | `datetime`| Date & Time | `datetime.now()` |
84
+ | `discord` | Bots | `class MyBot(discord.Client)` |
85
+
86
+ ## �🚀 Quick Start
70
87
 
71
88
  Create a file named `hello.easy` and write your first program:
72
89
 
@@ -33,7 +33,21 @@ docker run -it vadikgoel/easypy-lang
33
33
  - **Python Compatible**: Runs on top of the robust Python ecosystem.
34
34
  - **Zero Configuration**: No complex build tools or compilers needed.
35
35
 
36
- ## 🚀 Quick Start
36
+ ## Modules (Batteries Included)
37
+
38
+ | Module | Purpose | Example |
39
+ |--------|---------|---------|
40
+ | `gui` | Desktop Apps | `gui.create_app("My App")` |
41
+ | `ml` | Machine Learning | `ml.model("classifier")` |
42
+ | `ai` | AI Helpers | `ai.ask("Hello")` |
43
+ | `db` | Database | `db.sqlite("my.db")` |
44
+ | `game` | 2D Games | `game.window()` |
45
+ | `web` | Internet | `web.get("https://google.com")` |
46
+ | `file` | File I/O | `file.write("test.txt", "Hi")` |
47
+ | `datetime`| Date & Time | `datetime.now()` |
48
+ | `discord` | Bots | `class MyBot(discord.Client)` |
49
+
50
+ ## �🚀 Quick Start
37
51
 
38
52
  Create a file named `hello.easy` and write your first program:
39
53
 
@@ -0,0 +1,263 @@
1
+ """
2
+ Easypy Real Modules
3
+ Implementations that perform ACTUAL system actions
4
+ """
5
+
6
+ import sys
7
+ import os
8
+ import time
9
+ import json
10
+ import threading
11
+
12
+ # Global Aliases for Easypy -> Python compatibility
13
+ true = True
14
+ false = False
15
+ null = None
16
+
17
+ # Built-in String Helpers
18
+ def upper(s): return str(s).upper()
19
+ def lower(s): return str(s).lower()
20
+
21
+ # ==================== GUI (Tkinter) ====================
22
+ class _GUIImpl:
23
+ def __init__(self):
24
+ self.tk = None
25
+ self.windows = []
26
+
27
+ def create_app(self, title, width=800, height=600):
28
+ try:
29
+ import tkinter as tk
30
+ except ImportError:
31
+ print("❌ Error: 'tkinter' not found. This is usually built-in to Python.")
32
+ return None
33
+
34
+ root = tk.Tk()
35
+ root.title(title)
36
+ root.geometry(f"{width}x{height}")
37
+ self.windows.append(root)
38
+ return root
39
+
40
+ def button(self, parent, label, on_click=None):
41
+ import tkinter as tk
42
+ def handler():
43
+ if on_click:
44
+ if callable(on_click):
45
+ on_click()
46
+ else:
47
+ print(f"Button '{label}' clicked (No valid function passed)")
48
+ btn = tk.Button(parent, text=label, command=handler)
49
+ btn.pack(pady=5)
50
+ return btn
51
+
52
+ def label(self, parent, text):
53
+ import tkinter as tk
54
+ lbl = tk.Label(parent, text=text)
55
+ lbl.pack(pady=5)
56
+ return lbl
57
+
58
+ def textbox(self, parent, placeholder=""):
59
+ import tkinter as tk
60
+ entry = tk.Entry(parent)
61
+ entry.insert(0, placeholder)
62
+ entry.pack(pady=5)
63
+ return entry
64
+
65
+ def show(self, app):
66
+ print(f"🖥️ Opening Window: {app.title()}")
67
+ app.mainloop()
68
+
69
+ gui = _GUIImpl()
70
+
71
+
72
+ # ==================== SYSTEM ====================
73
+ class _FileImpl:
74
+ def create(self, path, content=""):
75
+ self.write(path, content)
76
+
77
+ def write(self, path, content=""):
78
+ with open(path, "w", encoding='utf-8') as f:
79
+ f.write(str(content))
80
+ print(f"✓ File written: {path}")
81
+
82
+ def append(self, path, content=""):
83
+ with open(path, "a", encoding='utf-8') as f:
84
+ f.write(str(content))
85
+ print(f"✓ File appended: {path}")
86
+
87
+ def read(self, path):
88
+ if not os.path.exists(path):
89
+ print(f"❌ Error: File not found '{path}'")
90
+ return ""
91
+ with open(path, "r", encoding='utf-8') as f:
92
+ return f.read()
93
+
94
+ file = _FileImpl()
95
+
96
+ # ==================== WEB ====================
97
+ class _WebImpl:
98
+ def open(self, url):
99
+ import webbrowser
100
+ webbrowser.open(url)
101
+ print(f"✓ Opened browser: {url}")
102
+
103
+ def get(self, url):
104
+ try:
105
+ import requests
106
+ return requests.get(url).text
107
+ except ImportError:
108
+ print("❌ Error: 'requests' module missing. Run: pip install requests")
109
+ return None
110
+
111
+ web = _WebImpl()
112
+
113
+ # ==================== DISCORD (Simplified Sync Wrapper) ====================
114
+ # Note: Real discord requires async. We will do a blocking runner for simplicity in v1 transpiler.
115
+ class _DiscordImpl:
116
+ def create(self, token):
117
+ print("Disclaimer: Real Discord bots require an Event Loop.")
118
+ print("To run a real bot, we would generate an async Python script.")
119
+ print(f"✓ Stored token: {token[:5]}...")
120
+ return {"token": token}
121
+
122
+ discord_bot = _DiscordImpl()
123
+
124
+ # ==================== ML (Machine Learning - Sklearn Wrapper) ====================
125
+ class _MLImpl:
126
+ def model(self, type="classifier"):
127
+ try:
128
+ from sklearn.neighbors import KNeighborsClassifier
129
+ from sklearn.linear_model import LinearRegression
130
+
131
+ if type == "classifier":
132
+ print("🔹 Created KNN Classifier")
133
+ return _SimpleModel(KNeighborsClassifier(n_neighbors=3))
134
+ elif type == "regression":
135
+ print("🔹 Created Linear Regression Model")
136
+ return _SimpleModel(LinearRegression())
137
+ except ImportError:
138
+ print("❌ Error: 'scikit-learn' not installed.")
139
+ return None
140
+
141
+ class _SimpleModel:
142
+ def __init__(self, internal):
143
+ self.model = internal
144
+ self.trained = False
145
+
146
+ def train(self, inputs, outputs):
147
+ try:
148
+ self.model.fit(inputs, outputs)
149
+ self.trained = True
150
+ print("✅ Model trained!")
151
+ except Exception as e:
152
+ print(f"❌ Training Failed: {e}")
153
+
154
+ def predict(self, input_data):
155
+ if not self.trained:
156
+ print("⚠️ Model not trained yet!")
157
+ return None
158
+ return self.model.predict([input_data])[0]
159
+
160
+ ml = _MLImpl()
161
+
162
+ # ==================== AI (Simple NLP/Chat) ====================
163
+ class _AIImpl:
164
+ def ask(self, prompt):
165
+ # Placeholder for actual LLM or API
166
+ responses = {
167
+ "hello": "Hello there! How can I help?",
168
+ "easypy": "Easypy is the easiest language ever!",
169
+ "time": f"The time is {time.strftime('%H:%M')}"
170
+ }
171
+ for k, v in responses.items():
172
+ if k in prompt.lower():
173
+ return v
174
+ return f"User asked: '{prompt}' (AI Backend not connected)"
175
+
176
+ ai = _AIImpl()
177
+
178
+ # ==================== GAME (Turtle Graphics) ====================
179
+ class _GameImpl:
180
+ def window(self, width=600, height=600, title="Easypy Game"):
181
+ import turtle
182
+ s = turtle.Screen()
183
+ s.setup(width, height)
184
+ s.title(title)
185
+ s.bgcolor("black")
186
+ return s
187
+
188
+ def player(self, shape="turtle", color="lime"):
189
+ import turtle
190
+ p = turtle.Turtle()
191
+ p.shape(shape)
192
+ p.color(color)
193
+ p.speed(0)
194
+ return p
195
+
196
+ game = _GameImpl()
197
+
198
+ # Helper for implicit 'ml_classifier' in examples often seen
199
+ def ml_classifier(): return ml.model("classifier")
200
+
201
+ # ==================== DATA (Database & Storage) ====================
202
+ class _DBImpl:
203
+ def sqlite(self, path="database.db"):
204
+ import sqlite3
205
+ try:
206
+ conn = sqlite3.connect(path)
207
+ print(f"✓ Connected to SQLite: {path}")
208
+ return _SQLiteConn(conn)
209
+ except Exception as e:
210
+ print(f"❌ Connection Failed: {e}")
211
+ return None
212
+
213
+ def save_json(self, path, data):
214
+ try:
215
+ with open(path, 'w') as f:
216
+ json.dump(data, f, indent=4)
217
+ print(f"✓ Data saved to {path}")
218
+ except Exception as e:
219
+ print(f"❌ Save JSON Failed: {e}")
220
+
221
+ def load_json(self, path):
222
+ try:
223
+ if not os.path.exists(path):
224
+ return {}
225
+ with open(path, 'r') as f:
226
+ return json.load(f)
227
+ except Exception as e:
228
+ print(f"❌ Load JSON Failed: {e}")
229
+ return None
230
+
231
+ class _SQLiteConn:
232
+ def __init__(self, conn):
233
+ self.conn = conn
234
+ self.cursor = conn.cursor()
235
+
236
+ def execute(self, query, params=()):
237
+ try:
238
+ self.cursor.execute(query, params)
239
+ self.conn.commit()
240
+ return self.cursor.fetchall()
241
+ except Exception as e:
242
+ print(f"❌ SQL Error: {e}")
243
+ return []
244
+
245
+ def close(self):
246
+ self.conn.close()
247
+
248
+ db = _DBImpl()
249
+
250
+ # ==================== DATE & TIME ====================
251
+ class _DateImpl:
252
+ def now(self):
253
+ return time.strftime("%Y-%m-%d %H:%M:%S")
254
+
255
+ def today(self):
256
+ return time.strftime("%Y-%m-%d")
257
+
258
+ def timestamp(self):
259
+ return time.time()
260
+
261
+ datetime = _DateImpl()
262
+
263
+
@@ -157,17 +157,32 @@ class EasypyTranspiler:
157
157
 
158
158
  def _clean_expression(self, text):
159
159
  """Helper to convert C-style syntax to Python"""
160
+ # Protect strings from replacement
161
+ # placeholders mapping: string_content -> placeholder
162
+ placeholders = {}
163
+ def replace_str(match):
164
+ key = f"__STR_{len(placeholders)}__"
165
+ placeholders[key] = match.group(0)
166
+ return key
167
+
168
+ # Temporarily replace strings with placeholders
169
+ # Regex for double and single quotes
170
+ text_safe = re.sub(r'("[^"]*"|\'[^\']*\')', replace_str, text)
171
+
160
172
  # Operators
161
- text = text.replace("===", "==")
162
- text = text.replace("&&", " and ")
163
- text = text.replace("||", " or ")
173
+ text_safe = text_safe.replace("===", "==")
174
+ text_safe = text_safe.replace("&&", " and ")
175
+ text_safe = text_safe.replace("||", " or ")
164
176
 
165
177
  # '!' but not '!='
166
178
  # Only replace if preceded by start-of-line, space, '(', '[', or '='
167
- # This prevents replacing '!' inside strings like "Hello!"
168
- text = re.sub(r'(?:^|(?<=[=\s(\[]))!(?!=)', 'not ', text)
179
+ text_safe = re.sub(r'(?:^|(?<=[=\s(\[]))!(?!=)', 'not ', text_safe)
180
+
181
+ # Restore strings
182
+ for key, val in placeholders.items():
183
+ text_safe = text_safe.replace(key, val)
169
184
 
170
- # 'true'/'false'/'null' are handled by modules_real.py aliases at runtime,
185
+ return text_safe
171
186
  # but replacing them here can be safer for some edge cases.
172
187
  # But let's stick to the aliases to avoid accidental string replacement.
173
188
 
@@ -255,7 +270,7 @@ class EasypyTranspiler:
255
270
  if len(parts) >= 2:
256
271
  mod = parts[1]
257
272
  # These are actually pre-loaded objects in modules_real.py
258
- preloaded_objects = ["gui", "file", "web", "system", "discord_bot", "api"]
273
+ preloaded_objects = ["gui", "file", "web", "system", "discord_bot", "api", "ml", "ai", "game", "db", "datetime"]
259
274
 
260
275
  if mod in preloaded_objects:
261
276
  return f"{indent}# Module '{mod}' is pre-loaded"
@@ -305,6 +320,18 @@ class EasypyTranspiler:
305
320
  # 3b. Async Functions
306
321
  if raw_line.startswith("async func ") and raw_line.endswith("{"):
307
322
  defn = raw_line[11:-1].strip()
323
+
324
+ # Auto-inject 'self' if inside a class
325
+ if self.context_stack and self.context_stack[-1] == 'class':
326
+ parts = defn.split("(", 1)
327
+ name = parts[0]
328
+ args = parts[1][:-1] if len(parts) > 1 else ""
329
+
330
+ if args.strip():
331
+ defn = f"{name}(self, {args})"
332
+ else:
333
+ defn = f"{name}(self)"
334
+
308
335
  self.indent_level += 1
309
336
  self.context_stack.append('func')
310
337
  return f"{indent}async def {defn}:"
@@ -369,11 +396,18 @@ class EasypyTranspiler:
369
396
  # If it is an assignment (x = {), keep the brace, do strict Python dict open.
370
397
  # Regex checks for "var =" or "word =" pattern at end of line
371
398
  # But NOT "if x == {" (comparison)
372
- # Simple heuristic: If it has "=" and not " if " or " while ", it's likely data.
399
+
400
+ # Also check for nested dictionary structure: "key": {
401
+ is_dict_entry = bool(re.search(r'[\w"\']+\s*:\s*$', clean_line)) # Ends with colon
402
+
373
403
  is_assignment = re.search(r'[^=!<>]=[^=]', clean_line) or clean_line.endswith("=")
374
404
 
405
+ # Check if current context is 'dict' (nested)
406
+ in_dict_context = self.context_stack and self.context_stack[-1] == 'dict'
407
+
375
408
  self.indent_level += 1
376
- if is_assignment:
409
+
410
+ if is_assignment or (in_dict_context and is_dict_entry):
377
411
  # It's a dict! Keep the brace.
378
412
  self.context_stack.append('dict')
379
413
  return f"{indent}{clean_line} {{"
@@ -1,17 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easypy-lang
3
- Version: 2.0.2
3
+ Version: 2.1.1
4
4
  Summary: A simple, powerful language for AI, ML, and apps - No coding experience needed!
5
5
  Home-page: https://github.com/VadikGoel/easypy-lang
6
6
  Author: Vadik Goel
7
7
  Author-email: vadikgoel1@gmail.com
8
+ License: MIT
8
9
  Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Intended Audience :: Education
12
12
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
13
13
  Requires-Python: >=3.9
14
14
  Description-Content-Type: text/markdown
15
+ License-File: LICENSE
15
16
  Requires-Dist: rich>=13.7.0
16
17
  Requires-Dist: requests>=2.28.0
17
18
  Requires-Dist: numpy>=1.21.0
@@ -27,6 +28,8 @@ Dynamic: classifier
27
28
  Dynamic: description
28
29
  Dynamic: description-content-type
29
30
  Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
30
33
  Dynamic: requires-dist
31
34
  Dynamic: requires-python
32
35
  Dynamic: summary
@@ -66,7 +69,21 @@ docker run -it vadikgoel/easypy-lang
66
69
  - **Python Compatible**: Runs on top of the robust Python ecosystem.
67
70
  - **Zero Configuration**: No complex build tools or compilers needed.
68
71
 
69
- ## 🚀 Quick Start
72
+ ## Modules (Batteries Included)
73
+
74
+ | Module | Purpose | Example |
75
+ |--------|---------|---------|
76
+ | `gui` | Desktop Apps | `gui.create_app("My App")` |
77
+ | `ml` | Machine Learning | `ml.model("classifier")` |
78
+ | `ai` | AI Helpers | `ai.ask("Hello")` |
79
+ | `db` | Database | `db.sqlite("my.db")` |
80
+ | `game` | 2D Games | `game.window()` |
81
+ | `web` | Internet | `web.get("https://google.com")` |
82
+ | `file` | File I/O | `file.write("test.txt", "Hi")` |
83
+ | `datetime`| Date & Time | `datetime.now()` |
84
+ | `discord` | Bots | `class MyBot(discord.Client)` |
85
+
86
+ ## �🚀 Quick Start
70
87
 
71
88
  Create a file named `hello.easy` and write your first program:
72
89
 
@@ -1,3 +1,4 @@
1
+ LICENSE
1
2
  README.md
2
3
  setup.py
3
4
  easypy_lang/__init__.py
@@ -5,17 +5,17 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="easypy-lang",
8
- version="2.0.2",
8
+ version="2.1.1",
9
9
  author="Vadik Goel",
10
10
  author_email="vadikgoel1@gmail.com",
11
11
  description="A simple, powerful language for AI, ML, and apps - No coding experience needed!",
12
12
  long_description=long_description,
13
13
  long_description_content_type="text/markdown",
14
+ license="MIT",
14
15
  url="https://github.com/VadikGoel/easypy-lang",
15
16
  packages=find_packages(),
16
17
  classifiers=[
17
18
  "Programming Language :: Python :: 3",
18
- "License :: OSI Approved :: MIT License",
19
19
  "Operating System :: OS Independent",
20
20
  "Intended Audience :: Education",
21
21
  "Topic :: Software Development :: Libraries :: Application Frameworks",
@@ -1,122 +0,0 @@
1
- """
2
- Easypy Real Modules
3
- Implementations that perform ACTUAL system actions
4
- """
5
-
6
- import sys
7
- import os
8
- import time
9
- import json
10
- import threading
11
-
12
- # Global Aliases for Easypy -> Python compatibility
13
- true = True
14
- false = False
15
- null = None
16
-
17
- # Built-in String Helpers
18
- def upper(s): return str(s).upper()
19
- def lower(s): return str(s).lower()
20
-
21
- # ==================== GUI (Tkinter) ====================
22
- class _GUIImpl:
23
- def __init__(self):
24
- self.tk = None
25
- self.windows = []
26
-
27
- def create_app(self, title, width=800, height=600):
28
- try:
29
- import tkinter as tk
30
- except ImportError:
31
- print("❌ Error: 'tkinter' not found. This is usually built-in to Python.")
32
- return None
33
-
34
- root = tk.Tk()
35
- root.title(title)
36
- root.geometry(f"{width}x{height}")
37
- self.windows.append(root)
38
- return root
39
-
40
- def button(self, parent, label, on_click=None):
41
- import tkinter as tk
42
- def handler():
43
- if on_click:
44
- if callable(on_click):
45
- on_click()
46
- else:
47
- print(f"Button '{label}' clicked (No valid function passed)")
48
- btn = tk.Button(parent, text=label, command=handler)
49
- btn.pack(pady=5)
50
- return btn
51
-
52
- def label(self, parent, text):
53
- import tkinter as tk
54
- lbl = tk.Label(parent, text=text)
55
- lbl.pack(pady=5)
56
- return lbl
57
-
58
- def textbox(self, parent, placeholder=""):
59
- import tkinter as tk
60
- entry = tk.Entry(parent)
61
- entry.insert(0, placeholder)
62
- entry.pack(pady=5)
63
- return entry
64
-
65
- def show(self, app):
66
- print(f"🖥️ Opening Window: {app.title()}")
67
- app.mainloop()
68
-
69
- gui = _GUIImpl()
70
-
71
-
72
- # ==================== SYSTEM ====================
73
- class _FileImpl:
74
- def create(self, path, content=""):
75
- self.write(path, content)
76
-
77
- def write(self, path, content=""):
78
- with open(path, "w", encoding='utf-8') as f:
79
- f.write(str(content))
80
- print(f"✓ File written: {path}")
81
-
82
- def append(self, path, content=""):
83
- with open(path, "a", encoding='utf-8') as f:
84
- f.write(str(content))
85
- print(f"✓ File appended: {path}")
86
-
87
- def read(self, path):
88
- if not os.path.exists(path):
89
- print(f"❌ Error: File not found '{path}'")
90
- return ""
91
- with open(path, "r", encoding='utf-8') as f:
92
- return f.read()
93
-
94
- file = _FileImpl()
95
-
96
- # ==================== WEB ====================
97
- class _WebImpl:
98
- def open(self, url):
99
- import webbrowser
100
- webbrowser.open(url)
101
- print(f"✓ Opened browser: {url}")
102
-
103
- def get(self, url):
104
- try:
105
- import requests
106
- return requests.get(url).text
107
- except ImportError:
108
- print("❌ Error: 'requests' module missing. Run: pip install requests")
109
- return None
110
-
111
- web = _WebImpl()
112
-
113
- # ==================== DISCORD (Simplified Sync Wrapper) ====================
114
- # Note: Real discord requires async. We will do a blocking runner for simplicity in v1 transpiler.
115
- class _DiscordImpl:
116
- def create(self, token):
117
- print("Disclaimer: Real Discord bots require an Event Loop.")
118
- print("To run a real bot, we would generate an async Python script.")
119
- print(f"✓ Stored token: {token[:5]}...")
120
- return {"token": token}
121
-
122
- discord_bot = _DiscordImpl()
File without changes