shell-lite 0.3.5__py3-none-any.whl → 0.4.1__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.
shell_lite/parser.py CHANGED
@@ -32,6 +32,8 @@ class Parser:
32
32
  def parse_statement(self) -> Node:
33
33
  if self.check('USE'):
34
34
  return self.parse_import()
35
+ elif self.check('APP'):
36
+ return self.parse_app()
35
37
  elif self.check('ON'):
36
38
  return self.parse_on()
37
39
  elif self.check('CONST'):
@@ -301,12 +303,25 @@ class Parser:
301
303
  node.line = token.line
302
304
  return node
303
305
  def parse_make(self) -> Node:
306
+ node = self.parse_make_expr()
307
+ self.consume('NEWLINE')
308
+ return node
309
+
310
+ def parse_make_expr(self) -> Make:
304
311
  token = self.consume('MAKE')
305
312
  class_name = self.consume('ID').value
306
313
  args = []
307
- while not self.check('NEWLINE') and not self.check('EOF'):
308
- args.append(self.parse_expression())
309
- self.consume('NEWLINE')
314
+ if self.check('LPAREN'):
315
+ self.consume('LPAREN')
316
+ if not self.check('RPAREN'):
317
+ args.append(self.parse_expression())
318
+ while self.check('COMMA'):
319
+ self.consume('COMMA')
320
+ args.append(self.parse_expression())
321
+ self.consume('RPAREN')
322
+ else:
323
+ while not self.check('NEWLINE') and not self.check('EOF'):
324
+ args.append(self.parse_expression())
310
325
  node = Make(class_name, args)
311
326
  node.line = token.line
312
327
  return node
@@ -501,7 +516,10 @@ class Parser:
501
516
  start_token = self.consume('STRUCTURE')
502
517
  name = self.consume('ID').value
503
518
  parent = None
504
- if self.check('LPAREN'):
519
+ if self.check('EXTENDS'):
520
+ self.consume('EXTENDS')
521
+ parent = self.consume('ID').value
522
+ elif self.check('LPAREN'):
505
523
  self.consume('LPAREN')
506
524
  parent = self.consume('ID').value
507
525
  self.consume('RPAREN')
@@ -512,10 +530,29 @@ class Parser:
512
530
  while not self.check('DEDENT') and not self.check('EOF'):
513
531
  if self.check('HAS'):
514
532
  self.consume()
515
- properties.append(self.consume('ID').value)
533
+ prop_name = None
534
+ if self.check('MAKE'):
535
+ prop_name = self.consume().value
536
+ else:
537
+ prop_name = self.consume('ID').value
538
+
539
+ default_val = None
540
+ if self.check('ASSIGN'):
541
+ self.consume('ASSIGN')
542
+ default_val = self.parse_expression()
543
+
544
+ properties.append((prop_name, default_val))
516
545
  self.consume('NEWLINE')
517
546
  elif self.check('TO'):
518
547
  methods.append(self.parse_function_def())
548
+ elif self.check('ID'):
549
+ prop_name = self.consume('ID').value
550
+ default_val = None
551
+ if self.check('ASSIGN'):
552
+ self.consume('ASSIGN')
553
+ default_val = self.parse_expression()
554
+ properties.append((prop_name, default_val))
555
+ self.consume('NEWLINE')
519
556
  elif self.check('NEWLINE'):
520
557
  self.consume()
521
558
  else:
@@ -597,6 +634,22 @@ class Parser:
597
634
  node = Assign(name, value)
598
635
  node.line = token_is.line
599
636
  return node
637
+ elif self.check('LBRACKET'):
638
+ self.consume('LBRACKET')
639
+ index = self.parse_expression()
640
+ self.consume('RBRACKET')
641
+ self.consume('ASSIGN')
642
+ val = self.parse_expression()
643
+ self.consume('NEWLINE')
644
+ # Convert simple assignment to PropertyAssign-like or specific set call?
645
+ # interpreter.visit_IndexAccess handles get.
646
+ # We need a node for IndexAssign. parser snippet doesn't show one.
647
+ # But visit_PropertyAssign handles dict keys.
648
+ # Let's map d[k] = v to PropertyAssign(d, k, v)?
649
+ # No, PropertyAssign takes member name as string. Here index handles expressions.
650
+ # I need to check if there is a node for this.
651
+ # If not, I'll return Call('set', [VarAccess(name), index, val])
652
+ return Call('set', [VarAccess(name), index, val])
600
653
  elif self.check('DOT'):
601
654
  self.consume('DOT')
602
655
  member_token = self.consume()
@@ -606,13 +659,40 @@ class Parser:
606
659
  value = self.parse_expression()
607
660
  self.consume('NEWLINE')
608
661
  return PropertyAssign(name, member, value)
662
+
609
663
  args = []
664
+ if self.check('LPAREN'):
665
+ self.consume('LPAREN')
666
+ if not self.check('RPAREN'):
667
+ args.append(self.parse_expression())
668
+ while self.check('COMMA'):
669
+ self.consume('COMMA')
670
+ args.append(self.parse_expression())
671
+ self.consume('RPAREN')
672
+ self.consume('NEWLINE')
673
+ node = MethodCall(name, member, args)
674
+ node.line = name_token.line
675
+ return node
676
+
610
677
  while not self.check('NEWLINE') and not self.check('EOF'):
611
678
  args.append(self.parse_expression())
612
679
  self.consume('NEWLINE')
613
680
  node = MethodCall(name, member, args)
614
681
  node.line = name_token.line
615
682
  return node
683
+ elif self.check('LPAREN'):
684
+ self.consume('LPAREN')
685
+ args = []
686
+ if not self.check('RPAREN'):
687
+ args.append(self.parse_expression())
688
+ while self.check('COMMA'):
689
+ self.consume('COMMA')
690
+ args.append(self.parse_expression())
691
+ self.consume('RPAREN')
692
+ self.consume('NEWLINE')
693
+ node = Call(name, args)
694
+ node.line = name_token.line
695
+ return node
616
696
  else:
617
697
  if not self.check('NEWLINE') and not self.check('EOF') and not self.check('EQ') and not self.check('IS'):
618
698
  args = []
@@ -855,7 +935,27 @@ class Parser:
855
935
  return Assign(name, value)
856
936
  def parse_import(self) -> Node:
857
937
  token = self.consume('USE')
858
- path = self.consume('STRING').value
938
+
939
+ # Check for Python Import: use python "numpy" as np
940
+ if self.check('ID') and self.peek().value == 'python':
941
+ self.consume('ID') # consume 'python'
942
+ if self.check('STRING'):
943
+ module_name = self.consume('STRING').value
944
+ alias = None
945
+ if self.check('AS'):
946
+ self.consume('AS')
947
+ alias = self.consume('ID').value
948
+ self.consume('NEWLINE')
949
+ node = PythonImport(module_name, alias)
950
+ node.line = token.line
951
+ return node
952
+ else:
953
+ raise SyntaxError(f"Expected module name string after 'use python' at line {token.line}")
954
+
955
+ if self.check('STRING'):
956
+ path = self.consume('STRING').value
957
+ else:
958
+ path = self.consume('ID').value
859
959
  if self.check('AS'):
860
960
  self.consume('AS')
861
961
  alias = self.consume('ID').value
@@ -1082,6 +1182,70 @@ class Parser:
1082
1182
  node = Dictionary(pairs)
1083
1183
  node.line = token.line
1084
1184
  return node
1185
+ def parse_app(self) -> Node:
1186
+ token = self.consume('APP')
1187
+ title = self.consume('STRING').value
1188
+
1189
+ width = 500
1190
+ height = 400
1191
+ if self.check('SIZE'):
1192
+ self.consume('SIZE')
1193
+ width = int(self.consume('NUMBER').value)
1194
+ height = int(self.consume('NUMBER').value)
1195
+
1196
+ self.consume('COLON')
1197
+ self.consume('NEWLINE')
1198
+ self.consume('INDENT')
1199
+
1200
+ body = []
1201
+ while not self.check('DEDENT'):
1202
+ body.append(self.parse_ui_block())
1203
+ if self.check('NEWLINE'):
1204
+ self.consume('NEWLINE')
1205
+
1206
+ self.consume('DEDENT')
1207
+ return App(title, width, height, body)
1208
+
1209
+ def parse_ui_block(self) -> Node:
1210
+ token = self.peek()
1211
+
1212
+ if token.type in ('COLUMN', 'ROW'):
1213
+ layout_type = self.consume().value # column or row
1214
+ self.consume('COLON')
1215
+ self.consume('NEWLINE')
1216
+ self.consume('INDENT')
1217
+ children = []
1218
+ while not self.check('DEDENT'):
1219
+ children.append(self.parse_ui_block())
1220
+ if self.check('NEWLINE'): self.consume('NEWLINE')
1221
+ self.consume('DEDENT')
1222
+ return Layout(layout_type, children)
1223
+
1224
+ elif token.type in ('BUTTON', 'INPUT', 'HEADING', 'TEXT'):
1225
+ widget_type = self.consume().value
1226
+ label = self.consume('STRING').value
1227
+
1228
+ var_name = None
1229
+ if self.check('AS'):
1230
+ self.consume('AS')
1231
+ var_name = self.consume('ID').value
1232
+
1233
+ event_handler = None
1234
+ if token.type == 'BUTTON' and self.check('DO'):
1235
+ self.consume('DO')
1236
+ self.consume('COLON')
1237
+ self.consume('NEWLINE')
1238
+ self.consume('INDENT')
1239
+ event_handler = []
1240
+ while not self.check('DEDENT'):
1241
+ event_handler.append(self.parse_statement())
1242
+ self.consume('DEDENT')
1243
+
1244
+ return Widget(widget_type, label, var_name, event_handler)
1245
+
1246
+ else:
1247
+ raise SyntaxError(f"Unexpected token in UI block: {token.type} at line {token.line}")
1248
+
1085
1249
  def parse_factor_simple(self) -> Node:
1086
1250
  token = self.peek()
1087
1251
  if token.type == 'NUMBER':
@@ -1178,12 +1342,23 @@ class Parser:
1178
1342
  raise SyntaxError(f"Unexpected argument token {token.type} at line {token.line}")
1179
1343
  def parse_factor(self) -> Node:
1180
1344
  token = self.peek()
1181
- if token.type == 'NOT':
1345
+ if token.type == 'MINUS':
1182
1346
  op = self.consume()
1183
- right = self.parse_factor()
1184
- node = UnaryOp(op.value, right)
1347
+ right = self.parse_factor()
1348
+ node = UnaryOp('-', right)
1185
1349
  node.line = op.line
1186
1350
  return node
1351
+ elif token.type == 'NOT':
1352
+ op = self.consume()
1353
+ right = self.parse_factor()
1354
+ node = UnaryOp('not', right)
1355
+ node.line = op.line
1356
+ return node
1357
+ elif token.type == 'LPAREN':
1358
+ self.consume('LPAREN')
1359
+ node = self.parse_expression()
1360
+ self.consume('RPAREN')
1361
+ return node
1187
1362
  elif token.type == 'DB':
1188
1363
  return self.parse_db_op()
1189
1364
  elif token.type == 'SPAWN':
@@ -1263,10 +1438,7 @@ class Parser:
1263
1438
  node.line = token.line
1264
1439
  return node
1265
1440
  elif token.type == 'STRING':
1266
- self.consume()
1267
- node = String(token.value)
1268
- node.line = token.line
1269
- return node
1441
+ return self.parse_factor_simple()
1270
1442
  elif token.type == 'YES':
1271
1443
  self.consume()
1272
1444
  node = Boolean(True)
@@ -1293,30 +1465,60 @@ class Parser:
1293
1465
  if self.check('DOT'):
1294
1466
  self.consume('DOT')
1295
1467
  method_name = self.consume().value
1468
+
1296
1469
  args = []
1470
+ # Check for C-style function call: func(arg1, arg2)
1471
+ if self.check('LPAREN'):
1472
+ self.consume('LPAREN')
1473
+ if not self.check('RPAREN'):
1474
+ args.append(self.parse_expression())
1475
+ while self.check('COMMA'):
1476
+ self.consume('COMMA')
1477
+ args.append(self.parse_expression())
1478
+ self.consume('RPAREN')
1479
+ if method_name:
1480
+ node = MethodCall(instance_name, method_name, args)
1481
+ else:
1482
+ node = Call(instance_name, args)
1483
+ node.line = token.line
1484
+ return node
1485
+
1486
+ # Fallback to command-style arguments: func arg1 arg2
1487
+ # But only if NOT a property access (method_name w/o args is property access,
1488
+ # but if it was method call it would use parens ideally, or spaces?)
1489
+ # Existing logic supported 'func arg1 arg2'.
1490
+ # We keep it for backward compatibility e.g. 'echo 123'.
1491
+
1297
1492
  force_call = False
1298
1493
  while True:
1299
1494
  next_t = self.peek()
1300
- if next_t.type == 'LPAREN' and self.peek(1).type == 'RPAREN':
1301
- self.consume('LPAREN')
1302
- self.consume('RPAREN')
1303
- force_call = True
1304
- continue
1305
- if next_t.type in ('NUMBER', 'STRING', 'REGEX', 'ID', 'LPAREN', 'INPUT', 'ASK', 'YES', 'NO', 'LBRACKET', 'LBRACE'):
1306
- args.append(self.parse_factor_simple())
1307
- else:
1495
+ # If we see LPAREN now, it's ambiguous if we didn't handle it above.
1496
+ # But 'func (1)' is func called with 1 arg which is (1).
1497
+ # 'func (1, 2)' would fail in old logic too.
1498
+ # So the above block handles the explicit invocation.
1499
+ # This loop is for 'func 1 2'.
1500
+
1501
+ # Check for keywords or invalid start tokens
1502
+ if next_t.type not in ('NUMBER', 'STRING', 'REGEX', 'ID', 'LPAREN', 'INPUT', 'ASK', 'YES', 'NO', 'LBRACKET', 'LBRACE'):
1308
1503
  break
1504
+
1505
+ # Special case: if we see LPAREN, is it part of command args?
1506
+ # e.g. 'func (1+2)' -> args=[(1+2)].
1507
+ args.append(self.parse_factor_simple())
1508
+
1309
1509
  if method_name:
1310
- if args or force_call:
1510
+ if args:
1311
1511
  node = MethodCall(instance_name, method_name, args)
1312
1512
  else:
1313
1513
  node = PropertyAccess(instance_name, method_name)
1314
1514
  node.line = token.line
1315
1515
  return node
1316
- if args or force_call:
1516
+
1517
+ if args:
1317
1518
  node = Call(instance_name, args)
1318
1519
  node.line = token.line
1319
1520
  return node
1521
+
1320
1522
  node = VarAccess(instance_name)
1321
1523
  node.line = token.line
1322
1524
  return node
@@ -1349,6 +1551,8 @@ class Parser:
1349
1551
  node = Confirm(prompt_expr)
1350
1552
  node.line = token.line
1351
1553
  return node
1554
+ elif token.type == 'MAKE':
1555
+ return self.parse_make_expr()
1352
1556
  raise SyntaxError(f"Unexpected token {token.type} at line {token.line}")
1353
1557
  def parse_for(self) -> Node:
1354
1558
  if self.check('LOOP'):
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.1
2
+ Name: shell-lite
3
+ Version: 0.4.1
4
+ Summary: A lightweight, English-like scripting language.
5
+ Author-email: Shrey Naithani <contact@shelllite.tech>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: prompt-toolkit>=3.0.0
13
+
14
+ <img src="assets/logo.png" align="right" width="250" alt="ShellLite Logo" />
15
+
16
+ # ShellLite: The English-Like Programming Language
17
+ # By Shrey Naithani
18
+ ShellLite is a modern, interpreted programming language designed to prioritize human readability. It replaces complex syntax with natural English commands, making software development accessible and maintainable.
19
+
20
+ ## Version 0.04.0 (Polaris Update)
21
+
22
+ This release transforms ShellLite from a scripting tool into a comprehensive platform with three major pillars:
23
+ 1. **The Bridge**: Import and use any Python library (pandas, requests, etc.) natively.
24
+ 2. **The Canvas**: Build native desktop GUI applications with declarative syntax.
25
+ 3. **The Universe**: Integrated package management for project dependencies.
26
+
27
+ ## Installation
28
+
29
+ ### Via PyPI (Recommended)
30
+ You can install ShellLite directly from PyPI:
31
+ ```bash
32
+ pip install shell-lite
33
+ ```
34
+
35
+ ### Windows Installer
36
+ Download the latest `shl.exe` from the Releases page.
37
+
38
+ ## Quick Start
39
+
40
+ ### 1. Hello World
41
+ Save this as `hello.shl`:
42
+ ```shell-lite
43
+ say "Hello, World"
44
+ ```
45
+ Run it:
46
+ ```bash
47
+ shl hello.shl
48
+ ```
49
+ ## Project Management
50
+
51
+ Initialize a new project:
52
+ ```bash
53
+ shl init
54
+ ```
55
+
56
+ Install dependencies defined in `shell-lite.toml`:
57
+ ```bash
58
+ shl install
59
+ ```
60
+
61
+ ## Ecosystem & Tools
62
+
63
+ | Tool | Description | Link |
64
+ | :--- | :--- | :--- |
65
+ | **ShellDesk** | The official IDE for ShellLite. | [GitHub](https://github.com/Shrey-N/ShellDesk) |
66
+ | **VS Code Extension** | Syntax highlighting and snippets. | [Marketplace](https://marketplace.visualstudio.com/items?itemName=ShellLite.shelllite-hello) / [OpenVSX](https://open-vsx.org/extension/shelllite/shelllite-hello) |
67
+ | **Website** | Official website source code. | [GitHub](https://github.com/Shrey-N/ShellLite-Website) |
68
+
69
+ ## Documentation
70
+
71
+ Full documentation is available directly in this repository:
72
+ - [**Language Guide**](https://github.com/Shrey-N/ShellLite)
73
+ - [**Examples**](https://github.com/Shrey-N/ShellLite/tree/main/examples)
74
+
75
+ License: MIT
76
+ Made by Shrey Naithani
77
+
@@ -0,0 +1,17 @@
1
+ shell_lite/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
2
+ shell_lite/ast_nodes.py,sha256=KGFlZmP21MJXo6uRYRJfo_R3BEspfDD8xMBtAVfUDgU,5873
3
+ shell_lite/cli.py,sha256=14Kq1ohSXS3p-xdh0DPi7eXskUtSX81huSyGhktoOMA,250
4
+ shell_lite/compiler.py,sha256=FcwDLbrjnMnH0VMzEeYPSqD3nIeFAwKIdvEDAT1e3GE,24984
5
+ shell_lite/formatter.py,sha256=590BfQmhsX466i5_xONXAhgVE97zfcV79q1wA3DT47A,2952
6
+ shell_lite/interpreter.py,sha256=oyyFIe8bx4Tok09Nd-qIexU6D9rVdvyxe2JVzCaHHTY,74577
7
+ shell_lite/js_compiler.py,sha256=b2-XyGqm2BYUfwU0OsphpMxLNeho1ihL7htAcg3uWII,9438
8
+ shell_lite/lexer.py,sha256=UDQtFX7UW3HgMftQ3HsCu9tfImk9vsyMX5icsAI6NuE,12549
9
+ shell_lite/main.py,sha256=h-RIPB-QcfQdQslafILdztJqKcRf9exoNF0gYMXWVww,22517
10
+ shell_lite/parser.py,sha256=Eh-LjIX1AdYyuhPaL-_GPlDoSzDM0RxDNQsBWog-06k,73377
11
+ shell_lite/runtime.py,sha256=pSjBeA1dTQ-a94q3FLdv9lqZurdd6MJmfhFGHhOoQEM,16057
12
+ shell_lite-0.4.1.dist-info/LICENSE,sha256=33eziKLPxbqGCqdHtEHAFe1KSOgqc0-jWUQmdgKq85Q,1092
13
+ shell_lite-0.4.1.dist-info/METADATA,sha256=7S7UoqTYKp5Wq1oZhTscVOrhCAT64iQs_k8L9QDJxaI,2475
14
+ shell_lite-0.4.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
15
+ shell_lite-0.4.1.dist-info/entry_points.txt,sha256=tglL8tjyPIh1W85j6zFpNZjMpQe_xC-k-7BOhHLWfxc,45
16
+ shell_lite-0.4.1.dist-info/top_level.txt,sha256=hIln5ltrok_Mn3ijlQeqMFF6hHBHCyhzqCO7KL358cg,11
17
+ shell_lite-0.4.1.dist-info/RECORD,,
@@ -1,40 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: shell-lite
3
- Version: 0.3.5
4
- Summary: A lightweight, English-like scripting language.
5
- Author-email: Shrey Naithani <contact@shelllite.tech>
6
- License: MIT
7
- Classifier: Programming Language :: Python :: 3
8
- Classifier: Operating System :: OS Independent
9
- Requires-Python: >=3.8
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
-
13
- # ShellLite
14
-
15
- **ShellLite** is a programming language designed to be as readable as plain English. It strips away the complex syntax of traditional languages and replaces it with natural, human-friendly commands.
16
-
17
- ## ⭐ Support Us
18
-
19
- If you like ShellLite, please kindly **star** our repository on GitHub! It helps us grow.
20
-
21
- 👉 [**GitHub Repository**](https://github.com/Shrey-N/ShellLite)
22
-
23
- ## 📦 Installation
24
-
25
- ```bash
26
- pip install shell-lite
27
- ```
28
-
29
- ## 🔗 Ecosystem
30
-
31
- - **Website & IDE**: [shelllite.tech](https://shelllite.tech)
32
- - **VS Code Extension**: [Marketplace](https://marketplace.visualstudio.com/items?itemName=shelllite.shelllite-hello)
33
- - **OpenVSX**: [OpenVSX Registry](https://open-vsx.org/extension/shelllite/shelllite-hello)
34
-
35
- ## 📞 Contact
36
-
37
- To help in the development, please contact **Shrey Naithani** at [contact@shelllite.tech](mailto:contact@shelllite.tech).
38
-
39
- ---
40
- **Made by Shrey Naithani**
@@ -1,17 +0,0 @@
1
- shell_lite/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
2
- shell_lite/ast_nodes.py,sha256=xbxIiUSduXWdq0DYQQLkWpW5TfmOFxmbpBRbe3YDyfI,5341
3
- shell_lite/cli.py,sha256=14Kq1ohSXS3p-xdh0DPi7eXskUtSX81huSyGhktoOMA,250
4
- shell_lite/compiler.py,sha256=nAWLyU1aLc5OJm5qpe3aHsKyVQ61JfHerOs3rl572xU,24600
5
- shell_lite/formatter.py,sha256=590BfQmhsX466i5_xONXAhgVE97zfcV79q1wA3DT47A,2952
6
- shell_lite/interpreter.py,sha256=yuGCdIL66SV9bwHGA2fUI6RwoJ45TheAiu_p0QZY8Z8,66858
7
- shell_lite/js_compiler.py,sha256=yBAHRASGccKIe5-U_SbLO13TexhJydQ_bClDHzWhogI,8877
8
- shell_lite/lexer.py,sha256=c8KpM9qtGmmUks3SlCZzEz-CdEj-Z1JC34FMr3WD9i0,12355
9
- shell_lite/main.py,sha256=ubDEMXWlxT7eUyfRlnzDkc8CVCqqzYLpBHkh8EJ1-Mg,15469
10
- shell_lite/parser.py,sha256=xT_CuN6Nz4Pz5sU5iM-KpnCWFde1txk1JRhhqFlckc8,64902
11
- shell_lite/runtime.py,sha256=pSjBeA1dTQ-a94q3FLdv9lqZurdd6MJmfhFGHhOoQEM,16057
12
- shell_lite-0.3.5.dist-info/LICENSE,sha256=33eziKLPxbqGCqdHtEHAFe1KSOgqc0-jWUQmdgKq85Q,1092
13
- shell_lite-0.3.5.dist-info/METADATA,sha256=-mt7dpP-TJ93MWZEcytgaT6CG2MO7XlUnPjM00Lo4-I,1311
14
- shell_lite-0.3.5.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
15
- shell_lite-0.3.5.dist-info/entry_points.txt,sha256=tglL8tjyPIh1W85j6zFpNZjMpQe_xC-k-7BOhHLWfxc,45
16
- shell_lite-0.3.5.dist-info/top_level.txt,sha256=hIln5ltrok_Mn3ijlQeqMFF6hHBHCyhzqCO7KL358cg,11
17
- shell_lite-0.3.5.dist-info/RECORD,,