dshellInterpreter 1.2.0.4__tar.gz → 1.2.0.6__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.
Files changed (53) hide show
  1. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_file.py +23 -2
  2. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/dshell_interpreter.py +43 -18
  3. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellParser/ast_nodes.py +77 -2
  4. dshellinterpreter-1.2.0.6/Dshell/DshellParser/errors.py +8 -0
  5. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellTokenizer/dshell_keywords.py +1 -0
  6. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/full_import.py +1 -1
  7. {dshellinterpreter-1.2.0.4/dshellInterpreter.egg-info → dshellinterpreter-1.2.0.6}/PKG-INFO +1 -1
  8. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6/dshellInterpreter.egg-info}/PKG-INFO +1 -1
  9. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/dshellInterpreter.egg-info/SOURCES.txt +1 -0
  10. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/setup.py +1 -1
  11. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/__init__.py +0 -0
  12. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_channel.py +0 -0
  13. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_embed.py +0 -0
  14. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_interaction.py +0 -0
  15. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_member.py +0 -0
  16. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_message.py +0 -0
  17. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_pastbin.py +0 -0
  18. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_role.py +0 -0
  19. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/dshell_ui.py +0 -0
  20. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/__init__.py +0 -0
  21. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_embed.py +0 -0
  22. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_file.py +0 -0
  23. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_global.py +0 -0
  24. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_list.py +0 -0
  25. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_member.py +0 -0
  26. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_message.py +0 -0
  27. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_numbers.py +0 -0
  28. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_permissions.py +0 -0
  29. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_string.py +0 -0
  30. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_thread.py +0 -0
  31. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DISCORD_COMMANDS/utils/utils_type_validation.py +0 -0
  32. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/__init__.py +0 -0
  33. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/cached_messages.py +0 -0
  34. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/dshell_arguments.py +0 -0
  35. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/dshell_global_variables.py +0 -0
  36. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/dshell_scope.py +0 -0
  37. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/errors.py +0 -0
  38. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellInterpreteur/utils_interpreter.py +0 -0
  39. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellParser/__init__.py +0 -0
  40. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellParser/dshell_parser.py +0 -0
  41. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellPreProcess/__init__.py +0 -0
  42. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellPreProcess/dshell_preprocess.py +0 -0
  43. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellTokenizer/__init__.py +0 -0
  44. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellTokenizer/dshell_token_type.py +0 -0
  45. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/DshellTokenizer/dshell_tokenizer.py +0 -0
  46. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/__init__.py +0 -0
  47. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/Dshell/regex_test.py +0 -0
  48. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/LICENSE +0 -0
  49. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/README.md +0 -0
  50. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/dshellInterpreter.egg-info/dependency_links.txt +0 -0
  51. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/dshellInterpreter.egg-info/requires.txt +0 -0
  52. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/dshellInterpreter.egg-info/top_level.txt +0 -0
  53. {dshellinterpreter-1.2.0.4 → dshellinterpreter-1.2.0.6}/setup.cfg +0 -0
@@ -1,5 +1,6 @@
1
+
1
2
  from ..full_import import Message, Union, PartialMessage, Optional
2
- from ..DshellParser.ast_nodes import ListNode, FileNode, StrNode, BoolNode, IntNode
3
+ from ..DshellParser.ast_nodes import ListNode, FileNode, StrNode, BoolNode, IntNode, FileStreamNode
3
4
 
4
5
  from .utils.utils_message import utils_get_message
5
6
  from .utils.utils_type_validation import (_validate_required_file_node,
@@ -11,6 +12,7 @@ __all__ = [
11
12
  "dshell_get_message_files",
12
13
  "dshell_write_file",
13
14
  "dshell_read_file",
15
+ "dshell_stream_file"
14
16
  ]
15
17
 
16
18
  async def dshell_get_message_files(ctx: Message, message: Union[StrNode, IntNode]) -> ListNode:
@@ -23,7 +25,7 @@ async def dshell_get_message_files(ctx: Message, message: Union[StrNode, IntNode
23
25
 
24
26
  target_message = ctx if message is None else utils_get_message(ctx, message)
25
27
 
26
- attachments_list: ListNode = ListNode([])
28
+ attachments_list: ListNode = ListNode([], bypass_limit_elt=True)
27
29
 
28
30
  if isinstance(target_message, PartialMessage):
29
31
  target_message = await target_message.fetch()
@@ -50,6 +52,25 @@ async def dshell_read_file(ctx: Message, file: FileNode) -> StrNode:
50
52
 
51
53
  return StrNode(file.read())
52
54
 
55
+ async def dshell_stream_file(ctx: Message, file: FileNode, separator: Optional[StrNode] = None) -> FileStreamNode:
56
+ """
57
+ Stream le contenue d'un fichier. Si un séparateur est passé en paramètre,
58
+ le stream s'arrêtera à chaque fois que le séparateur est rencontré, sinon il streamera ligne par ligne
59
+ (MAX_STR_SIZE de la str max renvoyé)
60
+ :param ctx:
61
+ :param file:
62
+ :param separator:
63
+ :return:
64
+ """
65
+
66
+ _validate_optional_string(separator, 'separator', 'sf')
67
+
68
+ if separator is not None and len(separator) > 1:
69
+ raise Exception(f"Separator in stream file must be a single character, not '{separator}' !")
70
+
71
+ return file.stream(separator)
72
+
73
+
53
74
  async def dshell_write_file(ctx: Message,
54
75
  message: StrNode,
55
76
  append: BoolNode = BoolNode(False),
@@ -3,7 +3,7 @@ from ..DshellTokenizer.dshell_token_type import DshellTokenType as DTT
3
3
  from ..DshellInterpreteur.errors import DshellInterpreterStopExecution
4
4
  from Dshell.full_import import TypeVar, Union, Optional, Any, Callable, sleep, findall
5
5
  from ..DshellParser.ast_nodes import *
6
- from Dshell.full_import import AutoShardedBot, Interaction, Message, PrivateChannel, Embed
6
+ from Dshell.full_import import AutoShardedBot, Interaction, Message, PrivateChannel
7
7
  from ..DshellParser.dshell_parser import parse, print_ast
8
8
  from ..DshellTokenizer.dshell_tokenizer import DshellTokenizer
9
9
  from .cached_messages import dshell_cached_messages
@@ -71,7 +71,7 @@ class DshellInterpreteur:
71
71
  '__message_before__': StrNode(message.content), # same as __message__, but before edit. Can be overwritten by add vars_env parameter
72
72
  '__message_created_at__': StrNode(message.created_at),
73
73
  '__message_edited_at__': StrNode(message.edited_at),
74
- '__message_reactions__': ListNode([StrNode(reaction.emoji) for reaction in message.reactions], bypass_limit_elt=True),
74
+ '__message_reactions__': ListNode([StrNode(reaction.emoji) for reaction in message.reactions], bypass_limit_elt=True, editable=False),
75
75
  '__message_add_reaction__': None, # Can be overwritten by add vars_env parameter to get the reaction added on message add event reaction
76
76
  '__message_remove_reaction__': None, # Can be overwritten by add vars_env parameter to get the reaction removed on message remove event reaction
77
77
  '__message_url__': StrNode(message.jump_url) if hasattr(message, 'jump_url') else None,
@@ -86,21 +86,21 @@ class DshellInterpreteur:
86
86
  '__guild__': IntNode(message.channel.guild.id),
87
87
  '__guild_name__': StrNode(message.channel.guild.name),
88
88
  '__guild_id__': IntNode(message.channel.guild.id),
89
- '__guild_members__': ListNode([IntNode(member.id) for member in message.channel.guild.members], bypass_limit_elt=True),
89
+ '__guild_members__': ListNode([IntNode(member.id) for member in message.channel.guild.members], bypass_limit_elt=True, editable=False),
90
90
  '__guild_member_count__': IntNode(message.channel.guild.member_count),
91
91
  '__guild_icon__': StrNode(message.channel.guild.icon.url) if message.channel.guild.icon else None,
92
92
  '__guild_owner_id__': IntNode(message.channel.guild.owner_id),
93
93
  '__guild_description__': StrNode(message.channel.guild.description),
94
- '__guild_roles__': ListNode([IntNode(role.id) for role in message.channel.guild.roles], bypass_limit_elt=True),
94
+ '__guild_roles__': ListNode([IntNode(role.id) for role in message.channel.guild.roles], bypass_limit_elt=True, editable=False),
95
95
  '__guild_roles_count__': IntNode(len(message.channel.guild.roles)),
96
- '__guild_emojis__': ListNode([IntNode(emoji.id) for emoji in message.channel.guild.emojis], bypass_limit_elt=True),
96
+ '__guild_emojis__': ListNode([IntNode(emoji.id) for emoji in message.channel.guild.emojis], bypass_limit_elt=True, editable=False),
97
97
  '__guild_emojis_count__': IntNode(len(message.channel.guild.emojis)),
98
- '__guild_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.channels], bypass_limit_elt=True),
99
- '__guild_text_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.text_channels], bypass_limit_elt=True),
100
- '__guild_voice_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.voice_channels], bypass_limit_elt=True),
101
- '__guild_categories__': ListNode([IntNode(channel.id) for channel in message.channel.guild.categories], bypass_limit_elt=True),
102
- '__guild_stage_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.stage_channels], bypass_limit_elt=True),
103
- '__guild_forum_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.forum_channels], bypass_limit_elt=True),
98
+ '__guild_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.channels], bypass_limit_elt=True, editable=False),
99
+ '__guild_text_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.text_channels], bypass_limit_elt=True, editable=False),
100
+ '__guild_voice_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.voice_channels], bypass_limit_elt=True, editable=False),
101
+ '__guild_categories__': ListNode([IntNode(channel.id) for channel in message.channel.guild.categories], bypass_limit_elt=True, editable=False),
102
+ '__guild_stage_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.stage_channels], bypass_limit_elt=True, editable=False),
103
+ '__guild_forum_channels__': ListNode([IntNode(channel.id) for channel in message.channel.guild.forum_channels], bypass_limit_elt=True, editable=False),
104
104
  '__guild_channels_count__': IntNode(len(message.channel.guild.channels)),
105
105
 
106
106
  } if message is not None and not debug else {'__ret__': None}) # {} is used in debug mode, when ctx is None
@@ -150,6 +150,7 @@ class DshellInterpreteur:
150
150
  self.env.set(node.variable.name.value, i)
151
151
  await self.execute(node.body)
152
152
 
153
+
153
154
  async def _execute_var_node(self, node: VarNode):
154
155
  """Execute a variable assignment node."""
155
156
  first_node = node.body[0]
@@ -353,19 +354,43 @@ class DshellIterator:
353
354
  """
354
355
 
355
356
  def __init__(self, data):
356
- self.data = data if isinstance(data, (StrNode, list, ListNode)) else range(int(data))
357
+ self.data = self._check_data(data)
357
358
  self.current = 0
358
359
 
359
360
  def __iter__(self):
360
361
  return self
361
362
 
362
363
  def __next__(self):
363
- if self.current >= len(self.data):
364
- self.current = 0
365
- raise StopIteration
364
+ return next(self.data)
365
+
366
+ def _check_data(self, data: Any):
367
+
368
+ if not isinstance(data, (StrNode, ListNode, FloatNode, IntNode, FileNode, FileStreamNode)):
369
+ raise Exception(f"{data} can't be in a loop !")
370
+
371
+ if isinstance(data, FileNode):
372
+ return data.stream()
373
+
374
+ elif isinstance(data, (FloatNode, IntNode)):
375
+ return IntIterator(IntNode(data))
366
376
 
367
- value = self.data[self.current]
368
- self.current += 1
369
- return value
377
+ else:
378
+ return data
379
+
380
+ class IntIterator:
381
+
382
+ def __init__(self, max_iterator: IntNode):
383
+ self.max_iterator = max_iterator
384
+ self.pointer = IntNode(0)
370
385
 
386
+ def __iter__(self) -> "IntIterator":
387
+ return self
388
+
389
+ def __next__(self) -> IntNode:
390
+ if self.pointer >= self.max_iterator:
391
+ self.pointer = IntNode(0)
392
+ raise StopIteration
371
393
 
394
+ current = self.pointer
395
+ self.pointer += 1
396
+ return current
@@ -1,6 +1,7 @@
1
1
  from Dshell.full_import import (Any, randint, Optional, Union, Embed, Member, Role, PermissionOverwrite)
2
2
  from ..DshellTokenizer.dshell_token_type import Token
3
3
  from ..DshellInterpreteur.dshell_global_variables import MAX_STR_SIZE, MAX_LIST_SIZE, MAX_FILE_SIZE
4
+ from .errors import *
4
5
 
5
6
  from sys import getsizeof
6
7
 
@@ -36,7 +37,8 @@ __all__ = [
36
37
  'UiSelectNode',
37
38
  'OptionUiSelectNode',
38
39
  'ScanNode',
39
- 'FileNode'
40
+ 'FileNode',
41
+ 'FileStreamNode'
40
42
  ]
41
43
 
42
44
 
@@ -54,8 +56,17 @@ class ASTNode:
54
56
  class StrNode(str, ASTNode):
55
57
 
56
58
  def __new__(cls, value: Any):
59
+ cls.pointer = 0
57
60
  return super().__new__(cls, value)
58
61
 
62
+ def __next__(self):
63
+ if self.pointer >= len(self):
64
+ raise StopIteration
65
+
66
+ current = self[self.pointer]
67
+ self.pointer += 1
68
+ return current
69
+
59
70
  def __len__(self):
60
71
  return IntNode(super().__len__())
61
72
 
@@ -802,6 +813,10 @@ class FileNode(ASTNode):
802
813
  def read(self):
803
814
  return self.content.decode(encoding="utf-8", errors="ignore")
804
815
 
816
+ def stream(self, separator: Optional[StrNode] = None):
817
+ return FileStreamNode(self, separator)
818
+
819
+
805
820
  def size(self):
806
821
  return len(self.read())
807
822
 
@@ -811,6 +826,50 @@ class FileNode(ASTNode):
811
826
  def __sizeof__(self):
812
827
  return self.size()+getsizeof(FileNode)
813
828
 
829
+ class FileStreamNode(ASTNode):
830
+
831
+ def __init__(self, file: FileNode, separator: Optional[StrNode] = None):
832
+ super().__init__(-1)
833
+ self.file: FileNode = file
834
+ self.content: str = file.read()
835
+ self.separator: Optional[StrNode] = separator
836
+ self.pointer: int = 0
837
+
838
+ def __iter__(self):
839
+ return self
840
+
841
+ def __next__(self):
842
+
843
+ if self.pointer >= len(self.content):
844
+ self.pointer = 0
845
+ raise StopIteration()
846
+
847
+ buffer = ""
848
+
849
+ if self.separator is None:
850
+
851
+ while self.pointer < len(self.content) and self.content[self.pointer] != "\n":
852
+ if len(buffer.encode('utf-8', errors="ignore")) + len(
853
+ self.content[self.pointer].encode('utf-8', errors="ignore")) > MAX_STR_SIZE:
854
+ return StrNode(buffer)
855
+
856
+ buffer += self.content[self.pointer]
857
+ self.pointer += 1
858
+
859
+ self.pointer += 1 # Skip the newline character
860
+ return StrNode(buffer)
861
+
862
+ while self.pointer < len(self.content) and self.content[self.pointer] != self.separator:
863
+ if len(buffer.encode('utf-8', errors="ignore")) + len(
864
+ self.content[self.pointer].encode('utf-8', errors="ignore")) > MAX_STR_SIZE:
865
+ return StrNode(buffer)
866
+
867
+ buffer += self.content[self.pointer]
868
+ self.pointer += 1
869
+ self.pointer += 1 # Skip the newline character
870
+ return StrNode(buffer)
871
+
872
+
814
873
  class ListNode(ASTNode):
815
874
  """
816
875
  Node representing a list structure in the AST.
@@ -818,7 +877,7 @@ class ListNode(ASTNode):
818
877
  This class also lets you interact with the list via specific methods not built in by python.
819
878
  """
820
879
 
821
- def __init__(self, body: list[Any], bypass_limit_elt: bool = False):
880
+ def __init__(self, body: list[Any], bypass_limit_elt: bool = False, editable: bool = True):
822
881
  """
823
882
  :param body: list of elements to initialize the ListNode with
824
883
  """
@@ -828,6 +887,7 @@ class ListNode(ASTNode):
828
887
  self.iterator_count: int = 0
829
888
  self.size: int = 0
830
889
  self.bypass_limit_elt: bool = bypass_limit_elt
890
+ self.editable: bool = editable
831
891
  for i in body:
832
892
  self.add(i)
833
893
 
@@ -861,6 +921,9 @@ class ListNode(ASTNode):
861
921
  """
862
922
  Add a value to the list.
863
923
  """
924
+ if not self.editable:
925
+ raise ListNotEditableError()
926
+
864
927
  if not self.bypass_limit_elt and self.len_iterable > 1000:
865
928
  raise PermissionError('The list is too long, it must not exceed 1000 elements !')
866
929
 
@@ -875,6 +938,9 @@ class ListNode(ASTNode):
875
938
  """
876
939
  Remove a value from the list.
877
940
  """
941
+ if not self.editable:
942
+ raise ListNotEditableError()
943
+
878
944
  if number < 1:
879
945
  raise Exception(f"The number of elements to remove must be at least 1, not {number} !")
880
946
 
@@ -893,6 +959,9 @@ class ListNode(ASTNode):
893
959
  Remove and return the last element of the list.
894
960
  :return: The last element of the list.
895
961
  """
962
+ if not self.editable:
963
+ raise ListNotEditableError()
964
+
896
965
  if self.len_iterable == 0:
897
966
  raise IndexError("pop from empty list")
898
967
  if 0 > index >= self.len_iterable or -self.len_iterable > index < 0:
@@ -908,6 +977,9 @@ class ListNode(ASTNode):
908
977
  :param index: The index at which to set the value.
909
978
  :param value: The value to set at the specified index.
910
979
  """
980
+ if not self.editable:
981
+ raise ListNotEditableError()
982
+
911
983
  if 0 > index >= self.len_iterable or -self.len_iterable > index < 0:
912
984
  raise IndexError("set index out of range")
913
985
 
@@ -926,6 +998,9 @@ class ListNode(ASTNode):
926
998
  """
927
999
  Clear the list.
928
1000
  """
1001
+ if not self.editable:
1002
+ raise ListNotEditableError()
1003
+
929
1004
  self.iterable = []
930
1005
  self.len_iterable = 0
931
1006
  self.iterator_count = 0
@@ -0,0 +1,8 @@
1
+ class AstNodeError(Exception):
2
+ """Base class for exceptions in this module."""
3
+ pass
4
+
5
+ class ListNotEditableError(AstNodeError):
6
+
7
+ def __init__(self):
8
+ super().__init__("This list is not editable, you can't modify it !")
@@ -85,6 +85,7 @@ dshell_commands: dict[str, Callable] = {
85
85
 
86
86
  ## Files
87
87
  "rf": dshell_read_file,
88
+ "sf": dshell_stream_file,
88
89
  "wf": dshell_write_file,
89
90
  "gmfs": dshell_get_message_files,
90
91
 
@@ -1,5 +1,5 @@
1
1
  from asyncio import sleep
2
- from typing import TypeVar, Optional, Callable, Union, Any, TYPE_CHECKING
2
+ from typing import *
3
3
  from copy import deepcopy
4
4
  from pycordViews import EasyModifiedViews, SelectMenu
5
5
  from pycordViews.views.errors import CustomIDNotFound
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dshellInterpreter
3
- Version: 1.2.0.4
3
+ Version: 1.2.0.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dshellInterpreter
3
- Version: 1.2.0.4
3
+ Version: 1.2.0.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
@@ -37,6 +37,7 @@ Dshell/DshellInterpreteur/utils_interpreter.py
37
37
  Dshell/DshellParser/__init__.py
38
38
  Dshell/DshellParser/ast_nodes.py
39
39
  Dshell/DshellParser/dshell_parser.py
40
+ Dshell/DshellParser/errors.py
40
41
  Dshell/DshellPreProcess/__init__.py
41
42
  Dshell/DshellPreProcess/dshell_preprocess.py
42
43
  Dshell/DshellTokenizer/__init__.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name="dshellInterpreter",
8
- version="1.2.0.4",
8
+ version="1.2.0.6",
9
9
  author="Chronos",
10
10
  author_email="vagabonwalybi@gmail.com",
11
11
  description="A Discord bot interpreter for creating custom commands and automations.",