IncludeCPP 3.7.25__py3-none-any.whl → 3.8.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.
@@ -205,6 +205,13 @@ class CSSLBuiltins:
205
205
  self._functions['isavailable'] = self.builtin_isavailable
206
206
  self._functions['instance::exists'] = self.builtin_isavailable # Alias
207
207
 
208
+ # Python interop functions
209
+ self._functions['python::pythonize'] = self.builtin_python_pythonize
210
+ self._functions['python::wrap'] = self.builtin_python_pythonize # Alias
211
+ self._functions['python::export'] = self.builtin_python_pythonize # Alias
212
+ self._functions['python::csslize'] = self.builtin_python_csslize
213
+ self._functions['python::import'] = self.builtin_python_csslize # Alias
214
+
208
215
  # Regex functions
209
216
  self._functions['match'] = self.builtin_match
210
217
  self._functions['search'] = self.builtin_search
@@ -2445,6 +2452,342 @@ class CSSLBuiltins:
2445
2452
 
2446
2453
  return None
2447
2454
 
2455
+ # ============= Python Interop Functions =============
2456
+
2457
+ def builtin_python_pythonize(self, cssl_instance: Any) -> Any:
2458
+ """Convert a CSSL class instance to a Python-usable object.
2459
+
2460
+ This allows CSSL classes to be returned and used in Python code
2461
+ with proper attribute access and method calls.
2462
+
2463
+ Usage in CSSL:
2464
+ class Greeter {
2465
+ string name;
2466
+
2467
+ Greeter(string n) {
2468
+ this->name = n;
2469
+ }
2470
+
2471
+ string sayHello() {
2472
+ return "Hello, " + this->name + "!";
2473
+ }
2474
+
2475
+ void setName(string newName) {
2476
+ this->name = newName;
2477
+ }
2478
+
2479
+ string getName() {
2480
+ return this->name;
2481
+ }
2482
+ }
2483
+
2484
+ greeter = new Greeter("World");
2485
+ pyclass = python::pythonize(greeter);
2486
+ parameter.return(pyclass);
2487
+
2488
+ Usage in Python:
2489
+ from includecpp import CSSL
2490
+
2491
+ cssl = CSSL.CsslLang()
2492
+ greeter = cssl.run('''
2493
+ class Greeter { ... }
2494
+ g = new Greeter("World");
2495
+ parameter.return(python::pythonize(g));
2496
+ ''')
2497
+
2498
+ # Now use it like a normal Python object:
2499
+ print(greeter.name) # "World"
2500
+ print(greeter.sayHello()) # "Hello, World!"
2501
+ greeter.setName("Python")
2502
+ print(greeter.getName()) # "Python"
2503
+
2504
+ Args:
2505
+ cssl_instance: A CSSLInstance object (created via 'new ClassName()')
2506
+
2507
+ Returns:
2508
+ PythonizedCSSLInstance - A Python-friendly wrapper
2509
+ """
2510
+ from .cssl_types import CSSLInstance, CSSLClass
2511
+
2512
+ if cssl_instance is None:
2513
+ return None
2514
+
2515
+ # Already pythonized
2516
+ if isinstance(cssl_instance, PythonizedCSSLInstance):
2517
+ return cssl_instance
2518
+
2519
+ # Must be a CSSLInstance
2520
+ if not isinstance(cssl_instance, CSSLInstance):
2521
+ # If it's a dict, wrap it as a simple object
2522
+ if isinstance(cssl_instance, dict):
2523
+ return PythonizedDict(cssl_instance)
2524
+ # Return as-is for primitives
2525
+ return cssl_instance
2526
+
2527
+ return PythonizedCSSLInstance(cssl_instance, self.runtime)
2528
+
2529
+ def builtin_python_csslize(self, python_obj: Any) -> Any:
2530
+ """Convert a Python object (class instance or function) to a CSSL-compatible wrapper.
2531
+
2532
+ Syntax:
2533
+ cssl_obj <== python::csslize($python_instance);
2534
+ cssl_func <== python::csslize($python_function);
2535
+
2536
+ Example:
2537
+ # In Python:
2538
+ class MyPythonClass:
2539
+ def __init__(self, name):
2540
+ self.name = name
2541
+ def greet(self):
2542
+ return f"Hello, {self.name}!"
2543
+
2544
+ cssl = CSSL.CsslLang()
2545
+ cssl.set_variable('MyPython', MyPythonClass("World"))
2546
+ result = cssl.run('''
2547
+ py_obj <== python::csslize($MyPython);
2548
+ printl(py_obj.greet()); // "Hello, World!"
2549
+ ''')
2550
+
2551
+ For class inheritance:
2552
+ py_class <== python::csslize($MyPythonClass);
2553
+ class MyExtended : extends py_class {
2554
+ void newMethod() { ... }
2555
+ }
2556
+
2557
+ Args:
2558
+ python_obj: A Python object (class instance, function, or class)
2559
+
2560
+ Returns:
2561
+ CSSLizedPythonObject - A CSSL-compatible wrapper
2562
+ """
2563
+ if python_obj is None:
2564
+ return None
2565
+
2566
+ # Already csslized
2567
+ if isinstance(python_obj, CSSLizedPythonObject):
2568
+ return python_obj
2569
+
2570
+ # Wrap the Python object
2571
+ return CSSLizedPythonObject(python_obj, self.runtime)
2572
+
2573
+
2574
+ class CSSLizedPythonObject:
2575
+ """CSSL wrapper for Python objects (classes, instances, functions).
2576
+
2577
+ Allows Python objects to be used within CSSL code, including as base classes.
2578
+ """
2579
+
2580
+ def __init__(self, python_obj: Any, runtime: Any = None):
2581
+ self._python_obj = python_obj
2582
+ self._runtime = runtime
2583
+ self._is_class = isinstance(python_obj, type)
2584
+ self._is_callable = callable(python_obj) and not self._is_class
2585
+
2586
+ def __repr__(self):
2587
+ if self._is_class:
2588
+ return f"<CSSLizedPythonClass: {self._python_obj.__name__}>"
2589
+ elif self._is_callable:
2590
+ return f"<CSSLizedPythonFunction: {getattr(self._python_obj, '__name__', 'anonymous')}>"
2591
+ else:
2592
+ return f"<CSSLizedPythonInstance: {type(self._python_obj).__name__}>"
2593
+
2594
+ def __call__(self, *args, **kwargs):
2595
+ """Call the wrapped object (for functions or class instantiation)."""
2596
+ return self._python_obj(*args, **kwargs)
2597
+
2598
+ def __getattr__(self, name: str) -> Any:
2599
+ """Get attribute from wrapped Python object."""
2600
+ if name.startswith('_'):
2601
+ raise AttributeError(f"Cannot access private attribute '{name}'")
2602
+
2603
+ obj = object.__getattribute__(self, '_python_obj')
2604
+
2605
+ if hasattr(obj, name):
2606
+ attr = getattr(obj, name)
2607
+ # If it's a method, wrap it for CSSL calling
2608
+ if callable(attr):
2609
+ return CSSLizedPythonMethod(attr, self._runtime)
2610
+ return attr
2611
+
2612
+ raise AttributeError(f"Python object has no attribute '{name}'")
2613
+
2614
+ def __setattr__(self, name: str, value: Any):
2615
+ """Set attribute on wrapped Python object."""
2616
+ if name.startswith('_'):
2617
+ object.__setattr__(self, name, value)
2618
+ else:
2619
+ setattr(self._python_obj, name, value)
2620
+
2621
+ def has_member(self, name: str) -> bool:
2622
+ """Check if the Python object has a member."""
2623
+ return hasattr(self._python_obj, name)
2624
+
2625
+ def get_member(self, name: str) -> Any:
2626
+ """Get a member from the Python object."""
2627
+ return getattr(self._python_obj, name, None)
2628
+
2629
+ def set_member(self, name: str, value: Any):
2630
+ """Set a member on the Python object."""
2631
+ setattr(self._python_obj, name, value)
2632
+
2633
+ def get_method(self, name: str):
2634
+ """Get a method from the Python object."""
2635
+ if hasattr(self._python_obj, name):
2636
+ method = getattr(self._python_obj, name)
2637
+ if callable(method):
2638
+ return CSSLizedPythonMethod(method, self._runtime)
2639
+ return None
2640
+
2641
+ def get_python_obj(self):
2642
+ """Get the underlying Python object (for inheritance)."""
2643
+ return self._python_obj
2644
+
2645
+
2646
+ class CSSLizedPythonMethod:
2647
+ """Wrapper for Python methods to be called from CSSL."""
2648
+
2649
+ def __init__(self, method: Any, runtime: Any = None):
2650
+ self._method = method
2651
+ self._runtime = runtime
2652
+
2653
+ def __call__(self, *args, **kwargs):
2654
+ """Call the Python method."""
2655
+ return self._method(*args, **kwargs)
2656
+
2657
+ def __repr__(self):
2658
+ return f"<CSSLizedPythonMethod: {getattr(self._method, '__name__', 'anonymous')}>"
2659
+
2660
+
2661
+ class PythonizedCSSLInstance:
2662
+ """Python wrapper for CSSL class instances.
2663
+
2664
+ Provides Pythonic attribute access and method calling for CSSL objects.
2665
+ """
2666
+
2667
+ def __init__(self, instance: Any, runtime: Any = None):
2668
+ # Use object.__setattr__ to avoid triggering our custom __setattr__
2669
+ object.__setattr__(self, '_cssl_instance', instance)
2670
+ object.__setattr__(self, '_cssl_runtime', runtime)
2671
+ object.__setattr__(self, '_cssl_class_name', instance._class.name if hasattr(instance, '_class') else 'Unknown')
2672
+
2673
+ def __getattr__(self, name: str) -> Any:
2674
+ """Get member or method from CSSL instance."""
2675
+ if name.startswith('_'):
2676
+ raise AttributeError(f"'{self._cssl_class_name}' has no attribute '{name}'")
2677
+
2678
+ instance = object.__getattribute__(self, '_cssl_instance')
2679
+ runtime = object.__getattribute__(self, '_cssl_runtime')
2680
+
2681
+ # Check for member variable first
2682
+ if instance.has_member(name):
2683
+ value = instance.get_member(name)
2684
+ # Recursively pythonize nested CSSL instances
2685
+ from .cssl_types import CSSLInstance
2686
+ if isinstance(value, CSSLInstance):
2687
+ return PythonizedCSSLInstance(value, runtime)
2688
+ return value
2689
+
2690
+ # Check for method
2691
+ method = instance.get_method(name)
2692
+ if method is not None:
2693
+ # Return a callable wrapper for the method
2694
+ return PythonizedMethod(instance, name, method, runtime)
2695
+
2696
+ raise AttributeError(f"'{self._cssl_class_name}' has no attribute '{name}'")
2697
+
2698
+ def __setattr__(self, name: str, value: Any) -> None:
2699
+ """Set member value on CSSL instance."""
2700
+ if name.startswith('_'):
2701
+ object.__setattr__(self, name, value)
2702
+ return
2703
+
2704
+ instance = object.__getattribute__(self, '_cssl_instance')
2705
+ instance.set_member(name, value)
2706
+
2707
+ def __repr__(self) -> str:
2708
+ class_name = object.__getattribute__(self, '_cssl_class_name')
2709
+ instance = object.__getattribute__(self, '_cssl_instance')
2710
+ members = list(instance._members.keys()) if hasattr(instance, '_members') else []
2711
+ return f"<PythonizedCSSL '{class_name}' members={members}>"
2712
+
2713
+ def __dir__(self) -> list:
2714
+ """List available attributes."""
2715
+ instance = object.__getattribute__(self, '_cssl_instance')
2716
+ members = list(instance._members.keys()) if hasattr(instance, '_members') else []
2717
+ methods = list(instance._class.methods.keys()) if hasattr(instance._class, 'methods') else []
2718
+ return members + methods
2719
+
2720
+ def _to_dict(self) -> dict:
2721
+ """Convert to Python dictionary."""
2722
+ instance = object.__getattribute__(self, '_cssl_instance')
2723
+ result = {}
2724
+ for name, value in instance._members.items():
2725
+ from .cssl_types import CSSLInstance
2726
+ if isinstance(value, CSSLInstance):
2727
+ result[name] = PythonizedCSSLInstance(value, None)._to_dict()
2728
+ else:
2729
+ result[name] = value
2730
+ return result
2731
+
2732
+
2733
+ class PythonizedMethod:
2734
+ """Wrapper that makes CSSL methods callable from Python."""
2735
+
2736
+ def __init__(self, instance: Any, method_name: str, method_ast: Any, runtime: Any):
2737
+ self._instance = instance
2738
+ self._method_name = method_name
2739
+ self._method_ast = method_ast
2740
+ self._runtime = runtime
2741
+
2742
+ def __call__(self, *args, **kwargs) -> Any:
2743
+ """Call the CSSL method with arguments."""
2744
+ if self._runtime is None:
2745
+ raise RuntimeError(f"Cannot call method '{self._method_name}' - no runtime available")
2746
+
2747
+ # Execute the method through the runtime
2748
+ # Pass the method AST node, not the method name
2749
+ result = self._runtime._call_method(self._instance, self._method_ast, list(args), kwargs)
2750
+
2751
+ # Pythonize the result if it's a CSSL instance
2752
+ from .cssl_types import CSSLInstance
2753
+ if isinstance(result, CSSLInstance):
2754
+ return PythonizedCSSLInstance(result, self._runtime)
2755
+
2756
+ return result
2757
+
2758
+ def __repr__(self) -> str:
2759
+ return f"<method '{self._method_name}' of '{self._instance._class.name}'>"
2760
+
2761
+
2762
+ class PythonizedDict:
2763
+ """Simple wrapper for dict objects with attribute access."""
2764
+
2765
+ def __init__(self, data: dict):
2766
+ object.__setattr__(self, '_data', data)
2767
+
2768
+ def __getattr__(self, name: str) -> Any:
2769
+ data = object.__getattribute__(self, '_data')
2770
+ if name in data:
2771
+ value = data[name]
2772
+ if isinstance(value, dict):
2773
+ return PythonizedDict(value)
2774
+ return value
2775
+ raise AttributeError(f"No attribute '{name}'")
2776
+
2777
+ def __setattr__(self, name: str, value: Any) -> None:
2778
+ if name.startswith('_'):
2779
+ object.__setattr__(self, name, value)
2780
+ return
2781
+ data = object.__getattribute__(self, '_data')
2782
+ data[name] = value
2783
+
2784
+ def __repr__(self) -> str:
2785
+ data = object.__getattribute__(self, '_data')
2786
+ return f"<PythonizedDict {data}>"
2787
+
2788
+ def _to_dict(self) -> dict:
2789
+ return object.__getattribute__(self, '_data')
2790
+
2448
2791
 
2449
2792
  # Module-level convenience functions
2450
2793
  _default_builtins: Optional[CSSLBuiltins] = None