IncludeCPP 3.3.20__py3-none-any.whl → 3.4.8__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.
@@ -25,6 +25,65 @@ def _safe_get(lst: List[Any], index: int, default: Any = None) -> Any:
25
25
  return default
26
26
 
27
27
 
28
+ # v3.3.22: Python reserved keywords - names that need escaping when used as identifiers
29
+ PYTHON_KEYWORDS = {
30
+ 'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await',
31
+ 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except',
32
+ 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is',
33
+ 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try',
34
+ 'while', 'with', 'yield'
35
+ }
36
+
37
+ # v3.4.1: C++ reserved words that need escaping when used as Python identifiers
38
+ # These are C++ types/keywords that are valid Python identifiers but confusing
39
+ CPP_RESERVED_WORDS = {
40
+ # Primitive types
41
+ 'int', 'float', 'double', 'char', 'bool', 'void', 'auto',
42
+ 'short', 'long', 'signed', 'unsigned', 'wchar_t',
43
+ # Type modifiers
44
+ 'const', 'static', 'virtual', 'volatile', 'mutable', 'extern',
45
+ 'register', 'inline', 'explicit', 'constexpr', 'consteval',
46
+ # Access modifiers
47
+ 'public', 'private', 'protected',
48
+ # Other keywords
49
+ 'template', 'typename', 'namespace', 'using', 'typedef',
50
+ 'struct', 'union', 'enum', 'sizeof', 'alignof', 'decltype',
51
+ 'new', 'delete', 'operator', 'friend', 'this',
52
+ 'throw', 'catch', 'noexcept', 'final', 'override',
53
+ }
54
+
55
+
56
+ def _escape_python_keyword(name: str) -> str:
57
+ """Escape Python reserved keywords by adding underscore suffix.
58
+
59
+ Example: 'class' -> 'class_', 'def' -> 'def_', 'import' -> 'import_'
60
+ """
61
+ if name in PYTHON_KEYWORDS:
62
+ return name + '_'
63
+ return name
64
+
65
+
66
+ def _escape_cpp_reserved(name: str) -> str:
67
+ """Escape C++ reserved words when used as Python identifiers.
68
+
69
+ Example: 'double' -> 'double_', 'int' -> 'int_', 'void' -> 'void_'
70
+ v3.4.1: Prevents C++ type names from being used as Python function/variable names.
71
+ """
72
+ if name in CPP_RESERVED_WORDS:
73
+ return name + '_'
74
+ return name
75
+
76
+
77
+ def _escape_identifier(name: str) -> str:
78
+ """Escape both Python keywords and C++ reserved words.
79
+
80
+ Combines both escaping functions for comprehensive identifier safety.
81
+ """
82
+ name = _escape_python_keyword(name)
83
+ name = _escape_cpp_reserved(name)
84
+ return name
85
+
86
+
28
87
  # Python type to C++ type mapping
29
88
  PY_TO_CPP_TYPES = {
30
89
  'int': 'int',
@@ -2205,11 +2264,31 @@ class CppToPythonConverter:
2205
2264
 
2206
2265
  def _parse_class_fields(self, body: str) -> List[Tuple[str, str, Optional[str]]]:
2207
2266
  fields = []
2267
+ all_field_names = set() # v3.4.1: Track ALL fields for self. prefix
2208
2268
 
2269
+ # v3.4.1: Parse fields from ALL sections (public, private, protected)
2270
+ # for self. prefix detection, but only return public fields for dataclass
2209
2271
  sections = re.split(r'(?:public|private|protected)\s*:', body)
2210
- public_section = sections[1] if len(sections) > 1 else body
2211
2272
 
2212
2273
  field_pattern = r'(\w+(?:<[^>]+>)?)\s+(\w+)\s*(?:=\s*([^;]+))?\s*;'
2274
+
2275
+ # First pass: collect ALL field names from all sections
2276
+ for section in sections:
2277
+ for match in re.finditer(field_pattern, section):
2278
+ field_type = match.group(1)
2279
+ field_name = match.group(2)
2280
+
2281
+ if '(' in field_type or field_type in ('return', 'if', 'for', 'while'):
2282
+ continue
2283
+
2284
+ all_field_names.add(field_name)
2285
+
2286
+ # Store all field names for self. prefix detection
2287
+ self._current_class_fields = all_field_names
2288
+
2289
+ # Second pass: return only public fields for the Python class definition
2290
+ public_section = sections[1] if len(sections) > 1 else body
2291
+
2213
2292
  for match in re.finditer(field_pattern, public_section):
2214
2293
  field_type = match.group(1)
2215
2294
  field_name = match.group(2)
@@ -2500,18 +2579,20 @@ class CppToPythonConverter:
2500
2579
  if var_name not in ('if', 'for', 'while', 'return'):
2501
2580
  return f'{var_name} = {self._get_default_value(var_type)}'
2502
2581
 
2503
- # Assignment
2504
- assign_match = re.match(r'(\w+(?:\.\w+)*(?:\[[^\]]+\])?)\s*=\s*(.+)$', stmt)
2582
+ # Assignment - v3.3.22: Expanded pattern to capture -> and ::
2583
+ assign_match = re.match(r'([a-zA-Z_][\w:>-]*(?:->|\.)?[a-zA-Z_][\w]*(?:\[[^\]]+\])?)\s*=\s*(.+)$', stmt)
2505
2584
  if assign_match:
2506
2585
  target = assign_match.group(1)
2507
- target = target.replace('this->', 'self.')
2586
+ # v3.3.22: Apply full expression conversion to target as well
2587
+ target = self._convert_cpp_expr(target)
2508
2588
  value = self._convert_cpp_expr(assign_match.group(2))
2509
2589
  return f'{target} = {value}'
2510
2590
 
2511
2591
  # Augmented assignment
2512
2592
  aug_match = re.match(r'(\w+(?:\.\w+)*)\s*(\+\+|--|\+=|-=|\*=|/=)', stmt)
2513
2593
  if aug_match:
2514
- target = aug_match.group(1).replace('this->', 'self.')
2594
+ # v3.3.22: Apply full expression conversion to target
2595
+ target = self._convert_cpp_expr(aug_match.group(1))
2515
2596
  op = aug_match.group(2)
2516
2597
  if op == '++':
2517
2598
  return f'{target} += 1'
@@ -2572,13 +2653,30 @@ class CppToPythonConverter:
2572
2653
  expr = re.sub(r'std::max\(([^,]+),\s*([^)]+)\)', r'max(\1, \2)', expr)
2573
2654
 
2574
2655
  # Handle std::accumulate(container.begin(), container.end(), init) -> sum(container) [+ init]
2656
+ # v3.4.1: Also handle accumulate without std:: prefix
2575
2657
  def _accumulate_to_sum(m):
2576
2658
  container = m.group(1)
2577
2659
  init_val = m.group(2).strip()
2578
2660
  if init_val == '0' or init_val == '0.0':
2579
2661
  return f'sum({container})'
2580
2662
  return f'sum({container}) + {init_val}'
2581
- expr = re.sub(r'std::accumulate\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)', _accumulate_to_sum, expr)
2663
+ expr = re.sub(r'(?:std::)?accumulate\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)', _accumulate_to_sum, expr)
2664
+
2665
+ # v3.4.1: Handle std::find, std::count, std::sort with .begin()/.end()
2666
+ # std::find(vec.begin(), vec.end(), val) -> val in vec
2667
+ expr = re.sub(r'(?:std::)?find\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)\s*!=\s*\1\.end\(\)', r'\2 in \1', expr)
2668
+ # std::count(vec.begin(), vec.end(), val) -> vec.count(val)
2669
+ expr = re.sub(r'(?:std::)?count\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)', r'\1.count(\2)', expr)
2670
+ # std::sort(vec.begin(), vec.end()) -> vec.sort()
2671
+ expr = re.sub(r'(?:std::)?sort\((\w+)\.begin\(\),\s*\1\.end\(\)\)', r'\1.sort()', expr)
2672
+ # std::reverse(vec.begin(), vec.end()) -> vec.reverse()
2673
+ expr = re.sub(r'(?:std::)?reverse\((\w+)\.begin\(\),\s*\1\.end\(\)\)', r'\1.reverse()', expr)
2674
+
2675
+ # v3.4.1: Clean up any remaining .begin()/.end() that couldn't be converted
2676
+ # container.begin() -> iter(container) for iteration context
2677
+ # But typically these are errors - flag as comment if they remain
2678
+ expr = re.sub(r'(\w+)\.begin\(\)', r'\1[0]', expr) # Approximate as first element
2679
+ expr = re.sub(r'(\w+)\.end\(\)', r'len(\1)', expr) # Approximate as length
2582
2680
 
2583
2681
  # Handle .size() -> len()
2584
2682
  expr = re.sub(r'(\w+)\.size\(\)', r'len(\1)', expr)
@@ -2617,33 +2715,53 @@ class CppToPythonConverter:
2617
2715
  # Handle negation !
2618
2716
  expr = re.sub(r'!(\w)', r'not \1', expr)
2619
2717
 
2620
- # Add self. prefix for class member access (when not already prefixed)
2718
+ # v3.3.22: Add self. prefix for class member access (when not already prefixed)
2621
2719
  if self._current_class_fields:
2622
2720
  for field in self._current_class_fields:
2623
2721
  # Match field name that's not already prefixed with self. or another identifier
2624
- expr = re.sub(rf'(?<![.\w])(?<!self\.){re.escape(field)}(?=\s*[=,)\];\s]|$)', f'self.{field}', expr)
2722
+ # Fixed lookahead to be more permissive - match non-word chars or end
2723
+ expr = re.sub(rf'(?<![.\w])(?<!self\.){re.escape(field)}(?=\W|$)', f'self.{field}', expr)
2724
+
2725
+ # v3.4.1: Handle common C++ member naming conventions
2726
+ # Convert m_name to self.name when in class context
2727
+ if self._current_class_fields:
2728
+ # Convert m_xxx to self.xxx
2729
+ expr = re.sub(r'(?<![.\w])m_(\w+)(?=\W|$)', r'self.\1', expr)
2730
+ # Convert _xxx to self.xxx (leading underscore)
2731
+ expr = re.sub(r'(?<![.\w])_(\w+)(?=\W|$)', r'self.\1', expr)
2732
+ # v3.4.1: Convert xxx_ to self.xxx_ (trailing underscore - Google style)
2733
+ # Only if it's a known field or matches the pattern
2734
+ for field in self._current_class_fields:
2735
+ if field.endswith('_') and field not in ('self_',):
2736
+ expr = re.sub(rf'(?<![.\w]){re.escape(field)}(?=\W|$)', f'self.{field}', expr)
2625
2737
 
2626
2738
  return expr
2627
2739
 
2628
2740
  def _generate_struct(self, struct: StructInfo) -> List[str]:
2629
2741
  lines = ['@dataclass']
2630
- lines.append(f'class {struct.name}:')
2742
+ # v3.4.1: Escape Python keywords and C++ reserved words in struct/class names
2743
+ struct_name = _escape_identifier(struct.name)
2744
+ lines.append(f'class {struct_name}:')
2631
2745
 
2632
2746
  if not struct.fields:
2633
2747
  lines.append(f'{self.indent}pass')
2634
2748
  else:
2635
2749
  for fname, ftype in struct.fields:
2636
- lines.append(f'{self.indent}{fname}: {ftype}')
2750
+ # v3.4.1: Escape Python keywords and C++ reserved words in field names
2751
+ escaped_fname = _escape_identifier(fname)
2752
+ lines.append(f'{self.indent}{escaped_fname}: {ftype}')
2637
2753
 
2638
2754
  return lines
2639
2755
 
2640
2756
  def _generate_class(self, cls: ClassInfo) -> List[str]:
2641
2757
  lines = []
2642
2758
 
2759
+ # v3.4.1: Escape Python keywords and C++ reserved words in class names
2760
+ class_name = _escape_identifier(cls.name)
2643
2761
  if cls.bases:
2644
- lines.append(f'class {cls.name}({", ".join(cls.bases)}):')
2762
+ lines.append(f'class {class_name}({", ".join(cls.bases)}):')
2645
2763
  else:
2646
- lines.append(f'class {cls.name}:')
2764
+ lines.append(f'class {class_name}:')
2647
2765
 
2648
2766
  if not cls.fields and not cls.methods and not cls.constructors:
2649
2767
  lines.append(f'{self.indent}pass')
@@ -2665,16 +2783,19 @@ class CppToPythonConverter:
2665
2783
 
2666
2784
  params = ['self'] if not method.is_static else []
2667
2785
  for pname, ptype in method.params:
2786
+ # v3.4.1: Escape Python keywords and C++ reserved words in parameter names
2787
+ escaped_pname = _escape_identifier(pname)
2668
2788
  if ptype and ptype != 'Any':
2669
- params.append(f'{pname}: {ptype}')
2789
+ params.append(f'{escaped_pname}: {ptype}')
2670
2790
  else:
2671
- params.append(pname)
2791
+ params.append(escaped_pname)
2672
2792
 
2673
2793
  ret_type = ''
2674
2794
  if not is_init and method.return_type and method.return_type != 'None':
2675
2795
  ret_type = f' -> {method.return_type}'
2676
2796
 
2677
- method_name = '__init__' if is_init else method.name
2797
+ # v3.4.1: Escape Python keywords and C++ reserved words in method names
2798
+ method_name = '__init__' if is_init else _escape_identifier(method.name)
2678
2799
  lines.append(f'{self.indent}def {method_name}({", ".join(params)}){ret_type}:')
2679
2800
 
2680
2801
  body_lines = method.body.split('\n')
@@ -2691,16 +2812,20 @@ class CppToPythonConverter:
2691
2812
 
2692
2813
  params = []
2693
2814
  for pname, ptype in func.params:
2815
+ # v3.4.1: Escape Python keywords and C++ reserved words in parameter names
2816
+ escaped_pname = _escape_identifier(pname)
2694
2817
  if ptype and ptype != 'Any':
2695
- params.append(f'{pname}: {ptype}')
2818
+ params.append(f'{escaped_pname}: {ptype}')
2696
2819
  else:
2697
- params.append(pname)
2820
+ params.append(escaped_pname)
2698
2821
 
2699
2822
  ret_type = ''
2700
2823
  if func.return_type and func.return_type != 'None':
2701
2824
  ret_type = f' -> {func.return_type}'
2702
2825
 
2703
- lines.append(f'def {func.name}({", ".join(params)}){ret_type}:')
2826
+ # v3.4.1: Escape Python keywords and C++ reserved words in function names
2827
+ func_name = _escape_identifier(func.name)
2828
+ lines.append(f'def {func_name}({", ".join(params)}){ret_type}:')
2704
2829
 
2705
2830
  body_lines = func.body.split('\n')
2706
2831
  if body_lines and body_lines[0].strip():
@@ -0,0 +1,40 @@
1
+ """
2
+ CSSL - CSO Service Script Language
3
+ Bundled with IncludeCPP for integrated scripting support.
4
+
5
+ Features:
6
+ - BruteForce Injection System: <==, ==>, +<==, -<==, <<==, ==>>
7
+ - Dynamic typing with 'dynamic' keyword
8
+ - Function modifiers: undefined, open, meta, super, closed, private, virtual
9
+ - Advanced data types: datastruct, shuffled, iterator, combo, dataspace
10
+ - Injection helpers: string::where, json::key, array::index, etc.
11
+ - Global references: @Name, r@Name, s@Name
12
+ """
13
+
14
+ from .cssl_parser import (
15
+ parse_cssl, parse_cssl_program, tokenize_cssl,
16
+ CSSLSyntaxError, CSSLLexer, CSSLParser, ASTNode,
17
+ KEYWORDS, TYPE_GENERICS, INJECTION_HELPERS
18
+ )
19
+ from .cssl_runtime import CSSLRuntime, CSSLRuntimeError, CSSLServiceRunner, run_cssl, run_cssl_file
20
+ from .cssl_types import (
21
+ DataStruct, Shuffled, Iterator, Combo, DataSpace, OpenQuote,
22
+ OpenFind, Parameter,
23
+ create_datastruct, create_shuffled, create_iterator,
24
+ create_combo, create_dataspace, create_openquote, create_parameter
25
+ )
26
+
27
+ __all__ = [
28
+ # Parser
29
+ 'parse_cssl', 'parse_cssl_program', 'tokenize_cssl',
30
+ 'CSSLSyntaxError', 'CSSLLexer', 'CSSLParser', 'ASTNode',
31
+ 'KEYWORDS', 'TYPE_GENERICS', 'INJECTION_HELPERS',
32
+ # Runtime
33
+ 'CSSLRuntime', 'CSSLRuntimeError', 'CSSLServiceRunner',
34
+ 'run_cssl', 'run_cssl_file',
35
+ # Data Types
36
+ 'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
37
+ 'OpenFind', 'Parameter',
38
+ 'create_datastruct', 'create_shuffled', 'create_iterator',
39
+ 'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter'
40
+ ]