dshellInterpreter 0.1.3__py3-none-any.whl → 0.1.6__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 dshellInterpreter might be problematic. Click here for more details.

@@ -1,7 +1,8 @@
1
1
  from asyncio import sleep
2
2
  from re import search
3
+ from typing import Union
3
4
 
4
- from discord import MISSING
5
+ from discord import MISSING, PermissionOverwrite, Member, Role
5
6
  from discord.abc import GuildChannel
6
7
 
7
8
  __all__ = [
@@ -10,8 +11,10 @@ __all__ = [
10
11
  'dshell_delete_channels'
11
12
  ]
12
13
 
14
+
13
15
  async def dshell_create_text_channel(ctx: GuildChannel, name, category=None, position=MISSING, slowmode=MISSING,
14
- topic=MISSING, nsfw=MISSING):
16
+ topic=MISSING, nsfw=MISSING,
17
+ permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING):
15
18
  """
16
19
  Crée un salon textuel sur le serveur
17
20
  """
@@ -23,7 +26,8 @@ async def dshell_create_text_channel(ctx: GuildChannel, name, category=None, pos
23
26
  position=position,
24
27
  slowmode_delay=slowmode,
25
28
  topic=topic,
26
- nsfw=nsfw)
29
+ nsfw=nsfw,
30
+ overwrites=permission._values)
27
31
 
28
32
  return created_channel.id
29
33
 
@@ -1,7 +1,6 @@
1
1
  from discord import Embed
2
2
  from discord.abc import GuildChannel
3
3
 
4
- from .._DshellParser.ast_nodes import ListNode
5
4
 
6
5
  __all__ = [
7
6
  'dshell_send_message',
@@ -9,8 +8,9 @@ __all__ = [
9
8
  'dshell_purge_message'
10
9
  ]
11
10
 
12
- async def dshell_send_message(ctx: GuildChannel, message=None, delete=None, channel=None, embeds: ListNode = None,
13
- embed=None):
11
+
12
+ async def dshell_send_message(ctx: GuildChannel, message=None, delete=None, channel=None, embeds=None, embed=None):
13
+ from .._DshellParser.ast_nodes import ListNode
14
14
  """
15
15
  Envoie un message sur Discord
16
16
  """
@@ -2,13 +2,13 @@ from asyncio import sleep
2
2
  from re import findall
3
3
  from typing import TypeVar, Union, Any, Optional, Callable
4
4
 
5
- from discord import AutoShardedBot, Embed, Colour
5
+ from discord import AutoShardedBot, Embed, Colour, PermissionOverwrite, Permissions, Guild, Member, Role
6
6
  from discord.abc import GuildChannel, PrivateChannel
7
7
 
8
- from .._DshellTokenizer.dshell_keywords import *
9
8
  from .._DshellParser.ast_nodes import *
10
9
  from .._DshellParser.dshell_parser import parse
11
10
  from .._DshellParser.dshell_parser import to_postfix, print_ast
11
+ from .._DshellTokenizer.dshell_keywords import *
12
12
  from .._DshellTokenizer.dshell_token_type import DshellTokenType as DTT
13
13
  from .._DshellTokenizer.dshell_token_type import Token
14
14
  from .._DshellTokenizer.dshell_tokenizer import DshellTokenizer
@@ -23,7 +23,7 @@ class DshellInterpreteur:
23
23
  """
24
24
  Interpreter Dshell code or AST.
25
25
  """
26
- self.ast: StartNode = parse(DshellTokenizer(ast_or_code).start(), StartNode([]))[0]
26
+ self.ast: list[ASTNode] = parse(DshellTokenizer(ast_or_code).start(), StartNode([]))[0]
27
27
  self.env: dict[str, Any] = {}
28
28
  self.ctx: context = ctx
29
29
  if debug:
@@ -75,6 +75,9 @@ class DshellInterpreteur:
75
75
  elif isinstance(first_node, EmbedNode):
76
76
  self.env[node.name.value] = build_embed(first_node.body, first_node.fields, self)
77
77
 
78
+ elif isinstance(first_node, PermissionNode):
79
+ self.env[node.name.value] = build_permission(first_node.body, self)
80
+
78
81
  else:
79
82
  self.env[node.name.value] = eval_expression(node.body, self)
80
83
 
@@ -93,6 +96,7 @@ class DshellInterpreteur:
93
96
 
94
97
  await sleep(sleep_time)
95
98
 
99
+
96
100
  elif isinstance(node, EndNode):
97
101
  raise RuntimeError(f"Execution interromput -> #end atteint")
98
102
 
@@ -110,6 +114,8 @@ class DshellInterpreteur:
110
114
  return float(token.value)
111
115
  elif token.type == DTT.BOOL:
112
116
  return token.value.lower() == "true"
117
+ elif token.type == DTT.NONE:
118
+ return None
113
119
  elif token.type == DTT.LIST:
114
120
  return ListNode(
115
121
  [self.eval_data_token(tok) for tok in token.value]) # token.value contient déjà une liste de Token
@@ -176,7 +182,7 @@ async def call_function(function: Callable, args: ArgsCommandNode, interpreter:
176
182
  """
177
183
  Appelle une fonction avec évaluation des arguments Dshell en valeurs Python
178
184
  """
179
- reformatted = regroupe_commandes(args.body, interpreter)
185
+ reformatted = regroupe_commandes(args.body, interpreter)[0]
180
186
 
181
187
  # conversion des args en valeurs Python
182
188
  absolute_args = reformatted.pop('*', list())
@@ -190,7 +196,7 @@ async def call_function(function: Callable, args: ArgsCommandNode, interpreter:
190
196
  return await function(*absolute_args, **keyword_args)
191
197
 
192
198
 
193
- def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> dict[Union[str, Token], list[Token]]:
199
+ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> list[dict[str, list[Any]]]:
194
200
  """
195
201
  Regroupe les arguments de la commande sous la forme d'un dictionnaire python.
196
202
  Sachant que l'on peut spécifier le paramètre que l'on souhaite passer via -- suivit du nom du paramètre. Mais ce n'est pas obligatoire !
@@ -200,6 +206,7 @@ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> di
200
206
  tokens = {'*': []} # les tokens à renvoyer
201
207
  current_arg = '*' # les clés des arguments sont les types auquels ils appartiennent. L'* sert à tous les arguments non explicité par un séparateur et un IDENT
202
208
  n = len(body)
209
+ list_tokens: list[dict] = [tokens]
203
210
 
204
211
  i = 0
205
212
  while i < n:
@@ -208,26 +215,36 @@ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> di
208
215
  current_arg = body[i + 1].value # on change l'argument actuel. Il sera donc impossible de revenir à l'*
209
216
  tokens[current_arg] = '' # on lui crée une paire clé/valeur
210
217
  i += 2 # on skip l'IDENT qu'il y a après le séparateur car on vient de le traiter
218
+
219
+ elif body[
220
+ i].type == DTT.SUB_SEPARATOR: # permet de délimiter les paramètres et de pouvoir en mettre plusieurs ayant le même nom
221
+ list_tokens += regroupe_commandes(
222
+ [Token(
223
+ type_=DTT.SEPARATOR, value=body[i].value, position=body[i].position)
224
+ ] + body[i + 1:], interpreter
225
+ ) # on ajoute un sous-dictionnaire pour les sous-commandes
226
+ return list_tokens
227
+
211
228
  else:
212
229
  if current_arg == '*':
213
230
  tokens[current_arg].append(interpreter.eval_data_token(body[i]))
214
231
  else:
215
232
  tokens[current_arg] = interpreter.eval_data_token(body[i]) # on ajoute le token à l'argument actuel
216
233
  i += 1
217
- return tokens
234
+ return list_tokens
218
235
 
219
236
 
220
237
  def build_embed(body: list[Token], fields: list[FieldEmbedNode], interpreter: DshellInterpreteur) -> Embed:
221
238
  """
222
239
  Construit un embed à partir des informations de la commande.
223
240
  """
224
- args_main_embed: dict[Union[str, Token], list[Token]] = regroupe_commandes(body, interpreter)
241
+ args_main_embed: dict[str, list[Any]] = regroupe_commandes(body, interpreter)[0]
225
242
  args_main_embed.pop('*') # on enlève les paramètres non spécifié pour l'embed
226
243
  args_main_embed: dict[str, Token] # on précise se qu'il contient dorénavant
227
244
 
228
245
  args_fields: list[dict[str, Token]] = []
229
246
  for field in fields: # on fait la même chose pour tous les fields
230
- a = regroupe_commandes(field.body, interpreter)
247
+ a = regroupe_commandes(field.body, interpreter)[0]
231
248
  a.pop('*')
232
249
  a: dict[str, Token]
233
250
  args_fields.append(a)
@@ -243,6 +260,21 @@ def build_embed(body: list[Token], fields: list[FieldEmbedNode], interpreter: Ds
243
260
  return embed
244
261
 
245
262
 
263
+ def build_permission(body: list[Token], interpreter: DshellInterpreteur) -> dict[
264
+ Union[Member, Role], PermissionOverwrite]:
265
+ """
266
+ Construit un dictionnaire de permissions à partir des informations de la commande.
267
+ """
268
+ args_permissions: list[dict[str, list[Any]]] = regroupe_commandes(body, interpreter)
269
+ permissions: dict[Union[Member, Role], PermissionOverwrite] = {}
270
+
271
+ for i in args_permissions:
272
+ i.pop('*')
273
+ permissions.update(DshellPermissions(i).get_permission_overwrite(interpreter.ctx.guild))
274
+
275
+ print(args_permissions)
276
+
277
+
246
278
  class DshellIterator:
247
279
  """
248
280
  Utilisé pour transformer n'importe quoi en un iterable
@@ -267,3 +299,98 @@ class DshellIterator:
267
299
  value = self.data[self.current]
268
300
  self.current += 1
269
301
  return value
302
+
303
+
304
+ class DshellPermissions:
305
+
306
+ def __init__(self, target: dict[str, list[int]]):
307
+ """
308
+ Permet de créer un objet de permissions Dshell.
309
+ :param target: Un dictionnaire contenant les paramètres et leurs valeurs.
310
+ Paramètres attendus : "allow", "deny", "members", "roles".
311
+ Pour "members" et "roles", les valeurs doivent être des ListNode d'IDs.
312
+ """
313
+ self.target: dict[str, Union[ListNode, int]] = target
314
+
315
+ @staticmethod
316
+ def get_instance(guild: Guild, target_id: int) -> Union[Member, Role]:
317
+ """
318
+ Retourne l'instance correspondante à l'id donné. Uniquement un Member ou un Role.
319
+ :param guild: Le serveur Discord dans lequel chercher
320
+ :param target_id: L'ID du membre ou du rôle
321
+ :return: Une instance de Member ou Role
322
+ """
323
+ try:
324
+ member = DshellPermissions.get_member(guild, target_id)
325
+ except ValueError:
326
+ member = None
327
+
328
+ try:
329
+ role = DshellPermissions.get_role(guild, target_id)
330
+ except ValueError:
331
+ role = None
332
+
333
+ if member is not None:
334
+ return member
335
+
336
+ if role is not None:
337
+ return role
338
+
339
+ raise ValueError(f"Aucun membre ou rôle trouvé avec l'ID {target_id} dans le serveur {guild.name}.")
340
+
341
+ @staticmethod
342
+ def get_member(guild: Guild, target_id: int) -> Member:
343
+ """
344
+ Retourne l'instance de Member correspondante à l'id donné.
345
+ :param guild: Le serveur Discord dans lequel chercher
346
+ :param target_id: L'ID du membre
347
+ :return: Une instance de Member
348
+ """
349
+ member = guild.get_member(target_id)
350
+ if member is not None:
351
+ return member
352
+
353
+ raise ValueError(f"Aucun membre trouvé avec l'ID {target_id} dans le serveur {guild.name}.")
354
+
355
+ @staticmethod
356
+ def get_role(guild: Guild, target_id: int) -> Role:
357
+ """
358
+ Retourne l'instance de Role correspondante à l'id donné.
359
+ :param guild: Le serveur Discord dans lequel chercher
360
+ :param target_id: L'ID du rôle
361
+ :return: Une instance de Role
362
+ """
363
+ role = guild.get_role(target_id)
364
+ if role is not None:
365
+ return role
366
+
367
+ raise ValueError(f"Aucun rôle trouvé avec l'ID {target_id} dans le serveur {guild.name}.")
368
+
369
+ def get_permission_overwrite(self, guild: Guild) -> dict[Union[Member, Role], PermissionOverwrite]:
370
+ """
371
+ Retourne un objet PermissionOverwrite avec les permissions des membres et rôles.
372
+ :param guild: Le serveur Discord
373
+ :return: Un objet PermissionOverwrite
374
+ """
375
+ permissions: dict[Union[Member, Role], PermissionOverwrite] = {}
376
+ target_keys = self.target.keys()
377
+
378
+ if 'members' in target_keys:
379
+ for member_id in self.target['members']:
380
+ member = self.get_member(guild, member_id)
381
+ permissions[member] = PermissionOverwrite.from_pair(
382
+ allow=Permissions(permissions=self.target.get('allow', 0)),
383
+ deny= Permissions(permissions=self.target.get('deny', 0))
384
+ )
385
+
386
+ elif 'roles' in target_keys:
387
+ for role_id in self.target['roles']:
388
+ role = self.get_role(guild, role_id)
389
+ permissions[role] = PermissionOverwrite.from_pair(
390
+ allow=Permissions(permissions=self.target.get('allow', 0)),
391
+ deny= Permissions(permissions=self.target.get('deny', 0))
392
+ )
393
+ else:
394
+ raise ValueError("Aucun membre ou rôle spécifié dans les permissions.")
395
+
396
+ return permissions
@@ -1,7 +1,8 @@
1
- from typing import Optional, Any
1
+ from typing import Optional, Any, TYPE_CHECKING
2
2
 
3
3
  from .._DshellTokenizer.dshell_token_type import Token
4
4
 
5
+
5
6
  __all__ = [
6
7
  'ASTNode',
7
8
  'StartNode',
@@ -17,9 +18,11 @@ __all__ = [
17
18
  'EmbedNode',
18
19
  'SleepNode',
19
20
  'IdentOperationNode',
20
- 'ListNode'
21
+ 'ListNode',
22
+ 'PermissionNode'
21
23
  ]
22
24
 
25
+
23
26
  class ASTNode:
24
27
  pass
25
28
 
@@ -122,6 +125,14 @@ class EmbedNode(ASTNode):
122
125
  return f"<EMBED> - {self.body}"
123
126
 
124
127
 
128
+ class PermissionNode(ASTNode):
129
+ def __init__(self, body: list[Token]):
130
+ self.body = body
131
+
132
+ def __repr__(self):
133
+ return f"<PERMISSION> - {self.body}"
134
+
135
+
125
136
  class SleepNode(ASTNode):
126
137
  def __init__(self, body: list[Token]):
127
138
  self.body = body
@@ -21,6 +21,7 @@ from .ast_nodes import (ASTNode,
21
21
  IdentOperationNode,
22
22
  EmbedNode,
23
23
  FieldEmbedNode,
24
+ PermissionNode,
24
25
  StartNode)
25
26
  from .._DshellTokenizer.dshell_token_type import DshellTokenType as DTT
26
27
  from .._DshellTokenizer.dshell_token_type import Token
@@ -157,6 +158,19 @@ def parse(token_lines: list[list[Token]], start_node: ASTNode) -> tuple[list[AST
157
158
  raise SyntaxError(f'[FIELD] Aucun embed ouvert ligne {first_token_line.position} !')
158
159
  last_block.fields.append(FieldEmbedNode(tokens_by_line[1:]))
159
160
 
161
+ elif first_token_line.value in ('perm', 'permission'):
162
+ perm_node = PermissionNode(body=[])
163
+ var_node = VarNode(tokens_by_line[1], body=[perm_node])
164
+ last_block.body.append(var_node)
165
+ _, p = parse(token_lines[pointeur + 1:], perm_node)
166
+ pointeur += p + 1
167
+
168
+ elif first_token_line.value in ('#perm', '#permission'):
169
+ if not isinstance(last_block, PermissionNode):
170
+ raise SyntaxError(f'[#PERM] Aucun permission ouvert ligne {first_token_line.position} !')
171
+ blocks.pop()
172
+ return blocks, pointeur
173
+
160
174
  ############################## AUTRE ##############################
161
175
 
162
176
  elif first_token_line.type == DTT.IDENT:
@@ -6,7 +6,9 @@ __all__ = [
6
6
  "dshell_logical_operators",
7
7
  "dshell_operators"
8
8
  ]
9
+
9
10
  from typing import Callable
11
+
10
12
  from ..DISCORD_COMMANDS.dshell_channel import *
11
13
  from ..DISCORD_COMMANDS.dshell_message import *
12
14
 
@@ -15,9 +17,8 @@ dshell_keyword: set[str] = {
15
17
  }
16
18
 
17
19
  dshell_discord_keyword: set[str] = {
18
- 'embed', '#embed', 'field'
20
+ 'embed', '#embed', 'field', 'perm', 'permission', '#perm', '#permission'
19
21
  }
20
-
21
22
  dshell_commands: dict[str, Callable] = {
22
23
  "sm": dshell_send_message, # send message
23
24
  "dm": dshell_delete_message,
@@ -68,8 +69,6 @@ dshell_logical_operators: dict[str, tuple[Callable, int]] = {
68
69
  dshell_operators: dict[str, tuple[Callable, int]] = dshell_logical_operators.copy()
69
70
  dshell_operators.update(dshell_mathematical_operators)
70
71
 
71
-
72
-
73
72
  '''
74
73
  C_create_var = "var"
75
74
  C_obligate_var = "ovar" # rend obligatoire les variables
@@ -14,7 +14,8 @@ class DshellTokenType(Enum):
14
14
  INT = auto()
15
15
  FLOAT = auto()
16
16
  STR = auto()
17
- BOOL = auto()
17
+ BOOL = auto(),
18
+ NONE = auto(),
18
19
  LIST = auto()
19
20
  CALL_ARGS = auto()
20
21
  DICT = auto()
@@ -23,7 +24,8 @@ class DshellTokenType(Enum):
23
24
  KEYWORD = auto() # if, let, end, etc.
24
25
  DISCORD_KEYWORD = auto() # embed, #embed...
25
26
  COMMAND = auto()
26
- SEPARATOR = auto()
27
+ SEPARATOR = auto() # --
28
+ SUB_SEPARATOR = auto(), # ~~
27
29
  MATHS_OPERATOR = auto() # ==, +, -, *, etc.
28
30
  LOGIC_OPERATOR = auto(),
29
31
  COMMENT = auto() # lignes commençant par ##
@@ -23,12 +23,14 @@ table_regex: dict[DTT, Pattern] = {
23
23
  DTT.KEYWORD: compile(rf"(?<!\w)(#?{'|'.join(dshell_keyword)})(?!\w)"),
24
24
  DTT.DISCORD_KEYWORD: compile(rf"(?<!\w|-)(#?{'|'.join(dshell_discord_keyword)})(?!\w|-)"),
25
25
  DTT.SEPARATOR: compile(rf"(--)"),
26
+ DTT.SUB_SEPARATOR: compile(rf"(~~)"),
26
27
  DTT.COMMAND: compile(rf"\b({'|'.join(dshell_commands.keys())})\b"),
27
28
  DTT.MATHS_OPERATOR: compile(rf"({'|'.join([escape(i) for i in dshell_mathematical_operators.keys()])})"),
28
29
  DTT.LOGIC_OPERATOR: compile(rf"(?<!\w)({'|'.join([escape(i) for i in dshell_logical_operators.keys()])})(?<!\w)"),
29
30
  DTT.FLOAT: compile(r"(\d+\.\d+)"),
30
31
  DTT.INT: compile(r"(\d+)"),
31
32
  DTT.BOOL: compile(r"(True|False)", flags=IGNORECASE),
33
+ DTT.NONE: compile(r"(None)", flags=IGNORECASE),
32
34
  DTT.IDENT: compile(rf"([A-Za-z0-9_]+)")
33
35
  }
34
36
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dshellInterpreter
3
- Version: 0.1.3
3
+ Version: 0.1.6
4
4
  Summary: A Discord bot interpreter for creating custom commands and automations.
5
5
  Home-page: https://github.com/BOXERRMD/Dshell_Interpreter
6
6
  Author: Chronos
@@ -31,4 +31,5 @@ Dynamic: requires-python
31
31
  Dynamic: summary
32
32
 
33
33
  # Dshell_Interpreter
34
+
34
35
  Python interpreter for Discord.
@@ -0,0 +1,18 @@
1
+ Dshell/__init__.py,sha256=UPvXnewe_8FX9aoevMA78UN1k8AY-u8LTY3vEVxaDxw,72
2
+ Dshell/DISCORD_COMMANDS/__init__.py,sha256=s58iMazDXNPDLZ3Hvymh__C5w7lcgEvaYfX0-SHocRo,62
3
+ Dshell/DISCORD_COMMANDS/dshell_channel.py,sha256=Vtmp9J-h89cxL46enLWG1GNN7s1jNQgd-ZRvponq49I,2396
4
+ Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=FhUo_zpdHJErsAjKyO34SXPdDkwPmE_QSli5svIpI4E,1882
5
+ Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
6
+ Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=6EzLmV7s8xT0tpg31ZyPieLpNqzB23plPJDcWPwYqv8,15942
7
+ Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
8
+ Dshell/_DshellParser/ast_nodes.py,sha256=3QyfTGCNeCn2e1QFda1DMiGziLPgGNMnRh5_XyzR8BI,5704
9
+ Dshell/_DshellParser/dshell_parser.py,sha256=mA8uA-xBhKcfnSKfLfePwI_fD0GrHbj0VBVeJPbcGas,13956
10
+ Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
11
+ Dshell/_DshellTokenizer/dshell_keywords.py,sha256=wTV89px9bUY4uf0KCnDr356H_dBIVgcPr55L_6-AWdg,3661
12
+ Dshell/_DshellTokenizer/dshell_token_type.py,sha256=NE-sVloBYtioZpWKnWuO5p0YcObGJZPNaKwc8lWDonQ,999
13
+ Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=2tto_gXYj94fLFx99p6nBbtplALT3Ysz9oBwatX9tIA,5788
14
+ dshellinterpreter-0.1.6.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
15
+ dshellinterpreter-0.1.6.dist-info/METADATA,sha256=x2myoZGTHcsxK6YTTnUTbUMPyVmQSQlX_DR3nT135Hg,1095
16
+ dshellinterpreter-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ dshellinterpreter-0.1.6.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
18
+ dshellinterpreter-0.1.6.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- Dshell/__init__.py,sha256=UPvXnewe_8FX9aoevMA78UN1k8AY-u8LTY3vEVxaDxw,72
2
- Dshell/DISCORD_COMMANDS/__init__.py,sha256=s58iMazDXNPDLZ3Hvymh__C5w7lcgEvaYfX0-SHocRo,62
3
- Dshell/DISCORD_COMMANDS/dshell_channel.py,sha256=IubzNzBtGEcbgkL_NJOWRY1oqE3Yb-ySDMUmoHKjGzM,2135
4
- Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=jgSGBeDDHVy8u9fX2WN6wzh7I9WqVkeySlpmbJsBZjs,1919
5
- Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
6
- Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=xMGOPQFm4bEz2mNx-ZEZcQpjf_qgKw-yGv-yHVWZy9Q,10818
7
- Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
8
- Dshell/_DshellParser/ast_nodes.py,sha256=ArTyuk7AykJ3xKiW656BOdZg92YEwbfAlzZF1YQeZoA,5483
9
- Dshell/_DshellParser/dshell_parser.py,sha256=gFSngEyNcuYlpWPAPNyuwWetwIpQKFSQWnS_r1B-dRs,13247
10
- Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
11
- Dshell/_DshellTokenizer/dshell_keywords.py,sha256=NFa4VdfX26X5lU1Ps05hZkZg5IyBDpG9WgT9L1oTckM,3617
12
- Dshell/_DshellTokenizer/dshell_token_type.py,sha256=Gp-Vg2P96oTaKpOEKGHAvER7l98mbcuwmapLVJgmoCI,937
13
- Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=9ycZhz2X2uvZynE0illgi5AhtNyR_c5o1KX-pwCP1xM,5692
14
- dshellinterpreter-0.1.3.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
15
- dshellinterpreter-0.1.3.dist-info/METADATA,sha256=2JV6Io5ErRYXuFUAGbRJs_VwyAF1XPwvbR3QIk1I7o0,1093
16
- dshellinterpreter-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- dshellinterpreter-0.1.3.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
18
- dshellinterpreter-0.1.3.dist-info/RECORD,,